aboutsummaryrefslogtreecommitdiff
path: root/src/as_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/as_parser.c')
-rw-r--r--src/as_parser.c103
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;