shithub: scc

Download patch

ref: a0cd5bb006c62c6b6d97e1db7a061ab329edc3a2
parent: 8b5ea303454aa1f5ea386833c337a39ad7ab0996
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Mar 18 11:31:58 EDT 2014

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.

--- a/decl.c
+++ b/decl.c
@@ -57,7 +57,7 @@
 {
 	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 @@
 			goto too_much_declarators;
 		qlf = 0;
 		if (yytoken == TQUALIFIER) {
-			qlf |= yylval.sym->u.c;
+			qlf |= yylval.token;
 			next();
 		}
 		*bp++ = qlf;
@@ -161,7 +161,7 @@
 	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 @@
 
 	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 @@
 }
 
 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,7 +401,7 @@
 }
 
 static struct ctype *
-enumdcl(uint8_t token)
+enumdcl(void)
 {
 	register struct ctype *tp;
 	struct symbol *sym;
@@ -403,6 +408,7 @@
 	int val = 0;
 	char *err;
 
+	next();
 	tp = newtag(ENUM);
 	if (yytoken != ';') {
 		expect('{');
@@ -474,7 +480,7 @@
 	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;
--- a/lex.c
+++ b/lex.c
@@ -135,7 +135,7 @@
 	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 @@
 {
 	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 @@
 	*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
--- a/symbol.c
+++ b/symbol.c
@@ -69,9 +69,6 @@
 	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;
--- a/tokens.h
+++ b/tokens.h
@@ -56,6 +56,7 @@
 struct symbol;
 union yystype {
 	struct symbol *sym;
+	uint8_t token;
 };
 
 extern union yystype yylval;