161 lines
3.8 KiB
C
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
|