From: NeilBrown Date: Thu, 7 Oct 2021 00:13:44 +0000 (+1100) Subject: parsergen: require all terms to be declared if any are. X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=7643c19409c4d3c6d94412a85d0dc048a6e8a68f parsergen: require all terms to be declared if any are. 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 --- diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index e3dc493..3474508 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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 = $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); diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index 4faea9e..80027aa 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -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: