如何使用antlr4恢复特定行和字符位置的ParserRuleContext?

时间:2018-12-30 17:23:02

标签: c++ antlr4

一旦我初始化了解析器,词法分析器并获得了translationUnit上下文,我如何直接跳转到在antlr4(CPP运行时)中包含特定行和字符位置的(最近)ParserRuleContext?

通常,我使用Listener模式来遍历translationUnit上下文。在每个访问的上下文中,我可以使用以下代码获取上下文的相应行和字符位置:

antlr4::Token* tokenclass = _tokenstream->get(myContext->getSourceInterval().a); // use ".b" if end of interval is needed 
size_t CharPositionStartInLine = tokenclass->getCharPositionInLine();       
size_t LineStart = tokenclass->getLine();

我想执行相反的操作:从特定的行和char位置获取令牌,然后获取(第一个)父上下文。有可能吗?

我认为我可以通过检查函数contextenterEveryRule(antlr4::ParserRuleContext* context)的每一行和每个字符的位置来实现我想要的(即根据行和字符的位置找到一个上下文),但这似乎太复杂了。那么,有没有一种更简单的方法来恢复特定行/字符位置的ParserRuleContext?

1 个答案:

答案 0 :(得分:1)

方法非常简单。 ParserRuleContext包含带有定位信息的开始标记和停止标记。因此,很容易判断规则上下文是否包含特定位置。从解析树根开始,并遍历其子级。找到一个包含该位置的位置(不可能重叠)。继续处理该节点及其子节点,直到找到要查找的终端节点。如果对于给定的节点,没有子项包含给定的位置,请改用该节点。

MySQL Workbench Sources中,有一个terminalFromPositioncontextFromPosition的C ++实现。第一个函数采用行/列对,并力争始终返回一个终端(即使在给定位置没有直接返回),而第一个函数使用字符索引并完全按照上一段所述实现方法。