用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}?;
有没有好的方法让 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}?;