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

时间:2018-11-11 04:06:01

标签: java parsing antlr4 parser-generator

我正在尝试隐瞒此BNF语法以验证当前在Swift中使用的布尔表达式。现在想在Java中实现类似的解析器。我遇到过Antlr4 lib,想用它为同一语法生成解析器。我对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

1 个答案:

答案 0 :(得分:0)

原始语法没有相互的左递归-只是在转换版本中通过使用&&中的ConcatenationExpr引入的,该语法应该读为&。一旦确定,语法仅具有ANTLR 4应该能够应付的直接左递归。

您甚至可以通过重写递归规则来完全删除左递归,例如ConcatenationExpr将变为

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

如果对所有递归规则都这样做,则语法为LL(2)。