【发布时间】:2018-11-11 04:06:01
【问题描述】:
我试图隐藏这个 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
【问题讨论】:
-
ANTLR 不支持跨多个规则的左递归。您需要将所有表达式规则组合成一个规则
Expr,并按优先级排序;或者重写语法以去除左递归。 -
“谁能给我指导”和“我被卡住了”不是问题。然而,当我搜索“antlr left recursion tutorial”时,谷歌确实为我找到了以下内容:theantlrguy.atlassian.net/wiki/spaces/ANTLR3/pages/2687334/…
-
@StephenC 请注意,此信息已过时。与 ANTLR3 不同,ANTLR4 确实支持在单个规则中进行左递归,因此解决 OP 问题的最简单方法实际上就是将所有内容放入一个表达式规则中。
标签: java parsing antlr4 parser-generator