首页 > 解决方案 > 使用侦听器遍历 anltr 解析树的问题

问题描述

我一直在使用 Antlr,尝试在数据结构中解析和存储(antlr 中的语法).g4 文件,以便我能够对规则进行变异,然后在具有变异规则的 garmmars 上运行 antlr。我有 ANTLRv4Parser 语法,我正在尝试编写一个沿着存储令牌的树走的侦听器。但是,这样做是可行的,但对于带有替代管道“|”的规则 符号似乎已关闭。这来自 antlrv4parser 语法中的以下规则 ruleAltList :alternative (OR alternative)* 。因此,我似乎在努力从管道之前的替代子节点获取令牌,然后在我的侦听器的 enterRuleAltList 中的管道之后获取令牌,似乎 antlr 进行了前序遍历,因此它在前往替代之前获取管道。

所以我想要的可能是在 antlr 中使用相同的侦听器模式和某种中序遍历。

这是 antlrv4parser 语法的片段

ruleAltList: labeledAlt (OR labeledAlt)* ;

anltrv4parser 语法和其他语法可以在这个链接上找到https://github.com/antlr/grammars-v4/tree/master/antlr4

例如,如果我有以下语法

grammar c; A : B | C;

我希望能够将数据结构存储为 ["A", ":", "B","|","C",";"]

我得到的是 ["A", ":", "|","B", "C",";"]

那么关于如何在我的侦听器中覆盖 enterRuleAltList 方法以在 OR 之前获得来自替代子节点的令牌的任何想法,即“|”?

标签: antlrantlr4

解决方案


语法的简化表示:

parserRuleSpec
   : RULE_REF COLON ruleBlock SEMI 
   ;

ruleBlock
   : ruleAltList
   ;

ruleAltList
   : labeledAlt (OR labeledAlt)*
   ;

labeledAlt
   : terminal
   ;

收集遍历过程中遇到的节点的所有终端应该导致排序["A", ":", ";", "|", "B", "C"]。(如果最初给出的不是错字,请发布实际的完整侦听器代码。)

enterParserRuleSpec -> A : ;
    enterRuleBlock
       enterRuleAltList -> |
           enterLabeledAlt 
               enterTerminal -> B
           enterLabeledAlt
               enterTerminal -> C

收集终端时,必须注意它们在上下文子列表中相对于其兄弟非终端的顺序。

或者,可能只是将终端收集到按令牌索引排序的列表中。


推荐阅读