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>
+###### declare terminals
+ $TERM [ ]
+
###### type grammar
| [ NUMBER ] Type ${
###### type grammar
| [ NUMBER ] Type ${
+###### declare terminals
+ $TERM struct .
+
###### variable grammar
| Variable . IDENTIFIER ${ {
###### variable grammar
| Variable . IDENTIFIER ${ {
$*val
Value -> True ${
$0 = new_val(Tbool, $1);
$*val
Value -> True ${
$0 = new_val(Tbool, $1);
$*var
VariableDecl -> IDENTIFIER : ${ {
struct variable *v = var_decl(c, $1.txt);
$*var
VariableDecl -> IDENTIFIER : ${ {
struct variable *v = var_decl(c, $1.txt);
###### Binode types
Block,
###### Binode types
Block,
-###### expr precedence
- $TERM pass
-
$*binode
Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
| { SimpleStatements } ${ $0 = reorder_bilist($<SS); }$
$*binode
Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Sl; }$
| { SimpleStatements } ${ $0 = reorder_bilist($<SS); }$
SimpleStatement -> pass ${ $0 = NULL; }$
| ERROR ${ tok_err(c, "Syntax error in statement", &$1); }$
## SimpleStatement Grammar
SimpleStatement -> pass ${ $0 = NULL; }$
| ERROR ${ tok_err(c, "Syntax error in statement", &$1); }$
## SimpleStatement Grammar
+###### declare terminals
+ $TERM =
+
###### SimpleStatement Grammar
| Variable = Expression ${
$0 = new(binode);
###### SimpleStatement Grammar
| Variable = Expression ${
$0 = new(binode);
$void
Ocean -> OptNL DeclarationList
$void
Ocean -> OptNL DeclarationList
OptNL ->
| OptNL NEWLINE
Newlines -> NEWLINE
OptNL ->
| OptNL NEWLINE
Newlines -> NEWLINE
DeclareConstant -> const { IN OptNL ConstList OUT OptNL } Newlines
| const { SimpleConstList } Newlines
| const IN OptNL ConstList OUT Newlines
DeclareConstant -> const { IN OptNL ConstList OUT OptNL } Newlines
| const { SimpleConstList } Newlines
| const IN OptNL ConstList OUT Newlines
$*binode
Program -> program OpenScope Varlist ColonBlock Newlines ${
$0 = new(binode);
$*binode
Program -> program OpenScope Varlist ColonBlock Newlines ${
$0 = new(binode);
tk = token_next(state);
while (tk.num == TK_ident || tk.num == TK_mark) {
struct symbol *bs = sym_find(g, tk.txt);
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;
if (bs->type == Virtual) {
err = "Virtual symbol not permitted in production";
goto abort;
goto abort;
}
token_close(state);
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;