是否有让Antlr4识别用于解析输入的语法版本的好方法?
如果我有两个语法,即GA和GB,其中GA是GB的子集,而GB则是从GA导入的,如果解析的输入是使用GA或GB解析的,是否可以让Antlr4报告?
我可以先尝试先使用GB解析,如果失败则尝试使用GA解析,但我想知道是否有一种更有效的方法让Antlr跟踪使用的规则并说:“我成功解析了此规则但只使用了GA语法中的规则”。
答案 0 :(得分:0)
正确的方法是将每个规则(或仅关键规则)与解析器版本相关联。
首先,您需要一个字段来跟踪当前版本:
@members {
int currentVersion = 1;
}
现在,让我们假设您有一个规则RULE_ONE
与版本 one 相关,而RULE_TWO与版本 two 相关。
每次接受与较高版本相关的规则时,currentVersion
字段都应更改:
RULE_ONE
{currentVersion = Math.max(1, currentVersion);} //1 is the parser version
: some_token
;
RULE_TWO
{currentVersion = Math.max(2, currentVersion);} //2 is the parser version
: some_token
;
因此,解析完成后,您可以获得已使用的最大版本。
答案 1 :(得分:0)
并非完全是您的要求,但是in my MySQL grammar我必须支持多个服务器版本,这是通过使用语义谓词来实现的。这意味着,我可以使用一个语法并根据解析器中的serverVersion
字段启用/禁用某些路径。看起来像这样:
alterDatabase:
DATABASE_SYMBOL schemaRef (
createDatabaseOption+
| {serverVersion < 80000}? UPGRADE_SYMBOL DATA_SYMBOL DIRECTORY_SYMBOL NAME_SYMBOL
)
;
,效果很好。即使在the lexer中,我也可以使用这种方法(但出于性能原因,其中包含验证语义谓词),这使我可以打开和关闭关键字,如下所示:
CONTRIBUTORS_SYMBOL: C O N T R I B U T O R S {serverVersion < 50700}?;