2016-04-04 7 views
0

と同じパターンの2の発生を検出するために、私はシンプルな文法があります(私はANTLRからPythonの出力を使用していますし、私のPythonプログラムでは、私が訪問者を使用していますANTLR:どのように別の「訪問」

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

をし、リスナーではありません)私のデータ構造を構築する。 visitConstantでは、visitRangebox()を実行すると、すべての範囲ボックスの一致(IDの前後)が返されるため、問題になります。私は別のリストにIDの前にrangeboxの一致を格納する必要があり、別のリストの後のものを格納する必要があります。 visitConstantで個別に訪問するにはどうすればよいですか?

編集:私は試すなかったことを言及するような何かを忘れた場合:

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

をしかし、私はこのエラーを取得する:

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

編集:私は当たり前(最初のチェックを追加することにより、属性のエラーを修正します!)。しかし私が今見ているのは、0または1がIDの前後に対応していないということです。これは、すべての範囲のリスト内のインデックスを意味します。 IDに遭遇する前に起こった範囲のマッチとその後のマッチを区別するにはどうすればよいですか?

答えて

1

ANTLRはそれらをすべてリストにまとめているため、一致しません。あなたができることは、レンジボックスだけを含む新しいルールを作成することです。このように:

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にあなたはラベルを付けることができていること、であるので、あなたは簡単にそれらにアクセスすることができますそれらを訪問するとき。私はあなたが文脈のリストを持っているときにうまくいくかどうか分からない。そうでない場合は、最初の解決策はまだ動作するはずです。

+0

私は以前にラベルを貼り付けてみましたが、リストのように動作しません(疑わしい)。これは、セットから正確に1つのアイテムを照合できる場合にのみ機能します。 しかし、あなたの別の名前、left_rangeとright_rangeの提案は完全に機能します!私はそれを早期に考えていましたが、2つのルールが同じものに一致するため、私にはあいまいでした。しかし、それは完全に動作します。ありがとう! – shikhanshu

関連する問題