0

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

3
  • Without the whole grammar, we can't solve this. But, generally speaking, you cannot place semantic predicates in the middle of a rule's element list. A semantic predicate has to go at the beginning of an alt, just after a : or |.
    – kaby76
    Commented Jul 8 at 21:32
  • @kaby76 I've copied that solution from [ Javascript antrl4 grammar ](github.com/antlr/grammars-v4/tree/master/javascript), and you're right, it only blocks the part of the rule where the predicate is, jumping on the next 'alt' of returning part of the rule if no other option satisfies it. The problem is that the parser will always assume that 'expr' is 'fn_call' instead of factor. The meaning of "accessor" is irrelevant in the example. Commented Jul 8 at 23:17
  • Looks like the javascript grammar is wrong, because the Antlr tool allows you to place semantic predicates in other positions, but it really should not. This is because Antlr really does not do "backtracking": it calls "AdaptivePredict()" to determine the parser when a choice is needed. The semantic predicate has to go all the way up the chain of rules to the point where it properly needs to make that choice. I will make a note in the grammars-v4 repo. Ty.
    – kaby76
    Commented Jul 9 at 11:13

0

Browse other questions tagged or ask your own question.