diff options
| -rw-r--r-- | src/as_op.c | 28 | ||||
| -rw-r--r-- | src/as_op.h | 14 | ||||
| -rw-r--r-- | src/as_parser.c | 52 | ||||
| -rw-r--r-- | src/as_parser.h | 24 | ||||
| -rw-r--r-- | src/as_tokenizer.c | 6 | ||||
| -rw-r--r-- | src/as_tokenizer.h | 7 |
6 files changed, 100 insertions, 31 deletions
diff --git a/src/as_op.c b/src/as_op.c new file mode 100644 index 0000000..847214d --- /dev/null +++ b/src/as_op.c @@ -0,0 +1,28 @@ +#include "as_op.h" + +#include <string.h> + +struct opTableEntry{ + Op op; + const char* name; +}; +typedef struct opTableEntry OpTableEntry; + +OpTableEntry opTable[] = { + {ADD, "add"}, + {SUB, "sub"}, + {MUL, "mul"}, + {DIV, "div"}, + {MOD, "mod"}, + {EQ, "eq"}, + {OPEND, NULL} +}; + +Op str2op(const char* str) { + for (int i = 0; opTable[i].name != NULL; i++) { + if (strcmp(opTable[i].name, str) == 0) { + return opTable[i].op; + } + } + return OPEND; +} diff --git a/src/as_op.h b/src/as_op.h new file mode 100644 index 0000000..ec88670 --- /dev/null +++ b/src/as_op.h @@ -0,0 +1,14 @@ +#ifndef FVM_AS_OP_H_ +#define FVM_AS_OP_H_ + +enum op { + ADD, SUB, MUL, DIV, MOD, EQ, + // place holder for the end of the table + OPEND +}; +typedef enum op Op; + +Op str2op(const char *str); + +#endif + diff --git a/src/as_parser.c b/src/as_parser.c index d80cdd9..b419be5 100644 --- a/src/as_parser.c +++ b/src/as_parser.c @@ -7,9 +7,9 @@ // // <prog> ::= <stmts> // <stmts> ::= <stmt> <newline> | <stmt> <stmts> -// <stmt> ::= <tag> <instr> | <instr> | <tag> -// <instr> ::= <op> | <op> <arg> | <op> <label> -// <tag> ::= <label> : +// <stmt> ::= <label> <instr> | <instr> | <label> +// <instr> ::= <op> | <op> <arg> | <op> <tag> +// <label> ::= <tag> : // <op> ::= add | sub | mul | div | mod | eq @@ -38,9 +38,25 @@ Stmts* parseStmts(TokenStream *ts) { return ss; } +Label* parseLabel(TokenStream *ts) { + Token *t = nextToken(ts); + if (t->type != TAG) { + fprintf(stderr, "%d:%d Expect LABEL.\n", t->line, t->col); + exit(-1); + } + Label *l = malloc(sizeof(Label)); + l->name = t->sval; + t = nextToken(ts); + if (t->type != COLON) { + fprintf(stderr, "%d:%d Expect COLON.\n", t->line, t->col); + exit(-1); + } + return l; +} + Stmt* parseStmt(TokenStream *ts) { Token *t = peekToken(ts); - if (t->type == LABEL) { + if (t->type == TAG) { Label *l = parseLabel(ts); t = peekToken(ts); if (t->type == COLON) { @@ -49,23 +65,40 @@ Stmt* parseStmt(TokenStream *ts) { } else { Instr *i = parseInstr(ts); Stmt *s = malloc(sizeof(Stmt)); - s->tag = l; + s->label = l; s->instr = i; return s; } } else { Instr *i = parseInstr(ts); Stmt *s = malloc(sizeof(Stmt)); - s->tag = NULL; + s->label = NULL; s->instr = i; return s; } } +// parse op +Op parseOp(TokenStream *ts) { + Token *t = nextToken(ts); + Op op; + if (t->type == OP) { + op = str2op(t->sval); + if (op == OPEND) { + fprintf(stderr, "%d:%d Invalid OP.\n", t->line, t->col); + exit(-1); + } + } else { + fprintf(stderr, "%d:%d Expect OP.\n", t->line, t->col); + exit(-1); + } + return op; +} + Instr* parseInstr(TokenStream *ts) { Token *t = nextToken(ts); Instr *i = malloc(sizeof(Instr)); - i->labelName = NULL; + i->tagName = NULL; if (t->type == OP) { i->op = parseOp(ts); t = peekToken(ts); @@ -73,11 +106,10 @@ Instr* parseInstr(TokenStream *ts) { 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; + } else if (t->type == TAG) { + i->tagName = t->sval; nextToken(ts); } } diff --git a/src/as_parser.h b/src/as_parser.h index 268f45a..3306909 100644 --- a/src/as_parser.h +++ b/src/as_parser.h @@ -1,31 +1,20 @@ +#ifndef FVM_AS_PARSER_H_ +#define FVM_AS_PARSER_H_ + #include "as_tokenizer.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 - -enum op { - ADD, SUB, MUL, DIV, MOD, EQ -}; -typedef enum op Op; +#include "as_op.h" struct arg { int64_t ival; double fval; - const char *sval; }; typedef struct arg Arg; struct instr { Op op; Arg* arg; - const char* labelName; + const char* tagName; }; typedef struct instr Instr; @@ -35,7 +24,7 @@ struct label { typedef struct label Label; struct stmt { - Label* tag; + Label* label; Instr* instr; }; typedef struct stmt Stmt; @@ -57,3 +46,4 @@ Instr* parseInstr(TokenStream *ts); Label* parseLabel(TokenStream *ts); Op parseOp(TokenStream *ts); +#endif diff --git a/src/as_tokenizer.c b/src/as_tokenizer.c index 7cf244a..23c0ce1 100644 --- a/src/as_tokenizer.c +++ b/src/as_tokenizer.c @@ -132,7 +132,7 @@ Token nextTokenImpl(InputStream *s) { if (isOp(sval)) { return (Token){.type = OP, .sval = sval, .line = line, .col = col}; } - return (Token){.type = LABEL, .sval = sval, .line = line, .col = col}; + return (Token){.type = TAG, .sval = sval, .line = line, .col = col}; } fprintf(stderr, "error: invalid character %c at line %d, col %d\n", c, s->line, s->col); } @@ -164,11 +164,11 @@ void printToken(Token *t) { switch (t->type) { case OP: printf("OP: %s, line: %d, col: %d\n", t->sval, t->line, t->col); - 狗太厉害了 break; + break; case ARG: printf("ARG: %ld, line: %d, col: %d\n", t->ival, t->line, t->col); break; - case LABEL: + case TAG: printf("LABEL: %s, line: %d, col: %d\n", t->sval, t->line, t->col); break; case COLON: diff --git a/src/as_tokenizer.h b/src/as_tokenizer.h index fef8625..377aca0 100644 --- a/src/as_tokenizer.h +++ b/src/as_tokenizer.h @@ -1,8 +1,11 @@ +#ifndef FMV_AS_TOKENIZER_H_ +#define FMV_AS_TOKENIZER_H_ + #include <stdint.h> #include <stdio.h> typedef enum { - OP, ARG, LABEL, COLON, NEWLINE, ENDOFFILE + OP, ARG, TAG, COLON, NEWLINE, ENDOFFILE } TokenType; typedef struct { @@ -34,3 +37,5 @@ Token *nextToken(TokenStream *ts); Token *peekToken(TokenStream *ts); void printToken(Token *t); TokenStream* makeTokenStream(FILE* fp); + +#endif // FMV_AS_TOKENIZER_H_ |
