[antlr-interest] Disambiguate following rules

Mike Lischke mike at lischke-online.de
Sun Oct 28 05:04:34 PDT 2012


Hi,

> var_decl
> 	: identifier ( '=' expression )?
>         | expression
> 	;

expression can also be an identifier, so you have two alternatives that match the same input. You might be able to solve this with a higher lookahead value, but I'd rather disambiguate this with a predicate like this:

var_decl
	: (identifier '=')? identifier '=' expression
	| expression
	;

You might also just enable backtracking in var_decl rule only (the predicate will use local backtracking anyway for the lookahead).

If you can use the lexer IDENTIFIER rule instead of the parser identifier rule you can even avoid backtracking entirely here using:

var_decl
	: {LA(1) == IDENTIFIER && LA(2) == '='}? identifier '=' expression
	| expression
	;

Yet another solution might be to move the assignment part to your primary expression, if that is valid input for the rest of your grammar (where expression is used):

primary_expression
    : TRUE | FALSE
    | 'defined' '(' expression ')'  /*  for prepocessing */
    | TYPEOF identifier                 /* javascript */
    | TYPEOF '(' identifier ')'         /* javascript */
    | '[' expression? ']'     /* objj array? DIES */
    | '[' expression ',' expression ( ',' expression )* ']'   /* objj array? DIES */
	| message_expression        /*   '[' receiver message_selector ']'  */
	| selector_expression
	| protocol_expression
	| encode_expression
    | '{' STRING_LITERAL ':' primary_expression ( ','  STRING_LITERAL ':' primary_expression )* '}'  /* js obj array? */
    | '{' '}'                                                 /* js empty obj array? */
	| constant
    | identifier ('=' expression)?
    | VAR identifier
	| '(' expression ')'
    ;

and simplify your var_decl to just expression.

Mike
-- 
www.soft-gems.net




More information about the antlr-interest mailing list