当语法谓词数量较大时,将Antlr3语法谓词转换为Antlr4中的等效语法
我的Antlr3解析器规则如下所示:当语法谓词数量较大时,将Antlr3语法谓词转换为Antlr4中的等效语法,antlr4,antlr3,Antlr4,Antlr3,我的Antlr3解析器规则如下所示: ruleA: (TOKEN_1) => TOKEN_1 ruleToken1 | (TOKEN_2) => TOKEN_2 ruleToken2 .... .... <many more such rules> | genericRuleA ; 这很好,除非如果ruleToken1的其余部分失败,解析器会自动选择genericRuleA作为首选路径。所以现在,我有一个副作用,就是能够“重载”命名函
ruleA:
(TOKEN_1) => TOKEN_1 ruleToken1
| (TOKEN_2) => TOKEN_2 ruleToken2
....
....
<many more such rules>
| genericRuleA
;
这很好,除非如果ruleToken1
的其余部分失败,解析器会自动选择genericRuleA
作为首选路径。所以现在,我有一个副作用,就是能够“重载”命名函数。这在某些情况下可能有用,但在我的情况下,要求明确不允许这种重载,即命名函数必须符合ruleToken1
中列出的特定结构,如果违反该结构,则报告错误。为其编写此语法的系统不支持重载函数
genericRuleA
必须满足命名函数以外的任何功能
我的第一个问题:有没有标准的方法来实现这种转换?
我见过的一种方法是创建与命名函数(TOKEN_1、TOKEN_2等)相对应的令牌列表;构造一个@parser::member
函数,如果输入标记在此列表中具有成员身份,则该函数将返回true
。因此,假设适当定义了一个isNamedFunction()
,则该规则如下所示:
ruleA:
TOKEN_1 ruleToken1
| TOKEN_2 ruleToken2
| {!isNamedFunction()}? genericRuleA
;
当您只有几个命名函数时,这可能会起作用,但如果您可能有数百个(例如,考虑TSQL中的内置函数),那么构建该列表将非常麻烦。更不用说,随着新命名函数的出现,我将不得不不断更新该列表
因此,我的后续问题是:假设上面概述的语义谓词方法是正确的方法,那么有没有一种方法可以以编程方式组装列表?
一种似乎有希望的方法是从getExpectedTokens()
构建它。在这里,我将稍微重新构造规则,使所有命名函数都属于一个规则(我们称之为namedRuleA
),如下所示:
规则a:
蒙德鲁利亚
|总规则
;
namedRuleA:
令牌1规则令牌1
|令牌2规则令牌2
....
....
;
然后从ruleA的ATNState
[recognizer.getATN().states.get(recognizer.getState())
]开始,我会沿着过渡走到namedRuleA
的ATNState
,然后使用getATN().getExpectedTokens(
ruleA:
TOKEN_1 ruleToken1
| TOKEN_2 ruleToken2
| {!isNamedFunction()}? genericRuleA
;
ruleA:
namedRuleA
| genericRuleA
;
namedRuleA:
TOKEN_1 ruleToken1
| TOKEN_2 ruleToken2
....
....
<many more such rules>
;