fix syntax error hint & strip all warnings
Signed-off-by: szdytom <szdytom@163.com>
This commit is contained in:
parent
121c37c16a
commit
24ab2a70f7
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "util/linklist.h"
|
||||
|
||||
extern int Line;
|
||||
struct linklist scan_tokens(const char *name);
|
||||
|
||||
#endif
|
||||
|
@ -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
2
main.c
@ -19,7 +19,7 @@ void unload(void) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// atexit(unload);
|
||||
atexit(unload);
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
@ -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:
|
||||
@ -111,7 +111,7 @@ void ast_free(struct ASTnode *x) {
|
||||
ast_free(t->left);
|
||||
ast_free(t->right);
|
||||
} break;
|
||||
|
||||
|
||||
case A_PRINT: case A_RETURN: {
|
||||
struct ASTunnode *t = (struct ASTunnode*)x;
|
||||
ast_free(t->left);
|
||||
@ -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);
|
||||
|
12
src/fatals.c
12
src/fatals.c
@ -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);
|
||||
}
|
||||
|
||||
|
52
src/parse.c
52
src/parse.c
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
13
src/scan.c
13
src/scan.c
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user