parse.h (2674B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #pragma once
#include "defaults.h"
// Tokens:
typedef enum {
TT_LPAREN, TT_RPAREN,
TT_IDENTIFIER,
TT_NUMERIC,
TT_OPERATOR,
TT_STRING,
TT_NONE,
} TokenType;
typedef struct {
TokenType type;
const char *value;
} Token;
Token *new_token(TokenType, const char *);
// Operator properties.
typedef enum {
LEFT_ASSOC,
RIGHT_ASSOC,
NEITHER_ASSOC,
} Associativity;
typedef enum {
PREFIX,
INFIX,
POSTFIX,
} Fixity;
typedef struct {
const char *value;
u16 precedence;
Associativity assoc;
Fixity fixity;
} Operator;
static const u16 FUNCTION_PRECEDENCE = 9;
// Known operators from longest to shortests.
static const Operator KNOWN_OPERATORS[] = {
// 3 characters long.
{ "not", 8, RIGHT_ASSOC, PREFIX },
// 2 characters long.
{ "**", 10, RIGHT_ASSOC, INFIX },
{ "<=", 4, LEFT_ASSOC, INFIX },
{ ">=", 4, LEFT_ASSOC, INFIX },
{ "==", 3, LEFT_ASSOC, INFIX },
{ "/=", 3, LEFT_ASSOC, INFIX },
// 1 character long.
{ "-", 10, RIGHT_ASSOC, PREFIX },
{ "+", 10, RIGHT_ASSOC, PREFIX },
{ "¬", 10, RIGHT_ASSOC, PREFIX },
{ "!", 10, LEFT_ASSOC, POSTFIX },
{ "^", 10, RIGHT_ASSOC, INFIX },
{ "*", 6, LEFT_ASSOC, INFIX },
{ "/", 6, LEFT_ASSOC, INFIX },
{ "+", 5, LEFT_ASSOC, INFIX },
{ "-", 5, LEFT_ASSOC, INFIX },
{ ">", 4, LEFT_ASSOC, INFIX },
{ "<", 4, LEFT_ASSOC, INFIX },
{ "=", 2, RIGHT_ASSOC, INFIX },
{ ",", 1, RIGHT_ASSOC, INFIX },
};
// Parse tree nodes:
typedef enum {
IDENT_NODE,
NUMBER_NODE,
STRING_NODE,
UNARY_NODE,
BINARY_NODE,
} NodeType;
struct _parse_node;
typedef struct {
char *value;
} IdentNode;
typedef struct {
usize len;
byte *value;
} StringNode;
typedef enum {
FLOAT,
INT,
BIGINT, // Not supported yet.
RATIO, // Not supported yet.
} NumberType;
typedef struct {
NumberType type;
union {
fsize f;
ssize i;
// Add bigint_t and ratio_t in future.
} value;
} NumberNode;
typedef struct {
const struct _parse_node *callee;
const struct _parse_node *operand;
bool is_postfix;
} UnaryNode;
typedef struct {
const struct _parse_node *callee;
const struct _parse_node *left;
const struct _parse_node *right;
} BinaryNode;
typedef struct _parse_node {
NodeType type;
union {
IdentNode ident;
StringNode str;
NumberNode number;
UnaryNode unary;
BinaryNode binary;
} node;
} ParseNode;
// Functions:
void free_token(Token *);
void free_parsenode(ParseNode *);
Token *lex(char **);
Token *peek(char **);
NumberNode *make_number(NumberType, void *);
NumberNode *parse_number(const char *);
ParseNode *parse_prefix(const Token *, char **);
ParseNode *parse_infix(const ParseNode *, const Token *, char **, u16);
ParseNode *parse_expr(char **, u16);
ParseNode *parse(const char *);
|