我正在尝试编写一个匹配事物列表的ANTLR解析器规则,我想编写一个解析器操作,可以独立处理列表中的每个项目.
这些规则的一些示例输入是:
$(A1 A2 A3)
我希望这会产生一个评估器,其中包含三个MyIdentEvaluator对象的列表 – 每个对象分别对应A1,A2和A3.
这是我的语法片段:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
op=my_ident+ {
/* want to do something here for each 'my_ident'. */
/* the following seems to see only the 'A3' my_ident */
$e.Add($op.e);
}
RPAREN
;
my_ident returns [IEvaluator e]
: IDENT { $e = new MyIdentEvaluator($IDENT.text); }
;
我认为my_ident是正确定义的,因为我可以看到三个MyIdentEvaluators按照我的输入字符串的预期创建,但只有最后一个my_ident被添加到列表中(在我的示例输入中为A3).
如何通过语法更改或解析器操作更改来独立地最好地处理每个元素?
在我看来,我对这些概念的词汇不是它应该是的,所以如果它看起来像是在滥用一个术语,我可能就是这样.
编辑回应Wayne的评论:
我尝试使用op = my_ident.在这种情况下,我的操作中的$op成为包含Antlr.Runtime.Tree.CommonTree实例的IList(在C#中).它确实在$op中为每个匹配的令牌提供了一个条目,所以我看到了我的三个匹配,但是我没有我真正想要的MyIdentEvaluator实例.我希望我能在ANTLR文档中找到一个可能对此有帮助的规则属性,但似乎没有任何东西可以帮助我摆脱这个IList.
结果…
根据chollida的回答,我最终得到了这个效果很好:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
(op=my_ident { $e.Add($op.e); } )+
RPAREN
;
为my_ident的每个匹配调用Add方法.
最佳答案 如果我写这篇文章,我会将个别匹配分成列表模式:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
op=my_ident { $e.Add($op.e); }
(opNext=my_ident { $e.Add($opNext.e); })*
RPAREN
;
my_ident returns [IEvaluator e]
: IDENT { $e = new MyIdentEvaluator($IDENT.text); }
;
这里不是使用Antlr内置的,而是自己进行迭代.我们匹配第一个项目并将其添加到列表中,然后我们匹配连续项目并存储它们.