简体   繁体   English

将BNF语法的形式转换为g4语法

[英]Convert a form of BNF grammar to g4 grammar

I'm trying to covert this BNF grammar for validating boolean expression which is currently being used in Swift. 我试图隐瞒此BNF语法以验证当前在Swift中使用的布尔表达式。 Now want to implement similar parser in Java. 现在想在Java中实现类似的解析器。 I came across Antlr4 lib and want to use it to generate parser for the same grammar. 我遇到过Antlr4 lib,想用它为同一语法生成解析器。 I'm not very familiar with antlr4. 我对antlr4不太熟悉。 Can someone please provide me some guidance? 有人可以给我一些指导吗? This is what I have so far. 到目前为止,这就是我所拥有的。

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>;

I tried to convert to g4 and this is what it looks like. 我试图转换为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
    ;

I'm stuck at antlr4 VALIDATE.g4 step. 我被困在antlr4 VALIDATE.g4步骤中。 I'm not sure I did the conversion right. 我不确定我的转换正确吗。

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

The original grammar has no mutual left recursion - that was only introduced in the converted version by using && in ConcatenationExpr where it should have read & . 原始语法没有相互的左递归-只是在转换后的版本中通过在ConcatenationExpr中使用&&引入的,该语法应该读为& Once that is fixed, the grammar has only direct left recursion which ANTLR 4 should be able to cope with. 一旦确定,语法仅具有ANTLR 4应该能够应付的直接左递归。

You could even completely remove left recursion by rewriting recursive rules, such that eg ConcatenationExpr would become 您甚至可以通过重写递归规则来完全删除左递归,例如, ConcatenationExpr将变为

ConcatenationExpr
     ::= AndExpr ( '&' AndExpr )*

If this is done for all recursive rules, the resulting grammar is LL(2). 如果对所有递归规则都这样做,则生成的语法为LL(2)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM