commit a0cd5bb006c62c6b6d97e1db7a061ab329edc3a2
parent 8b5ea303454aa1f5ea386833c337a39ad7ab0996
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 18 Mar 2014 15:31:58 +0100
Add token field in yylval
This token allows us to reduce the complexity of specifier, and in case
of having an error is specifier the error is shown to the user before of
the read of the next token, or before of parsing the definition of a
struct/union/enum.
Diffstat:
4 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/decl.c b/decl.c
@@ -57,7 +57,7 @@ newiden(uint8_t ns)
{
struct symbol *sym;
- if ((sym = lookup(yytext, ns)) && sym->ctx == curctx)
+ if (yylval.sym && yylval.sym->ctx == curctx)
error("redeclaration of '%s'", yytext);
sym = install(yytext, ns);
next();
@@ -110,7 +110,7 @@ declarator0(struct dcldata *dp, uint8_t ns, int8_t flags)
goto too_much_declarators;
qlf = 0;
if (yytoken == TQUALIFIER) {
- qlf |= yylval.sym->u.c;
+ qlf |= yylval.token;
next();
}
*bp++ = qlf;
@@ -161,7 +161,7 @@ declarator(struct ctype *tp, uint8_t ns, int8_t flags)
return sym;
}
-static struct ctype *structdcl(uint8_t tag), *enumdcl(uint8_t tag);
+static struct ctype *structdcl(void), *enumdcl(void);
static struct ctype *
specifier(int8_t *sclass)
@@ -173,46 +173,49 @@ specifier(int8_t *sclass)
for (;;) {
register uint8_t *p;
- struct symbol *sym = yylval.sym;
+ struct ctype *(*dcl)(void) = NULL;
switch (yytoken) {
case SCLASS: p = &cls; break;
case TQUALIFIER:
- if ((qlf |= sym->u.c) & RESTRICT)
+ if ((qlf |= yylval.token) & RESTRICT)
goto invalid_type;
- goto next_token;
+ next();
+ continue;
case TYPE:
- switch (t = sym->u.c) {
- case ENUM: case STRUCT: case UNION:
- next();
- tp = (t == ENUM) ? enumdcl(t) : structdcl(t);
- p = &type;
- goto check_spec;
+ switch (yylval.token) {
+ case ENUM:
+ dcl = enumdcl; p = &type; break;
+ case STRUCT: case UNION:
+ dcl = structdcl; p = &type; break;
case TYPENAME:
tp = yylval.sym->type;
case VOID: case BOOL: case CHAR:
case INT: case FLOAT: case DOUBLE:
- p = &type; goto next_token;
+ p = &type; break;
case SIGNED: case UNSIGNED:
p = &sign; break;
case LONG:
if (size == LONG) {
size = LONG+LONG;
- goto next_token;
+ break;
}
case SHORT:
- p = &size; goto next_token;
+ p = &size; break;
case COMPLEX: case IMAGINARY:
- p = &cplex; goto next_token;
+ p = &cplex; break;
}
break;
default:
goto check_types;
}
-next_token: next();
-check_spec: if (*p)
+ if (*p)
goto invalid_type;
- *p = sym->u.c;
+ *p = yylval.token;
+ if (dcl)
+ tp = dcl();
+ else
+ next();
}
check_types:
@@ -372,11 +375,13 @@ bad_tag:
}
static struct ctype *
-structdcl(uint8_t tag)
+structdcl(void)
{
struct ctype *tp;
- uint8_t ns;
+ uint8_t ns, tag;
+ tag = yylval.token;
+ next();
tp = newtag(tag);
tp->u.fields = NULL;
ns = tp->sym->u.ns;
@@ -396,13 +401,14 @@ redefined:
}
static struct ctype *
-enumdcl(uint8_t token)
+enumdcl(void)
{
register struct ctype *tp;
struct symbol *sym;
int val = 0;
char *err;
+ next();
tp = newtag(ENUM);
if (yytoken != ';') {
expect('{');
@@ -474,7 +480,7 @@ extdecl(void)
forbid_eof = 1;
switch (yytoken) {
- case IDEN: TYPE: case SCLASS: case TQUALIFIER:
+ case IDEN: case TYPE: case SCLASS: case TQUALIFIER:
tp = specifier(&sclass);
if (sclass == REGISTER || sclass == AUTO)
goto bad_storage;
diff --git a/lex.c b/lex.c
@@ -135,7 +135,7 @@ init_keywords(void)
for (bp = buff; bp->str; ++bp) {
sym = install(bp->str, NS_KEYWORD);
sym->token = bp->token;
- sym->u.c = bp->value;
+ sym->u.token = bp->value;
}
}
@@ -144,6 +144,7 @@ iden(void)
{
register char *bp;
register int c;
+ struct symbol *sym;
for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
if (!isalnum(c = getc(yyin)) && c != '_')
@@ -154,8 +155,13 @@ iden(void)
*bp = '\0';
ungetc(c, yyin);
- yynlval.sym = lookup(yybuf, NS_IDEN);
- return (yynlval.sym) ? yynlval.sym->token : IDEN;
+ sym = lookup(yybuf, NS_IDEN);
+ if (!sym || sym->token == IDEN) {
+ yynlval.sym = sym;
+ return IDEN;
+ }
+ yynlval.token = sym->u.token;
+ return sym->token;
}
static uint8_t
diff --git a/symbol.c b/symbol.c
@@ -69,9 +69,6 @@ lookup(register char *s, uint8_t ns)
static struct symtab *tbl;
register struct symbol *sym;
- if (ns == NS_IDEN && (sym = yylval.sym) && !strcmp(sym->name, s))
- return sym;
-
tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
for (sym = tbl->htab[hash(s)]; sym; sym = sym->hash) {
register char *t = sym->name;
diff --git a/tokens.h b/tokens.h
@@ -56,6 +56,7 @@ enum tokens {
struct symbol;
union yystype {
struct symbol *sym;
+ uint8_t token;
};
extern union yystype yylval;