fix syntax error hint & strip all warnings

Signed-off-by: szdytom <szdytom@163.com>
This commit is contained in:
方而静 2023-06-12 16:39:30 +08:00
parent 121c37c16a
commit 24ab2a70f7
11 changed files with 55 additions and 52 deletions

View File

@ -1,3 +1,3 @@
# acc # acc
A (WIP) zero-dependence (sub) C compiler written in pure ISO C11, minimal but aims to implement all 4 passes(lex, parse, build ir, code generation) and a set of machine-independent optimizations. A (WIP) zero-dependence (sub) C compiler written in pure ISO C, minimal but aims to implement all 4 passes(lex, parse, build ir, code generation) and a set of machine-independent optimizations.

View File

@ -8,8 +8,8 @@ void* malloc_or_fail(size_t s, const char *func_name);
noreturn void fail_target(const char *target_name); noreturn void fail_target(const char *target_name);
noreturn void fail_malloc(const char *func_name); noreturn void fail_malloc(const char *func_name);
noreturn void fail_ast_op(int op, const char *func_name); noreturn void fail_ast_op(int op, const char *func_name);
noreturn void fail_ce_expect(const char *expected, const char *got); noreturn void fail_ce_expect(int line, const char *expected, const char *got);
noreturn void fail_ce(const char *reason); noreturn void fail_ce(int line, const char *reason);
noreturn void fail_char(int c); noreturn void fail_char(int line, int c);
#endif #endif

View File

@ -3,7 +3,6 @@
#include "util/linklist.h" #include "util/linklist.h"
extern int Line;
struct linklist scan_tokens(const char *name); struct linklist scan_tokens(const char *name);
#endif #endif

View File

@ -7,6 +7,7 @@
// Token structure // Token structure
struct token { struct token {
struct llist_node n; struct llist_node n;
int line; // token location line number
int type; // token type int type; // token type
union { // hold the value of the literal that we scanned in union { // hold the value of the literal that we scanned in
int16_t val_i16; int16_t val_i16;

2
main.c
View File

@ -19,7 +19,7 @@ void unload(void) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// atexit(unload); atexit(unload);
if (argc < 3) { if (argc < 3) {
usage(argv[0]); usage(argv[0]);
} }

View File

@ -101,7 +101,7 @@ void ast_free(struct ASTnode *x) {
switch (x->op) { switch (x->op) {
case A_IF: { case A_IF: {
ast_free(((struct ASTifnode*)x)->cond); ast_free(((struct ASTifnode*)x)->cond);
} // dont break } [[fallthrough]];
case A_ASSIGN: case A_ASSIGN:
case A_ADD: case A_SUB: case A_MUL: case A_DIV: case A_ADD: case A_SUB: case A_MUL: case A_DIV:
@ -111,7 +111,7 @@ void ast_free(struct ASTnode *x) {
ast_free(t->left); ast_free(t->left);
ast_free(t->right); ast_free(t->right);
} break; } break;
case A_PRINT: case A_RETURN: { case A_PRINT: case A_RETURN: {
struct ASTunnode *t = (struct ASTunnode*)x; struct ASTunnode *t = (struct ASTunnode*)x;
ast_free(t->left); ast_free(t->left);
@ -122,7 +122,7 @@ void ast_free(struct ASTnode *x) {
struct llist_node *p = t->st.head, *nxt; struct llist_node *p = t->st.head, *nxt;
while (p) { while (p) {
nxt = p->nxt; nxt = p->nxt;
ast_free(p); ast_free((struct ASTnode*)p);
p = nxt; p = nxt;
} }
llist_free(&t->st); llist_free(&t->st);

View File

@ -25,18 +25,18 @@ void fail_ast_op(int op, const char *func_name) {
exit(1); exit(1);
} }
void fail_ce_expect(const char *expected, const char *got) { void fail_ce_expect(int line, const char *expected, const char *got) {
fprintf(stderr, "syntax error on line %d: expected %s, got %s.\n", Line, expected, got); fprintf(stderr, "syntax error on line %d: expected %s, got %s.\n", line, expected, got);
exit(1); exit(1);
} }
void fail_ce(const char *reason) { void fail_ce(int line, const char *reason) {
fprintf(stderr, "syntax error on line %d: %s.\n", Line, reason); fprintf(stderr, "syntax error on line %d: %s.\n", line, reason);
exit(1); exit(1);
} }
void fail_char(int c) { void fail_char(int line, int c) {
fprintf(stderr, "Unrecognised character %c on line %d.\n", c, Line); fprintf(stderr, "Unrecognised character %c on line %d.\n", c, line);
exit(1); exit(1);
} }

View File

@ -11,8 +11,8 @@ static struct linklist Tokens; // current token for parsing
// Check that we have a binary operator and return its precedence. // Check that we have a binary operator and return its precedence.
// operators with larger precedence value will be evaluated first // operators with larger precedence value will be evaluated first
static int op_precedence(int t) { static int op_precedence(struct token *t) {
switch (t) { switch (t->type) {
case T_ASSIGN: case T_ASSIGN:
return (20); return (20);
case T_GT: case T_GE: case T_LT: case T_LE: case T_GT: case T_GE: case T_LT: case T_LE:
@ -24,12 +24,12 @@ static int op_precedence(int t) {
case T_STAR: case T_SLASH: case T_STAR: case T_SLASH:
return (90); return (90);
default: default:
fail_ce_expect("an operator", token_typename[t]); fail_ce_expect(t->line, "an operator", token_typename[t->type]);
} }
} }
// Convert a arithmetic token into an AST operation. // Convert a arithmetic token into an AST operation.
static int arithop(int t) { static int arithop(struct token *t) {
static const int map[][2] = { static const int map[][2] = {
{T_PLUS, A_ADD}, {T_PLUS, A_ADD},
{T_MINUS, A_SUB}, {T_MINUS, A_SUB},
@ -46,11 +46,11 @@ static int arithop(int t) {
}; };
for (int i = 0; map[i][0] != -1; ++i) { for (int i = 0; map[i][0] != -1; ++i) {
if (t == map[i][0]) { if (t->type == map[i][0]) {
return map[i][1]; return map[i][1];
} }
} }
fail_ce_expect("an binary operator", token_typename[t]); fail_ce_expect(t->line, "an binary operator", token_typename[t->type]);
} }
// operator ssociativity direction // operator ssociativity direction
@ -95,14 +95,14 @@ static void match(int t) {
if (current()->type == t) { if (current()->type == t) {
next(); next();
} else { } else {
fail_ce_expect(token_typename[current()->type], token_typename[t]); fail_ce_expect(current()->line, token_typename[t], token_typename[current()->type]);
} }
} }
// check current token's type or report syntax error. // check current token's type or report syntax error.
static void expect(int t) { static void expect(int t) {
if (current()->type != t) { if (current()->type != t) {
fail_ce_expect(token_typename[current()->type], token_typename[t]); fail_ce_expect(current()->line, token_typename[t], token_typename[current()->type]);
} }
} }
@ -113,20 +113,21 @@ static struct ASTnode* expression(void);
// AST node representing it. // AST node representing it.
static struct ASTnode* primary(void) { static struct ASTnode* primary(void) {
struct ASTnode *res; struct ASTnode *res;
struct token *t = current();
if (current()->type == T_LP) { if (t->type == T_LP) {
// ( expr ) considered as primary // ( expr ) considered as primary
next(); next();
res = expression(); res = expression();
match(T_RP); match(T_RP);
} else if (current()->type == T_I32_LIT) { } else if (t->type == T_I32_LIT) {
res = ast_make_lit_i32(current()->val_i32); res = ast_make_lit_i32(t->val_i32);
next(); next();
} else if (current()->type == T_I64_LIT) { } else if (t->type == T_I64_LIT) {
res = ast_make_lit_i64(current()->val_i64); res = ast_make_lit_i64(current()->val_i64);
next(); next();
} else if (current()->type == T_ID) { } else if (t->type == T_ID) {
// TODO: identifier. // TODO: identifier.
fail_ce(t->line, "got an identifier");
/* /*
int id = findglob((char*)current()->val); int id = findglob((char*)current()->val);
if (id == -1) { if (id == -1) {
@ -136,11 +137,8 @@ static struct ASTnode* primary(void) {
next(); next();
return (ast_make_var(id)); return (ast_make_var(id));
*/ */
res = NULL;
next();
} else { } else {
fprintf(stderr, "syntax error on line %d: primary expression excpeted.\n", Line); fail_ce(t->line, "primary expression expected");
exit(1);
} }
return (res); return (res);
} }
@ -155,28 +153,28 @@ static struct ASTnode* binexpr(int precedence) {
struct ASTnode *left, *right; struct ASTnode *left, *right;
left = primary(); left = primary();
int tt = current()->type; struct token *op = current();
if (!is_binop(tt)) { if (!is_binop(op->type)) {
return (left); return (left);
} }
int tp = op_precedence(tt); int tp = op_precedence(op);
while (tp > precedence) { while (tp > precedence) {
next(); next();
if (direction_rtl(tt)) { if (direction_rtl(op->type)) {
right = binexpr(precedence); right = binexpr(precedence);
left = ast_make_assign(arithop(tt), ((struct ASTvarnode*)left)->id, right); left = ast_make_assign(arithop(op), left, right);
} else { } else {
right = binexpr(tp); right = binexpr(tp);
left = ast_make_binary(arithop(tt), left, right); // join right into left left = ast_make_binary(arithop(op), left, right); // join right into left
} }
tt = current()->type; op = current();
if (!is_binop(tt)) { if (!is_binop(op->type)) {
return (left); return (left);
} }
tp = op_precedence(tt); tp = op_precedence(op);
} }
return (left); return (left);
} }

View File

@ -23,7 +23,7 @@ static void ast_dfs(FILE* Outfile, struct ASTnode *x) {
switch(x->op) { switch(x->op) {
case A_RETURN: case A_PRINT: { case A_RETURN: case A_PRINT: {
struct ASTunnode *t = x; struct ASTunnode *t = (struct ASTunnode*)x;
fprintf(Outfile, "--->UNOP(%s)\n", ast_opname[x->op]); fprintf(Outfile, "--->UNOP(%s)\n", ast_opname[x->op]);
tabs += 1; tabs += 1;
ast_dfs(Outfile, t->left); ast_dfs(Outfile, t->left);
@ -31,22 +31,22 @@ static void ast_dfs(FILE* Outfile, struct ASTnode *x) {
} break; } break;
case A_LIT_I32: { case A_LIT_I32: {
struct ASTi32node *t = x; struct ASTi32node *t = (struct ASTi32node*)x;
fprintf(Outfile, "--->INT32(%d)\n", t->val); fprintf(Outfile, "--->INT32(%d)\n", t->val);
} break; } break;
case A_LIT_I64: { case A_LIT_I64: {
struct ASTi64node *t = x; struct ASTi64node *t = (struct ASTi64node*)x;
fprintf(Outfile, "--->INT64(%lld)\n", t->val); fprintf(Outfile, "--->INT64(%lld)\n", t->val);
} break; } break;
case A_BLOCK: { case A_BLOCK: {
struct ASTblocknode *t = x; struct ASTblocknode *t = (struct ASTblocknode*)x;
fprintf(Outfile, "--->BLOCK(%d statements)\n", t->st.length); fprintf(Outfile, "--->BLOCK(%d statements)\n", t->st.length);
tabs += 1; tabs += 1;
struct llist_node *p = t->st.head; struct llist_node *p = t->st.head;
while (p) { while (p) {
ast_dfs(Outfile, p); ast_dfs(Outfile, (struct ASTnode*)p);
p = p->nxt; p = p->nxt;
} }
tabs -= 1; tabs -= 1;

View File

@ -8,7 +8,7 @@
#include "fatals.h" #include "fatals.h"
#include "util/misc.h" #include "util/misc.h"
int Line = 1; static int Line = 1;
static int Preview; static int Preview;
static FILE *Infile; static FILE *Infile;
@ -155,9 +155,11 @@ static bool scan_1c(struct token *t) {
// Scan and return the next token found in the input. // Scan and return the next token found in the input.
static struct token* scan(void) { static struct token* scan(void) {
struct token *t = malloc_or_fail(sizeof(struct token), __FUNCTION__);
skip_whitespaces(); skip_whitespaces();
struct token *t = malloc_or_fail(sizeof(struct token), __FUNCTION__);
t->line = Line;
int c = preview(); int c = preview();
if (c == EOF) { if (c == EOF) {
t->type = T_EOF; t->type = T_EOF;
@ -183,7 +185,8 @@ static struct token* scan(void) {
t->type = T_NE; t->type = T_NE;
next(); next();
} else { } else {
fail_char(c); // TODO: the not operator
fail_char(t->line, c);
} }
} else if (c == '<') { } else if (c == '<') {
t->type = T_LT; t->type = T_LT;
@ -212,7 +215,7 @@ static struct token* scan(void) {
t->type = T_ID; t->type = T_ID;
} }
} else { // cannot match to anything we know, report error. } else { // cannot match to anything we know, report error.
fail_char(c); fail_char(t->line, c);
} }
} }
return (t); return (t);

View File

@ -4,6 +4,8 @@ set_basename("acc")
set_languages("c11") set_languages("c11")
set_targetdir(".") set_targetdir(".")
set_policy("build.warning", true)
target("build") target("build")
set_kind("binary") set_kind("binary")
set_default(true) set_default(true)