Преобразовать форму грамматики BNF в грамматику g4
Я пытаюсь скрыть эту грамматику BNF для проверки логического выражения, которое в настоящее время используется в Swift. Теперь хочу реализовать подобный парсер в Java. Я наткнулся на библиотеку Antlr4 и хочу использовать ее для генерации парсера для той же грамматики. Я не очень знаком с antlr4. Может кто-нибудь дать мне несколько советов? Это то, что я до сих пор.
Expr ::= <ConcatenationExpr>;
NonInfixExpr ::= <BracketExpr>
| <Function>
| <Literal>
| <Accessor>;
BracketExpr ::= '(' <Expr> ')';
Accessor ::= ('$' <AccessorComponent> | <AccessorComponent>) ('.' <AccessorComponent> )*;
AccessorComponent ::= 'Identifier' ':' 'Identifier' | 'Identifier';
Function ::= 'Identifier' '(' ')' | ('Identifier' '(' <Expr> (',' <Expr>)* ')');
Literal ::= 'True'
| 'False'
| 'Null'
| 'Number'
| 'Text';
ConcatenationExpr ::= <AndExpr>
| <ConcatenationExpr> '&' <AndExpr>;
AndExpr ::= <OrExpr>
| <AndExpr> '&&' <OrExpr>;
OrExpr ::= <EqualityExpr>
| <OrExpr> '||' <EqualityExpr>;
EqualityExpr ::= <ComparisonExpr>
| <EqualityExpr> ('==' | '=' | '!=' | '<>') <ComparisonExpr>;
ComparisonExpr ::= <AddExpr>
| <AddExpr> ('<' | '<=' | '>' | '>=') <AddExpr>;
AddExpr ::= <ExponentialExpr>
| <AddExpr> ('+' | '-') <ExponentialExpr>;
ExponentialExpr ::= <MultExpr>
| <ExponentialExpr> '^' <MultExpr>;
MultExpr ::= <NonInfixExpr>
| <MultExpr> ('*' | '/') <NonInfixExpr>;
Я попытался преобразовать в g4, и вот как это выглядит.
grammar VALIDATE;
Expr
: ConcatenationExpr ';'
;
NonInfixExpr
: BracketExpr
| Function
| Literal
| Accessor
;
BracketExpr
: '(' Expr ')'
;
Accessor
: ('$' AccessorComponent | AccessorComponent ) ('.' AccessorComponent )*
;
AccessorComponent
: 'Identifier' ':' 'Identifier' | 'Identifier'
;
Function
: 'Identifier' '(' ')' | ('Identifier' '(' Expr (',' Expr)* ')')
;
Literal
: 'True' | 'False' | 'Null' | 'Number' | 'Text'
;
ConcatenationExpr
: AndExpr
| ConcatenationExpr '&&' AndExpr
;
AndExpr
: OrExpr | AndExpr '&&' OrExpr
;
OrExpr
: EqualityExpr | OrExpr '||' EqualityExpr
;
EqualityExpr
: ComparisonExpr | EqualityExpr ('==' | '=' | '!=' | '<>') ComparisonExpr
;
ComparisonExpr
: AddExpr | AddExpr ('<' | '<=' | '>' | '>=') AddExpr
;
AddExpr
: ExponentialExpr | AddExpr ('+' | '-') ExponentialExpr
;
ExponentialExpr
: MultExpr | ExponentialExpr '^' MultExpr
;
MultExpr
: NonInfixExpr | MultExpr ('*' | '/') NonInfixExpr
;
Я застрял на шаге antlr4 VALIDATE.g4. Я не уверен, что сделал преобразование правильно.
error(119): VALIDATE.g4::: The following sets of rules are mutually left-recursive [MultExpr] and [ExponentialExpr] and [AddExpr] and [EqualityExpr] and [OrExpr] and [AndExpr] and [ConcatenationExpr]
error(99): VALIDATE.g4::: grammar VALIDATE has no rules
0 ответов
Исходная грамматика не имеет взаимной левой рекурсии - это было введено только в преобразованной версии с использованием &&
в ConcatenationExpr
где он должен был прочитать &
, Как только это исправлено, грамматика имеет только прямую левую рекурсию, с которой ANTLR 4 должна справиться.
Вы можете даже полностью удалить левую рекурсию, переписав рекурсивные правила, например, такие как ConcatenationExpr
станет
ConcatenationExpr
::= AndExpr ( '&' AndExpr )*
Если это сделано для всех рекурсивных правил, результирующая грамматика будет LL(2).