I'm trying to write a parser for a maxscript that has several ambiguous statements. Example grammar:
program: expr* EOF ;
expr: simple_expr | case_expr ;
// fn_call must be first, if not, the program matches a sequence of operands...
simple_expr : fn_call | operand | ...;
// case val of (1:true; 2:false; 3:someVal, default:false)
case_expr :
'('
case_clause (Nl case_clause)*
')'
;
case_clause: case_clause_def expr ;
// no whitespace nor newlines here
case_clause_def: factor ':';
// calle arg arg param:val param:val....
// grammar reference says 'until an eol or lower precedence token'
// No new lines allowed between the call args or parameters
fn_call
: caller = (var_name | accessor) (args+=operand | params+=param))+
| caller = (var_name | accessor) '()'
;
param: param_name expr;
// no whitespace nor newlines here
param_name: var_name ':' ;
operand: factor | accessor;
factor
: var_name
| number
| ...
;
...
Nl : {this.lineTerminatorAhead()}?
;
I'm unable to correctly handle the 'NO NEW LINES' requirement (because predicates are not at the left and get ignored? or they do not work with the quantifiers?) resulting in an ambiguous grammar between <fn_call> and <case_clause>
test code:
case mode of (
1: 5
2: someVal
default: 10
)
Expected result
case expr: case mode of (1:5; 2: someVal; default:10)
Actual result:
case expr: case mode of (1:5; 2:someVal; default:10); fn_call: someVal default:10
:
or|
.