We have the following grammar for a simple language:
stmts^: stmt+;
stmt: nop | if | while | assignment;
nop^: '';
if: 'if'^ expr 'then'! stmts ('else'! stmts)? 'end'!;
while: 'while'^ expr 'do'! stmts 'end'!;
assignment: IDENT '='^ expr;
expr: term (('+'^|'-'^) term)*;
term: atom (('*'^|'/'^) atom)*;
atom: '-'^ atom | IDENT | NATURAL_LIT | '('! expr ')'!;
IDENT: ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;
NATURAL_LIT: ('0'..'9')+;
However, we have detected that one of the loops might hang. This happens when a
certain lookahead is valid to enter a loop, but this loop does not consume
anything with this lookahead. Change the grammar to fix this problem, without
modifying the language or AST construction.