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
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_malloc(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(const char *reason);
noreturn void fail_char(int c);
noreturn void fail_ce_expect(int line, const char *expected, const char *got);
noreturn void fail_ce(int line, const char *reason);
noreturn void fail_char(int line, int c);
#endif

View File

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

View File

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

2
main.c
View File

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

View File

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

View File

@ -25,18 +25,18 @@ void fail_ast_op(int op, const char *func_name) {
exit(1);
}
void fail_ce_expect(const char *expected, const char *got) {
fprintf(stderr, "syntax error on line %d: expected %s, got %s.\n", Line, expected, 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);
exit(1);
}
void fail_ce(const char *reason) {
fprintf(stderr, "syntax error on line %d: %s.\n", Line, reason);
void fail_ce(int line, const char *reason) {
fprintf(stderr, "syntax error on line %d: %s.\n", line, reason);
exit(1);
}
void fail_char(int c) {
fprintf(stderr, "Unrecognised character %c on line %d.\n", c, Line);
void fail_char(int line, int c) {
fprintf(stderr, "Unrecognised character %c on line %d.\n", c, line);
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.
// operators with larger precedence value will be evaluated first
static int op_precedence(int t) {
switch (t) {
static int op_precedence(struct token *t) {
switch (t->type) {
case T_ASSIGN:
return (20);
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:
return (90);
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.
static int arithop(int t) {
static int arithop(struct token *t) {
static const int map[][2] = {
{T_PLUS, A_ADD},
{T_MINUS, A_SUB},
@ -46,11 +46,11 @@ static int arithop(int t) {
};
for (int i = 0; map[i][0] != -1; ++i) {
if (t == map[i][0]) {
if (t->type == map[i][0]) {
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
@ -95,14 +95,14 @@ static void match(int t) {
if (current()->type == t) {
next();
} 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.
static void expect(int 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.
static struct ASTnode* primary(void) {
struct ASTnode *res;
if (current()->type == T_LP) {
struct token *t = current();
if (t->type == T_LP) {
// ( expr ) considered as primary
next();
res = expression();
match(T_RP);
} else if (current()->type == T_I32_LIT) {
res = ast_make_lit_i32(current()->val_i32);
} else if (t->type == T_I32_LIT) {
res = ast_make_lit_i32(t->val_i32);
next();
} else if (current()->type == T_I64_LIT) {
} else if (t->type == T_I64_LIT) {
res = ast_make_lit_i64(current()->val_i64);
next();
} else if (current()->type == T_ID) {
} else if (t->type == T_ID) {
// TODO: identifier.
fail_ce(t->line, "got an identifier");
/*
int id = findglob((char*)current()->val);
if (id == -1) {
@ -136,11 +137,8 @@ static struct ASTnode* primary(void) {
next();
return (ast_make_var(id));
*/
res = NULL;
next();
} else {
fprintf(stderr, "syntax error on line %d: primary expression excpeted.\n", Line);
exit(1);
fail_ce(t->line, "primary expression expected");
}
return (res);
}
@ -155,28 +153,28 @@ static struct ASTnode* binexpr(int precedence) {
struct ASTnode *left, *right;
left = primary();
int tt = current()->type;
if (!is_binop(tt)) {
struct token *op = current();
if (!is_binop(op->type)) {
return (left);
}
int tp = op_precedence(tt);
int tp = op_precedence(op);
while (tp > precedence) {
next();
if (direction_rtl(tt)) {
if (direction_rtl(op->type)) {
right = binexpr(precedence);
left = ast_make_assign(arithop(tt), ((struct ASTvarnode*)left)->id, right);
left = ast_make_assign(arithop(op), left, right);
} else {
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;
if (!is_binop(tt)) {
op = current();
if (!is_binop(op->type)) {
return (left);
}
tp = op_precedence(tt);
tp = op_precedence(op);
}
return (left);
}

View File

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

View File

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

View File

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