diff options
Diffstat (limited to 'src/as_parser.c')
| -rw-r--r-- | src/as_parser.c | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/src/as_parser.c b/src/as_parser.c index b419be5..f848730 100644 --- a/src/as_parser.c +++ b/src/as_parser.c @@ -1,36 +1,46 @@ #include "as_parser.h" +#include "as_tokenizer.h" +#include "utils.h" +#include <stdio.h> #include <stdlib.h> // BNF // === // // <prog> ::= <stmts> -// <stmts> ::= <stmt> <newline> | <stmt> <stmts> +// <stmts> ::= <stmt> newline | <stmt> newline <stmts> // <stmt> ::= <label> <instr> | <instr> | <label> -// <instr> ::= <op> | <op> <arg> | <op> <tag> -// <label> ::= <tag> : -// <op> ::= add | sub | mul | div | mod | eq +// <instr> ::= <op> | <op> arg | <op> tag +// <label> ::= tag ":" +// <op> ::= "add" | "sub" | "mul" | "div" | "mod" | "eq" -Prog* parseProg(TokenStream *ts) { - Prog *p = malloc(sizeof(Prog)); - p->stmts = parseStmts(ts); +Prog parseProg(Allocator alct, TokenStream ts) { + Prog p = allocate(alct, sizeof(struct prog)); + p->stmts = parseStmts(alct, ts); return p; } -Stmts* parseStmts(TokenStream *ts) { - Stmts *ss = malloc(sizeof(Stmts)); - ss->stmts = malloc(sizeof(Stmt*)); +Stmts parseStmts(Allocator alct, TokenStream ts) { + Stmts ss = allocate(alct, sizeof(struct stmts)); + ss->stmts = allocate(alct, sizeof(Stmt)); ss->stmts[0] = NULL; int capacity = 0; int len = 0; - while (peekToken(ts)->type != ENDOFFILE) { - Stmt *s = parseStmt(ts); + while (peekToken(alct, ts)->type != ENDOFFILE) { + Stmt s = parseStmt(alct, ts); + if (s == NULL) continue; if (len == capacity) { capacity = capacity * 2 + 1; ss->stmts = realloc(ss->stmts, sizeof(Stmt*) * capacity); } + // expect newline + if (peekToken(alct, ts)->type == NEWLINE) { + nextToken(alct, ts); + } else { + fprintf(stderr, "%d:%d Expect NEWLINE.\n", peekToken(alct, ts)->line, peekToken(alct, ts)->col); + } ss->stmts[len] = s; len++; } @@ -38,15 +48,15 @@ Stmts* parseStmts(TokenStream *ts) { return ss; } -Label* parseLabel(TokenStream *ts) { - Token *t = nextToken(ts); +Label parseLabel(Allocator alct, TokenStream ts) { + Token t = nextToken(alct, ts); if (t->type != TAG) { fprintf(stderr, "%d:%d Expect LABEL.\n", t->line, t->col); exit(-1); } - Label *l = malloc(sizeof(Label)); + Label l = allocate(alct, sizeof(Label)); l->name = t->sval; - t = nextToken(ts); + t = nextToken(alct, ts); if (t->type != COLON) { fprintf(stderr, "%d:%d Expect COLON.\n", t->line, t->col); exit(-1); @@ -54,34 +64,33 @@ Label* parseLabel(TokenStream *ts) { return l; } -Stmt* parseStmt(TokenStream *ts) { - Token *t = peekToken(ts); +Stmt parseStmt(Allocator alct, TokenStream ts) { + Token t = peekToken(alct, ts); + Stmt stmt = allocate(alct, sizeof(struct stmt)); + stmt->label = NULL; + stmt->instr = NULL; if (t->type == TAG) { - 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->label = l; - s->instr = i; - return s; + stmt->label = parseLabel(alct, ts); + if (peekToken(alct, ts)->type == NEWLINE) { + return stmt; } - } else { - Instr *i = parseInstr(ts); - Stmt *s = malloc(sizeof(Stmt)); - s->label = NULL; - s->instr = i; - return s; } + if (t->type == OP) { + stmt->instr = parseInstr(alct, ts); + if (peekToken(alct, ts)->type == NEWLINE) { + return stmt; + } + } + if (t->type == NEWLINE) { + return NULL; + } + fprintf(stderr, "%d:%d Expect lable + instruction, lable, or instruction.", t->line, t->col); + exit(-1); } -// parse op -Op parseOp(TokenStream *ts) { - Token *t = nextToken(ts); - Op op; +enum op parseOp(Allocator alct, TokenStream ts) { + Token t = nextToken(alct, ts); + enum op op; if (t->type == OP) { op = str2op(t->sval); if (op == OPEND) { @@ -95,22 +104,22 @@ Op parseOp(TokenStream *ts) { return op; } -Instr* parseInstr(TokenStream *ts) { - Token *t = nextToken(ts); - Instr *i = malloc(sizeof(Instr)); +Instr parseInstr(Allocator alct, TokenStream ts) { + Token t = nextToken(alct, ts); + Instr i = allocate(alct, sizeof(struct instr)); i->tagName = NULL; if (t->type == OP) { - i->op = parseOp(ts); - t = peekToken(ts); + i->op = parseOp(alct, ts); + t = peekToken(alct, ts); if (t->type == ARG) { - Arg *a = malloc(sizeof(Arg)); + Arg a = allocate(alct, sizeof(struct arg)); a->ival = t->ival; a->fval = t->fval; i->arg = a; - nextToken(ts); + nextToken(alct, ts); } else if (t->type == TAG) { i->tagName = t->sval; - nextToken(ts); + nextToken(alct, ts); } } return i; |
