From 88aa3b6891678669548f01a0f87c36a993694320 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Wed, 17 Apr 2019 13:54:48 -0700 Subject: Improve token descriptions in errors --- cc.h | 2 +- pp.c | 9 ++++++--- token.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/cc.h b/cc.h index 25a5fc0..bb5e23b 100644 --- a/cc.h +++ b/cc.h @@ -376,8 +376,8 @@ struct init { extern struct token tok; void tokprint(const struct token *); +void tokdesc(char *, size_t, enum tokenkind, const char *); _Noreturn void error(const struct location *, const char *, ...); -struct token; /* scan */ diff --git a/pp.c b/pp.c index 757492b..f334f07 100644 --- a/pp.c +++ b/pp.c @@ -124,10 +124,13 @@ peek(int kind) char * expect(int kind, const char *msg) { - char *lit; + char *lit, want[64], got[64]; - if (tok.kind != kind) - error(&tok.loc, "expected %d %s, saw %d", kind, msg, tok.kind); + if (tok.kind != kind) { + tokdesc(want, sizeof(want), kind, NULL); + tokdesc(got, sizeof(got), tok.kind, tok.lit); + error(&tok.loc, "expected %s %s, saw %s", want, msg, got); + } lit = tok.lit; next(); diff --git a/token.c b/token.c index fe358a9..3a97f7a 100644 --- a/token.c +++ b/token.c @@ -1,4 +1,6 @@ +#include #include +#include #include #include #include @@ -7,7 +9,7 @@ struct token tok; -static char *tokstr[] = { +static const char *tokstr[] = { /* keyword */ [TAUTO] = "auto", [TBREAK] = "break", @@ -130,6 +132,32 @@ tokprint(const struct token *t) fputs(str, stdout); } +void +tokdesc(char *buf, size_t len, enum tokenkind kind, const char *lit) +{ + const char *class; + bool quote; + + switch (kind) { + case TIDENT: class = "identifier"; quote = true; break; + case TNUMBER: class = "number"; quote = true; break; + case TCHARCONST: class = "character"; quote = false; break; + case TSTRINGLIT: class = "string"; quote = false; break; + case TNEWLINE: class = "newline"; quote = true; break; + default: + class = NULL; + lit = kind < LEN(tokstr) ? tokstr[kind] : NULL; + } + if (class && lit) + snprintf(buf, len, quote ? "%s '%s'" : "%s %s", class, lit); + else if (class) + snprintf(buf, len, "%s", class); + else if (lit) + snprintf(buf, len, "'%s'", lit); + else + snprintf(buf, len, ""); +} + _Noreturn void error(const struct location *loc, const char *fmt, ...) { va_list ap; -- cgit v1.2.3