]> ocean-lang.org Git - ocean/commitdiff
parsergen: require all terms to be declared if any are.
authorNeilBrown <neil@brown.name>
Thu, 7 Oct 2021 00:13:44 +0000 (11:13 +1100)
committerNeilBrown <neil@brown.name>
Thu, 7 Oct 2021 00:13:44 +0000 (11:13 +1100)
The previous implementation only required all terms used for the first
time after a $TERM declaration to be declared.  That isn't really
useful.

So change it to only set the default symbol type of Term after all the
grammar is parsed, and then only if not $TERM declarations were found.

This highlights that various terminals in ocean weren't declared, so
declare them now.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/oceani.mdc
csrc/parsergen.mdc

index e3dc493d7fb1b787ba46cca80fb0724d43ef1560..3474508cf6a7018b186c795196f1822ee1332116 100644 (file)
@@ -1582,6 +1582,9 @@ make a copy of an array with controllable recursive depth.
                .free = array_free,
        };
 
+###### declare terminals
+       $TERM [ ]
+
 ###### type grammar
 
        | [ NUMBER ] Type ${
@@ -1818,6 +1821,9 @@ function will be needed.
                free(e);
                break;
 
+###### declare terminals
+       $TERM struct .
+
 ###### variable grammar
 
        | Variable . IDENTIFIER ${ {
@@ -2064,6 +2070,8 @@ an executable.
 
 ###### Grammar
 
+       $TERM True False
+
        $*val
        Value ->  True ${
                        $0 = new_val(Tbool, $1);
@@ -2185,6 +2193,8 @@ link to find the primary instance.
 
 ###### Grammar
 
+       $TERM : ::
+
        $*var
        VariableDecl -> IDENTIFIER : ${ {
                struct variable *v = var_decl(c, $1.txt);
@@ -3002,11 +3012,10 @@ is in-place.
 ###### Binode types
        Block,
 
-###### expr precedence
-       $TERM pass
-
 ###### Grammar
 
+       $TERM { } ;
+
        $*binode
        Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
                | { SimpleStatements } ${ $0 = reorder_bilist($<SS); }$
@@ -3076,6 +3085,7 @@ is in-place.
                        $0->right = $<1;
                        }$
 
+       $TERM pass
        SimpleStatement -> pass ${ $0 = NULL; }$
                | ERROR ${ tok_err(c, "Syntax error in statement", &$1); }$
                ## SimpleStatement Grammar
@@ -3251,6 +3261,9 @@ it is declared, and error will be raised as the name is created as
        Assign,
        Declare,
 
+###### declare terminals
+       $TERM =
+
 ###### SimpleStatement Grammar
        | Variable = Expression ${
                        $0 = new(binode);
@@ -3921,6 +3934,8 @@ various declarations in the parse context.
        $void
        Ocean -> OptNL DeclarationList
 
+       ## declare terminals
+
        OptNL ->
                | OptNL NEWLINE
        Newlines -> NEWLINE
@@ -3964,6 +3979,8 @@ searching through for the Nth constant for decreasing N.
 
 ###### top level grammar
 
+       $TERM const
+
        DeclareConstant -> const { IN OptNL ConstList OUT OptNL } Newlines
                | const { SimpleConstList } Newlines
                | const IN OptNL ConstList OUT Newlines
@@ -4070,6 +4087,8 @@ analysis is a bit more interesting at this level.
                        c->prog = $<1;
        } }$
 
+       $TERM program
+
        $*binode
        Program -> program OpenScope Varlist ColonBlock Newlines ${
                $0 = new(binode);
index 4faea9ec69ed2f103c017651419db173556c6c26..80027aa74e49989428ea370172c3a783c8ebfd40 100644 (file)
@@ -515,10 +515,6 @@ Now we have all the bits we need to parse a full production.
                tk = token_next(state);
                while (tk.num == TK_ident || tk.num == TK_mark) {
                        struct symbol *bs = sym_find(g, tk.txt);
-                       if (bs->type == Unknown) {
-                               if (!g->terminals_declared)
-                                       bs->type = Terminal;
-                       }
                        if (bs->type == Virtual) {
                                err = "Virtual symbol not permitted in production";
                                goto abort;
@@ -692,20 +688,22 @@ used as a terminal anywhere that a terminal is expected.
                                goto abort;
                }
                token_close(state);
-               if (g->terminals_declared) {
-                       struct symbol *s;
-                       int errs = 0;
-                       for (s = g->syms; s; s = s->next) {
-                               if (s->type != Unknown)
-                                       continue;
-                               errs += 1;
-                               fprintf(stderr, "Token %.*s not declared\n",
-                                       s->name.len, s->name.txt);
-                       }
-                       if (errs) {
-                               free(g); // FIXME free content
-                               g = NULL;
+
+               struct symbol *s;
+               for (s = g->syms; s; s = s->next) {
+                       if (s->type != Unknown)
+                               continue;
+                       if (!g->terminals_declared) {
+                               s->type = Terminal;
+                               continue;
                        }
+                       err = "not declared";
+                       fprintf(stderr, "Token %.*s not declared\n",
+                               s->name.len, s->name.txt);
+               }
+               if (err) {
+                       free(g); // FIXME free content
+                       g = NULL;
                }
                return g;
        abort: