用Antlr4识别文法的版本

Identifying the version of the grammar with Antlr4

有没有好的方法让 Antlr4 识别用于解析输入的语法版本?

如果我有两个语法,GA 和 GB,其中 GA 是 GB 的一个子集,其中 GB 导入 GA 如果解析的输入是使用 GA 或 GB 解析的,有没有办法让 Antlr4 报告?

我可以简单地先尝试用 GB 解析它,如果失败尝试用 GA 解析它,但我想知道是否有更有效的方法让 Antlr 跟踪使用了哪些规则并说,"I successfully parsed this but only used rules from the GA grammar".

正确的方法是将每个规则(或仅关键规则)与解析器版本相关联。

首先,您需要一个字段来跟踪当前版本:

@members {
    int currentVersion = 1;
}

现在,假设您有一个规则 RULE_ONE 与版本 one 和 RULE_TWO 与版本 two[ 相关=25=].
每次接受与更高版本相关的规则时,应更改 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
    ;

这样,解析完成后,就可以得到已经使用的最大版本

不完全是您要问的,但是 in my MySQL grammar 我必须支持多个服务器版本,我通过使用语义谓词来做到这一点。这意味着,我可以使用单一语法和 enable/disable 某些路径,具体取决于我在解析器中的 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}?;