Previously an IN had to follow a terminal because it would never for a
reduce.
This made is a problem for
func FuncName
arguments
do
code
as the IN follows FuncName - a non-terminal.
Fix this by allowing an IN to force a reduce if nothing at all can be
shifted.
After "func IDENTIFIER", nothing can be shifted. The IDENTIFIER must be
reduced to FuncName. At that point, the IN is expected, so it won't be
ignored.
This allows the 'then' to be dropped.
Signed-off-by: NeilBrown <neil@brown.name>
} else
var_block_close(c, CloseSequential, NULL);
} }$
} else
var_block_close(c, CloseSequential, NULL);
} }$
- | func FuncName then IN OpenScope OptNL Args OUT OptNL do Block Newlines ${ {
- // FIXME that 'then' should not be there.
+ | func FuncName IN OpenScope OptNL Args OUT OptNL do Block Newlines ${ {
struct text funcname = { " func", 5};
$0 = $<FN;
if ($0) {
struct text funcname = { " func", 5};
$0 = $<FN;
if ($0) {
}
Indents are ignored unless they can be shifted onto the stack
}
Indents are ignored unless they can be shifted onto the stack
-immediately. The end of an indented section - the OUT token - is
-ignored precisely when the indent was ignored. To keep track of this we
-need a small stack of flags, which is easily stored as bits in an
-`unsigned long`. This will never overflow and the scanner only allows
-20 levels of indentation.
+immediately or nothing can be shifted (in which case we reduce, and try
+again). The end of an indented section - the OUT token - is ignored
+precisely when the indent was ignored. To keep track of this we need a
+small stack of flags, which is easily stored as bits in an `unsigned
+long`. This will never overflow and the scanner only allows 20 levels
+of indentation.
###### parser state
unsigned long ignored_indents;
###### parser state
unsigned long ignored_indents;
- if (tk->num == TK_in) {
- /* No indent expected here, so ignore IN */
+ if (tk->num == TK_in && states[p.stack[p.tos-1].state].go_to_cnt > 0) {
+ /* No indent expected here and reduce is not mandatory, so ignore IN */
free(tk);
tk = NULL;
p.ignored_indents <<= 1;
free(tk);
tk = NULL;
p.ignored_indents <<= 1;