埋め込みコードを実行したPerl正規表現を使ってネストされたタプルの抽象構文木を作成する方法を学びたいと思います。私はPerl 6文法を使って簡単にプログラムすることができます。パーシングモジュールを使うとPerl 5のタスクが単純化されることに気付いていますが、このような単純なタスクでは、モジュールなしで機械的に翻訳する方法文法の定義。私は$^Rを逆参照する方法を見つけることができなかったので、私はTUPLEルール定義の終わりに不本意なネスティングを取り消そうとしましたが、出力は間違っています。一部の部分文字列が2回表示されます。
use v5.10;
use Data::Dumper;
while (<DATA>) {
chomp;
/(?&TUPLE)(?{$a = $^R})
(?(DEFINE)
(?<TUPLE>
T \s (?&ELEM) \s (?&ELEM)
(?{ [$^R->[0][0],[$^R->[0][1],$^R[1]]] })
)
(?<ELEM>
(?: (a) (?{ [$^R,$^N] }) | \((?&TUPLE) \))
)
)/x;
say Dumper $a;
}
__DATA__
T a a
T (T a a) a
T a (T a a)
T (T a a) (T a a)
T (T (T a a) a) (T a (T a a))
予想される出力データ構造は、ネストされたリストです:使用方法を把握しようと
grammar Tuple {
token TOP { 'T ' <elem> ' ' <elem> }
token elem { 'a' | '(' <TOP> ')'}
}
class Actions {
method TOP($/) {make ($<elem>[0].made, $<elem>[1].made)}
method elem($/) {make $<TOP> ?? $<TOP>.made !! 'a'}
}
このように書くと、簡単に書くことができます。 parse_tupleでstringパラメータを参照として渡すのはなぜですか? – rubystallion
@rubystallion '\ G'アンカーが文字列値の一部である現在の' pos'のため、コピーを作成してはいけません(または、各サブに 'pos'をもう一度割り当てる必要があります)。 'parse_element()'は '$$ ref'が正しいposを持っているので、' parse_tuple() 'が終了したときにマッチを続けることに注意してください。また、大きな文書ではコピーが非効率的になります。 – amon
これは、パラメータの代わりに '$ _'を使うのが理にかなっている場所の一つだと思います。 – ikegami