一旦我初始化了解析器,词法分析器并获得了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位置获取令牌,然后获取(第一个)父上下文。有可能吗?
我认为我可以通过检查函数context
中enterEveryRule(antlr4::ParserRuleContext* context)
的每一行和每个字符的位置来实现我想要的(即根据行和字符的位置找到一个上下文),但这似乎太复杂了。那么,有没有一种更简单的方法来恢复特定行/字符位置的ParserRuleContext?
答案 0 :(得分:1)
方法非常简单。 ParserRuleContext
包含带有定位信息的开始标记和停止标记。因此,很容易判断规则上下文是否包含特定位置。从解析树根开始,并遍历其子级。找到一个包含该位置的位置(不可能重叠)。继续处理该节点及其子节点,直到找到要查找的终端节点。如果对于给定的节点,没有子项包含给定的位置,请改用该节点。
在MySQL Workbench Sources中,有一个terminalFromPosition
和contextFromPosition
的C ++实现。第一个函数采用行/列对,并力争始终返回一个终端(即使在给定位置没有直接返回),而第一个函数使用字符索引并完全按照上一段所述实现方法。>