diff options
| author | Mistivia <i@mistivia.com> | 2025-03-26 19:11:10 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-03-26 19:11:10 +0800 |
| commit | 97d4462ac24b726d9313ec52ca0f11711ead553b (patch) | |
| tree | 1bba7f6d4f2690d673b810bda4ec34523034bcaa /src/as_parser.c | |
| parent | 312716a295626f2b60b41777728c7f220fee843d (diff) | |
Diffstat (limited to 'src/as_parser.c')
| -rw-r--r-- | src/as_parser.c | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/src/as_parser.c b/src/as_parser.c deleted file mode 100644 index 4205179..0000000 --- a/src/as_parser.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "as_parser.h" -#include "as_tokenizer.h" -#include "utils.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -// BNF -// === -// -// <prog> ::= <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" | ... - -result parse_prog(allocator* alct, token_stream* ts) { - struct prog * p = allocate(alct, sizeof(struct prog)); - p->stmts = unwrap(parse_stmts(alct, ts)); - return ok(p); -} - -result parse_stmts(allocator* alct, token_stream* ts) { - token *token; - stmts* ss = allocate(alct, sizeof(stmts)); - stmt* s; - - ss->stmts = allocate(alct, sizeof(stmt*)); - ss->stmts[0] = NULL; - int capacity = 0; - int len = 0; - - while (1) { - token = unwrap(peek_token(alct, ts)); - if (token->type == TK_ENDOFFILE) { - break; - } - - s = unwrap(parse_stmt(alct, ts)); - if (s == NULL) continue; - if (len == capacity) { - size_t new_capacity = capacity * 2 + 1; - void* new_stmts = allocate(alct, sizeof(struct stmt **) * new_capacity); - memcpy(new_stmts, ss->stmts, sizeof(struct stmt **) * capacity); - ss->stmts = new_stmts; - capacity = new_capacity; - } - // expect newline - token = unwrap(peek_token(alct, ts)); - if (token->type == TK_NEWLINE) { - unwrap(next_token(alct, ts)); - } else { - return err(safe_sprintf(alct, "%d:%d expect newline.\n", token->line, token->col)); - } - ss->stmts[len] = s; - len++; - } - ss->stmts[len] = NULL; - return ok(ss); -} - -result parse_label(allocator* alct, token_stream* ts) { - struct token * t; - t = unwrap(next_token(alct, ts)); - if (t->type != TK_TAG) { - return err(safe_sprintf(alct, "%d:%d expect label.\n", t->line, t->col)); - } - struct label * l = allocate(alct, sizeof(struct label *)); - l->name = t->sval; - t = unwrap(next_token(alct, ts)); - if (t->type != TK_COLON) { - return err(safe_sprintf(alct, "%d:%d expect colon.\n", t->line, t->col)); - } - return ok(l); -} - -result parse_stmt(allocator* alct, token_stream* ts) { - const char *errmsg; - token* token; - token = unwrap(peek_token(alct, ts)); - stmt* stmt = allocate(alct, sizeof(struct stmt)); - stmt->label = NULL; - stmt->instr = NULL; - if (token->type == TK_TAG) { - stmt->label = unwrap(parse_label(alct, ts)); - token = unwrap(peek_token(alct, ts)); - if (token->type == TK_NEWLINE) { - return ok(stmt); - } - token = unwrap(peek_token(alct, ts)); - } - if (token->type == TK_OP) { - stmt->instr = unwrap(parse_instr(alct, ts)); - token = unwrap(peek_token(alct, ts)); - if (token->type == TK_NEWLINE) { - return ok(stmt); - } - } - if (token->type == TK_NEWLINE) { - return ok(NULL); - } - return err(safe_sprintf(alct, "%d:%d expect lable + instruction, lable, or instruction.\n", token->line, token->col)); -} - -result parse_op(allocator* alct, token_stream* ts) { - token* t; - t = unwrap(next_token(alct, ts)); - enum op op; - if (t->type == TK_OP) { - op = str2op(t->sval); - if (op == OP_END) { - return err(safe_sprintf(alct, "%d:%d invalid op.\n", t->line, t->col)); - } - } else { - return err(safe_sprintf(alct, "%d:%d expect op.\n", t->line, t->col)); - } - return ok((void*)op); -} - -result parse_instr(allocator* alct, token_stream* ts) { - token* t; - t = unwrap(peek_token(alct, ts)); - instr * i = allocate(alct, sizeof(instr)); - *i = (instr){ - .tag_name = NULL, - .arg = NULL, - .op = OP_END, - .lineno = -1 - }; - if (t->type == TK_OP) { - i->lineno = t->line; - i->op = (op)unwrap(parse_op(alct, ts)); - t = unwrap(peek_token(alct, ts)); - if (t->type == TK_ARG) { - arg* a = allocate(alct, sizeof(arg)); - a->ival = t->ival; - a->fval = t->fval; - i->arg = a; - unwrap(next_token(alct, ts)); - } else if (t->type == TK_TAG) { - i->tag_name = t->sval; - unwrap(next_token(alct, ts)); - } - } - return ok(i); -} - |
