ANTLR:如何检测两个相同模式的事件作为单独的“访问”

2024-10-04 07:25:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的语法:

constant:  ptype (rangebox)* ID (rangebox)* '=' expr END ;
ptype: 'logic' | 'integer' ;
rangebox: '[' expr ':' expr ']' ;
/* expr related rules which are not relevant here */

我使用ANTLR的Python输出,在我的Python程序中,我使用visitor(而不是listener)来构建我的数据结构。在visitConstant中,如果执行visitRangebox(),则会出现问题,因为它会返回所有rangebox匹配项(在ID之前或之后)。我需要将rangebox匹配项在ID之前存储在一个单独的列表中,后面的匹配项存储在一个单独的列表中。如何在visitConstant中分别访问它们?你知道吗

编辑:忘了提一下我确实尝试过这样的事情:

leftRanges = self.visit(ctx.rangebox(0))
rightRanges = self.visit(ctx.rangebox(1))

但我有个错误:

AttributeError: 'NoneType' object has no attribute 'accept'

编辑:我修正了属性错误,首先添加了一个检查(duh!)。但我现在看到的是0或1并不对应于ID之前或之后,它只是表示所有范围列表中的索引。如何区分遇到ID之前和之后发生的范围匹配?你知道吗


Tags: selfid编辑列表错误语法visitend
1条回答
网友
1楼 · 发布于 2024-10-04 07:25:19

它们不匹配,因为ANTLR将它们放在一个列表中。您可以做的一件事是创建只包含rangebox的新规则。像这样:

constant:  ptype (left_rangebox)* ID (right_rangebox)* '=' expr END ;
ptype: 'logic' | 'integer' ;
rangebox: '[' expr ':' expr ']' ;
left_rangebox: rangebox ;
right_rangebox: rangebox ;

然后可以通过创建for循环来访问它们。我对Python不太了解,但下面是它在Java中的实现方式:

for(Left_rangeboxContext ctxt : ctx.left_rangebox){
    visit(ctxt);
}

另一个解决方案是使用ANTLR的标签。不过,我不确定这是否有效,但这可能值得一试:

constant:  ptype left=(rangebox)* ID right=(rangebox)* '=' expr END ;

其思想是,在ANTLR中,您可以在使用解析器或lexer规则时添加标签,以便在访问它们时更容易地访问它们。我不确定当你有一个上下文列表时它是否有效。如果不是,第一个解决方案仍然有效:)

相关问题 更多 >