diff options
| author | Mistivia <i@mistivia.com> | 2025-03-02 19:28:26 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-03-02 19:28:26 +0800 |
| commit | 2c228ecb7d373fd3a7150768302ce0ade6714246 (patch) | |
| tree | eebe1f7a9ce6cbef639cd777bb014553848b558d /src/as_parser.c | |
| parent | b747628cbfba50fe3d74f7b8ed316d0bd2d56bdc (diff) | |
add parser
Diffstat (limited to 'src/as_parser.c')
| -rw-r--r-- | src/as_parser.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/as_parser.c b/src/as_parser.c new file mode 100644 index 0000000..d80cdd9 --- /dev/null +++ b/src/as_parser.c @@ -0,0 +1,85 @@ +#include "as_parser.h" + +#include <stdlib.h> + +// BNF +// === +// +// <prog> ::= <stmts> +// <stmts> ::= <stmt> <newline> | <stmt> <stmts> +// <stmt> ::= <tag> <instr> | <instr> | <tag> +// <instr> ::= <op> | <op> <arg> | <op> <label> +// <tag> ::= <label> : +// <op> ::= add | sub | mul | div | mod | eq + + +Prog* parseProg(TokenStream *ts) { + Prog *p = malloc(sizeof(Prog)); + p->stmts = parseStmts(ts); + return p; +} + +Stmts* parseStmts(TokenStream *ts) { + Stmts *ss = malloc(sizeof(Stmts)); + ss->stmts = malloc(sizeof(Stmt*)); + ss->stmts[0] = NULL; + int capacity = 0; + int len = 0; + while (peekToken(ts)->type != ENDOFFILE) { + Stmt *s = parseStmt(ts); + if (len == capacity) { + capacity = capacity * 2 + 1; + ss->stmts = realloc(ss->stmts, sizeof(Stmt*) * capacity); + } + ss->stmts[len] = s; + len++; + } + ss->stmts[len] = NULL; + return ss; +} + +Stmt* parseStmt(TokenStream *ts) { + Token *t = peekToken(ts); + if (t->type == LABEL) { + Label *l = parseLabel(ts); + t = peekToken(ts); + if (t->type == COLON) { + nextToken(ts); + return (Stmt*)l; + } else { + Instr *i = parseInstr(ts); + Stmt *s = malloc(sizeof(Stmt)); + s->tag = l; + s->instr = i; + return s; + } + } else { + Instr *i = parseInstr(ts); + Stmt *s = malloc(sizeof(Stmt)); + s->tag = NULL; + s->instr = i; + return s; + } +} + +Instr* parseInstr(TokenStream *ts) { + Token *t = nextToken(ts); + Instr *i = malloc(sizeof(Instr)); + i->labelName = NULL; + if (t->type == OP) { + i->op = parseOp(ts); + t = peekToken(ts); + if (t->type == ARG) { + Arg *a = malloc(sizeof(Arg)); + a->ival = t->ival; + a->fval = t->fval; + a->sval = t->sval; + i->arg = a; + nextToken(ts); + } else if (t->type == LABEL) { + i->labelName = t->sval; + nextToken(ts); + } + } + return i; +} |
