Я пытаюсь преобразовать правила postfix, infix и prefix из scala в форме EBNF в ANTLR, но вижу ошибку, касающуюся левой рекурсии в правиле infixExpression.
Рассматриваемые правила:
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
;
Если я изменил правило infixExpression на:
public infixExpression
: prefixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression prefixExpression symbolOrID? infixExpression?)
;
Тогда вместо этого он жалуется:
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
Наконец, есть ли способ условно создатьузлы в AST, так что если только левая часть правила является истинной, то это не добавляет этот уровень в?Например:
conditional_or_expression:
conditional_and_expression ('||' conditional_or_expression)?
;
Допустим, я создаю грамматику, которая следует иерархии, например:
conditional_and_expression
conditional_or_expression
null_coalescing_expression
, если анализируемое выражение равно a || b
, в настоящее время AST, которыйсоздан для этого выражения будет
conditional_and_expression
conditional_or_expression
Как я могу получить его, чтобы он просто получил conditional_or_expression
часть?
В JavaCC вы можете просто установить arity узла, например: #ConditionalOrExpression(>1)
РЕДАКТИРОВАТЬ: вчера вечером было немного поздно, инфиксное выражение теперь корректно изменено!
Окончательное редактирование: То, как я заставил его работать вВ конце были следующие правила:
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
;