我正在嘗試編寫一個ANTLR解析器規則,該規則匹配事物列表,並且我想要編寫一個可以獨立處理列表中每個項目的解析器操作。如何爲可匹配多個項目的規則中的每個項目執行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)。
如何通過語法更改或解析器操作更改獨立地對待每個元素?
我還想到,我對這些概念的詞彙量並不是它應該是的,所以如果看起來我濫用了一個詞,我可能是。
編輯迴應韋恩的評論:
我試圖用op+=my_ident+
。在這種情況下,我的動作中的$op
變爲IList
(在C#中),其中包含Antlr.Runtime.Tree.CommonTree
實例。它在$op
中爲每個匹配的令牌提供了一個條目,所以我看到了我的三個匹配項,但我沒有我真正想要的實例。我希望能夠在ANTLR文檔中找到一個可能有助於此的規則屬性,但似乎沒有任何東西可以幫助我擺脫這種IList
。
結果...
基於chollida的答案,我結束了這個效果很好:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
(op=my_ident { $e.Add($op.e); })+
RPAREN
;
的Add
方法被調用的my_ident的每場比賽。這裏
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的內置的+
我們迭代自己的:
對於我來說,回答你的問題還不夠,是否$ op不包含所有三個標記?還是其他的東西,比如你想爲每個標記做一些特定的事情?爲了將所有三個令牌放入$ op中,我認爲您需要op + = my_ident +(等號前面的另一個加號)。我需要更多信息來回答另一個問題。 – WayneH 2010-02-02 00:06:35
我的問題是我真的不知道「$ op」究竟是什麼。我到了那裏,部分歸功於你對這個和其他問題的幫助!我訂購了Terence Parr書。 :)是的,我只是想能夠對每個令牌做同樣的事情 - 在這種情況下,將令牌添加到列表中。我將編輯我的問題以反映您提出的「op +」建議的結果。 – 2010-02-02 05:45:36
好吧,所以來自該規則的my_ident和返回值加上$ op都按預期工作(此時通緝)。現在獲取my_list中的$ e以返回正確的對象。它應該只返回$ op的列表嗎?我想一個你想修改my_list規則在開始時是 - my_list返回[IEvaluator e] @init {$ e = new MyListEvaluator(); } :'$'... 另外,您可能希望更改my_ident或my_list中的返回標籤/變量;他們兩個都可能會有點混亂。 接下來是MyListEvaluator vs MyIdentEvaluator(我不知道C#)。 – WayneH 2010-02-02 13:34:04