commit 54fd1b0ef86755200dce120604c1a876d6123ccb
parent ededd35636769e3b9facdef0ed3b3255f8aa85a6
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 4 Aug 2015 09:08:48 +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.
Diffstat:
M | cc1/stmt.c | | | 106 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
1 file changed, 54 insertions(+), 52 deletions(-)
diff --git 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);
}