#ifndef EXPRESSION_PARSER_H #define EXPRESSION_PARSER_H //////////////////////////////// // Operators //// PRECEDENCE //// typedef struct EXP_Precedence{ String8 name; U32 order; B32 right_to_left; } EXP_Precedence; #define SYMBOL_SET_DEFINE EXP_PRECEDENCE #define EXP_PRECEDENCE_Type EXP_Precedence #define EXP_PRECEDENCE_elf_section ".sy.precedence" #define EXP_PRECEDENCE_coff_a_section ".sy$precedence_a" #define EXP_PRECEDENCE_coff_m_section ".sy$precedence_m" #define EXP_PRECEDENCE_coff_z_section ".sy$precedence_z" #define EXP_PRECEDENCE_marker precedence #include "symbol_set.define.h" #define EXP_PRECEDENCE(ord,N,...) \ SyDefine(EXP_PRECEDENCE, N) = { .order = (ord), .name = str8_const(#N), __VA_ARGS__ } //// OPERATOR //// typedef struct EXP_Operator{ String8 name; String8 token_str; SY__UAddr precedence_id; } EXP_Operator; #define SYMBOL_SET_DEFINE EXP_OPERATOR #define EXP_OPERATOR_Type EXP_Operator #define EXP_OPERATOR_elf_section ".sy.operator" #define EXP_OPERATOR_coff_a_section ".sy$operator_a" #define EXP_OPERATOR_coff_m_section ".sy$operator_m" #define EXP_OPERATOR_coff_z_section ".sy$operator_z" #define EXP_OPERATOR_marker operator #include "symbol_set.define.h" #define EXP_OPERATOR(N,str,P) \ SyDefine(EXP_OPERATOR, N) = { .name = str8_const(#N), \ .token_str = str8_const(str), \ .precedence_id = SyRaw(EXP_PRECEDENCE, P) } #if SY__MAIN SY_INIT(EXP_OPERATOR){ for (SyEach(EXP_OPERATOR, op)){ op->precedence_id = SyIDFromRaw(EXP_PRECEDENCE, op->precedence_id); } } #endif //////////////////////////////// // Operator Functions static U32 exp_operator_id_from_string(String8 string); //////////////////////////////// // Lexer Types #define EXP_TokenKindXList(X) \ X(Error)\ X(EndOfFile)\ X(Whitespace)\ X(IDNum)\ X(Operator)\ X(OpenParen)\ X(CloseParen)\ X(OpenBracket)\ X(CloseBracket)\ X(OpenBrace)\ X(CloseBrace) typedef enum EXP_TokenKind{ #define X(N) EXP_TokenKind_##N, EXP_TokenKindXList(X) #undef X EXP_TokenKind_COUNT } EXP_TokenKind; typedef struct EXP_Token{ EXP_TokenKind kind; U32 pos; } EXP_Token; typedef struct EXP_TokenArray{ EXP_Token *tokens; U64 count; } EXP_TokenArray; //////////////////////////////// // Lexer Functions static EXP_TokenArray exp_lex(Arena *arena, String8 text); //////////////////////////////// // Parser Types #define EXP_ParseNodeKindXList(X)\ X(NULL)\ X(Operator)\ X(Leaf) typedef enum EXP_ParseNodeKind{ #define X(N) EXP_ParseNodeKind_##N, EXP_ParseNodeKindXList(X) #undef X EXP_ParseNodeKind_COUNT } EXP_ParseNodeKind; typedef struct EXP_ParseNode{ EXP_ParseNodeKind kind; union{ struct{ U32 operator_id; struct EXP_ParseNode *child[2]; } op; struct{ U32 token_idx; } leaf; }; } EXP_ParseNode; typedef struct EXP_ParseCtx{ String8 text; EXP_TokenArray tokens; EXP_Token *token; B32 error; U32 error_token_idx; String8 error_message; } EXP_ParseCtx; typedef struct EXP_OperatorRead{ U32 operator_id; U32 precedence_level; B32 right_to_left; } EXP_OperatorRead; //////////////////////////////// // Parser Functions static EXP_ParseNode* exp_parse(Arena *arena, String8 text, EXP_TokenArray tokens); static EXP_ParseNode* exp__parse_op_rec(Arena *arena, EXP_ParseCtx *ctx, EXP_ParseNode *left, U32 precedence_level); static EXP_ParseNode* exp__parse_op(Arena *arena, EXP_ParseCtx *ctx); static EXP_ParseNode* exp__parse_leaf(Arena *arena, EXP_ParseCtx *ctx); static void exp__parse_errorf(Arena *arena, EXP_ParseCtx *ctx, char *fmt, ...); static void exp__parse_skip_whitespace(EXP_ParseCtx *ctx); static EXP_OperatorRead exp__parse_read_operator(EXP_ParseCtx *ctx); static void exp_parse_node_print(String8 text, EXP_TokenArray tokens, EXP_ParseNode *node, S32 indent); #endif //EXPRESSION_PARSER_H