c-scripting/examples/expression_parser.h

161 lines
3.8 KiB
C

#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