commit 54fd1b0ef86755200dce120604c1a876d6123ccb
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Tue Aug 4 09:08:48 2015 +0200
Commit:     Roberto E. Vargas Caballero <k...@shike2.com>
CommitDate: Tue Aug 4 09:20:24 2015 +0200

    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.

diff --git a/cc1/stmt.c b/cc1/stmt.c
index 7f75108..4b34e3a 100644
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -12,9 +12,41 @@ Symbol *curfun;
 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();
@@ -150,38 +182,6 @@ Break(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
        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)
 {
@@ -299,6 +299,25 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
        }
 }
 
+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 @@ compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
        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 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
        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);
 }

Reply via email to