shithub: scc

Download patch

ref: 54fd1b0ef86755200dce120604c1a876d6123ccb
parent: ededd35636769e3b9facdef0ed3b3255f8aa85a6
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Aug 4 05:08:48 EDT 2015

Add block item to the grammar

This non terminal symbol simplify a lot the logic in stmt()
and the logic in compound(), and it also makes the grammar
more similar to the C99 formal grammar.

--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -12,10 +12,42 @@
 static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
 
 static void
+label(void)
+{
+	Symbol *sym;
+
+	switch (yytoken) {
+	case IDEN:
+	case TYPEIDEN:
+		/*
+		 * We cannot call to insert() because the call to lookup in
+		 * lex.c was done in NS_IDEN namespace, and it is impossibe
+		 * to fix this point, because an identifier at the beginning
+		 * of a statement may be part of an expression or part of a
+		 * label. This double call to lookup() is going to generate
+		 * an undefined symbol that is not going to be used ever.
+		 */
+		sym = lookup(NS_LABEL);
+		if (sym->flags & ISDEFINED)
+			error("label '%s' already defined", yytoken);
+		sym->flags |= ISDEFINED;
+		emit(OLABEL, sym);
+		next();
+		expect(':');
+		break;
+	default:
+		unexpected();
+	}
+}
+
+static void
 stmtexp(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
-	Node *np = NULL;;
+	Node *np;
 
+	if (ahead() == ':')
+		label();
+
 	if (yytoken != ';') {
 		np = expr();
 		emit(OEXPR, np);
@@ -150,39 +182,7 @@
 	expect(';');
 }
 
-static void stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
-
 static void
-Label(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
-{
-	Symbol *sym;
-
-	switch (yytoken) {
-	case IDEN:
-	case TYPEIDEN:
-		/*
-		 * We cannot call to insert() because the call to lookup in
-		 * lex.c was done in NS_IDEN namespace, and it is impossibe
-		 * to fix this point, because an identifier at the beginning
-		 * of a statement may be part of an expression or part of a
-		 * label. This double call to lookup() is going to generate
-		 * an undefined symbol that is not going to be used ever.
-		 */
-		sym = lookup(NS_LABEL);
-		if (sym->flags & ISDEFINED)
-			error("label '%s' already defined", yytoken);
-		sym->flags |= ISDEFINED;
-		emit(OLABEL, sym);
-		next();
-		expect(':');
-		stmt(lbreak, lcont, lswitch);
-		break;
-	default:
-		unexpected();
-	}
-}
-
-static void
 Continue(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	expect(CONTINUE);
@@ -299,6 +299,25 @@
 	}
 }
 
+static void
+blockit(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
+{
+	switch (yytoken) {
+	case TYPEIDEN:
+		if (ahead() == ':')
+			goto parse_stmt;
+		/* PASSTHROUGH */
+	case TYPE:
+	case TQUALIFIER:
+	case SCLASS:
+		decl();
+		return;
+	default:
+	parse_stmt:
+		stmt(lbreak, lcont, lswitch);
+	}
+}
+
 void
 compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
@@ -310,26 +329,13 @@
 	for (;;) {
 		setsafe(END_COMP);
 		setjmp(recover);
-		switch (yytoken) {
-		case '}':
-			goto end_compound;
-		case TYPEIDEN:
-			if (ahead() == ':')
-				goto statement;
-			/* pass through */
-		case TYPE: case SCLASS: case TQUALIFIER:
-			decl();
+		if (yytoken == '}')
 			break;
-		default:
-		statement:
-			stmt(lbreak, lcont, lswitch);
-		}
+		blockit(lbreak, lcont, lswitch);
 	}
 
-end_compound:
 	popctx();
 	expect('}');
-	return;
 }
 
 static void
@@ -352,10 +358,6 @@
 	case CASE:     fun = Case;     break;
 	case DEFAULT:  fun = Default;  break;
 	default:       fun = stmtexp;  break;
-	case TYPEIDEN:
-	case IDEN:
-		fun = (ahead() == ':') ? Label : stmtexp;
-		break;
 	}
 	(*fun)(lbreak, lcont, lswitch);
 }