I'm trying to convert the postfix, infix and prefix rules from scala in EBNF form to ANTLR but am seeing an error relating to left-recursion on the infixExpression rule.
The rules in question are:
public symbolOrID
: ID
| Symbol
;
public postfixExpression
: infixExpression symbolOrID? -> ^(R__PostfixExpression infixExpression symbolOrID?)
;
public infixExpression
: prefixExpression
| infixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression infixExpression symbolOrID? infixExpression?)
;
public prefixExpression
: prefixCharacter? simpleExpression -> ^(R__PrefixExpression prefixCharacter? simpleExpression)
;
public prefixCharacter
: '-' | '+' | '~' | '!' | '#'
;
public simpleExpression
: constant
;
If I change the infixExpression rule to:
public infixExpression
: prefixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression prefixExpression symbolOrID? infixExpression?)
;
Then it instead complains:
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} String" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Number" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Boolean" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Regex" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Null" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
Lastly, is there a way to conditionally create the nodes in the AST so that if only the left part of the rule is true then it doesn't add that level in? E.g.:
conditional_or_expression:
conditional_and_expression ('||' conditional_or_expression)?
;
As in, lets say I create the grammar which follows a hierarchy like:
conditional_and_expression
conditional_or_expression
null_coalescing_expression
if the expresion that is parsed is a || b
, currently the AST that is created is for this expression would be
conditional_and_expression
conditional_or_expression
How could I get it so it just gets the conditional_or_expression
part?
In JavaCC, you could just set the node arity, e.g.: #ConditionalOrExpression(>1)
EDIT: it was a bit late last night, infix expression is now propery modified!
Final edit: The way I got it to work in the end were the following rules:
public symbolOrID
: ID
| Symbol
;
public postfixExpression
: infixExpression (symbolOrID^)?
;
public infixExpression
: (prefixExpression symbolOrID)=> prefixExpression symbolOrID^ infixExpression
| prefixExpression
;
public prefixExpression
: prefixCharacter^ simpleExpression
| simpleExpression
;
public prefixCharacter
: '-' | '+' | '~' | '!' | '#'
;
public simpleExpression
: constant
;
infixExpression
rule twice (you didn't change anything about it...). – Bart Kiers