Parse::RecDescent

bison マニュアルの多機能電卓

練習問題2 #!/usr/bin/env perl use strict; use Parse::RecDescent; $Parse::RecDescent::skip = '[ \t]*'; my %sym; $::sym{PI}{VARS} = 3.14159265358979; $::sym{E}{VARS} = 2.71828182845905; sub func { my($sym, $arg) = @_; if ($sym eq "sin") { re…

bison マニュアルの多機能電卓

#!/usr/bin/env perl use strict; use Parse::RecDescent; $Parse::RecDescent::skip = '[ \t]*'; my %sym; sub func { my($sym, $arg) = @_; if ($sym eq "sin") { return sin($arg); } elsif ($sym eq "cos") { return cos($arg); } elsif ($sym eq "atan"…

bison マニュアルの中間記法電卓

leftop, rightop を使ってみる #!/usr/bin/env perl use strict; use Parse::RecDescent; $Parse::RecDescent::skip = '[ \t]*'; package Parse::RecDescent; sub func_add { my(@x) = @_; my($ret) = 0; foreach (@x) { $ret += $_; } return $ret; } sub f…

bison マニュアルの中間記法電卓

整数入力のみ #!/usr/bin/env perl use strict; use Parse::RecDescent; $Parse::RecDescent::skip = '[ \t]*'; my $grammar = q{ inputs : line line : expr "\n" { print "\t$item[1]\n"; } expr : term '+' expr { $return = $item[1] + $item[3]; } | te…

行ごとの処理

良く分からなくなってきた〜(アクションのつけかたに問題???) #!/usr/bin/env perl use strict; use Parse::RecDescent; #$Parse::RecDescent::skip = '[ \t]+'; my $grammar = q{ inputs : line line : /\w+/ "\n" { print "*$item[1]*\n"; } }; my $par…

失敗したかどうかの間違ったテスト方法

まんま #!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : foo(s) eofile foo : 'a' | 'b' | <error> eofile : /^\Z/ }; my $parse = new Parse::RecDescent ($grammar); while (<>) { # defined $parse->inputs($_) or print "Ba</error>…

常にパースを失敗させるエラーの予測

ほぼ、まんま。意図通りにエラーとならない例 #!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : foo(s) { print "*foo*\n"; } foo : 'a' | 'b' | <error> }; my $parse = new Parse::RecDescent ($grammar); while (<>) { define</error>…

プリコンパイルされたパーサの呼び出し

inputs : 'a' { print "*a*\n"; }という中身のファイル 20080913_recdescent00.grammar で、 $ perl -MParse::RecDescent - 20080913_recdescent00.grammar m20080913_Grammar#!/usr/bin/env perl use strict; use m20080913_Grammar; my $parse = m20080913…

パーサのプリコンパイル

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' { print "*a*"; } }; Parse::RecDescent->Precompile($grammar, "20080912_PreGrammar"); で、20080912_PreGrammar.pm が生成される inputs : 'a' { print "*a*"; }…

値の保存

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : /\w/ { print "last: $thisparser->{local}{last}\n"; $thisparser->{local}{last} = $item[1]; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defi…

増加解析、実行中のパーサのアクション内での呼び出し

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' abc /\w/ { $thisparser->Extend("abc : '$item[3]'"); } abc : 'a' }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) o…

増加解析、Replace メソッド

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : ('a' | 'b' | 'c') { print "*$item[1]*\n"; } }; my $parse = new Parse::RecDescent ($grammar); $parse->Replace("inputs : 'd'\ninputs : 'e'"); while (<>) { defin…

増加解析、Extend メソッド

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' | 'b' | 'c' { print "*$item[1]*\n"; } }; my $parse = new Parse::RecDescent ($grammar); $parse->Extend("inputs : 'd'\ninputs : 'e'"); while (<>) { defined …

オルタネーションと反復指定子

#!/usr/bin/env perl use strict; use Parse::RecDescent; use Data::Dumper; my $grammar = q{ inputs : (a | b | c)(?) { print Data::Dumper::Dumper($item[1]); } a : 'a' b : 'b' c : 'c' }; my $parse = new Parse::RecDescent ($grammar); while (<>)…

オルタネーション

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : (a | 'b' | /\d+/) { print "$item[1]\n"; } a : 'a' b : 'b' }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) or print "B…

オルタネーション

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : (a | b | c) { print "$item[1]\n"; } a : 'a' b : 'b' c : 'c' }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) or print …

サブ規則の引数リストは開始規則が呼び出されるときに使う引数リストでも渡せる

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' { print "$arg[0] $arg[1]\n"; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_, 1, "foo", 2) or print "Bad text!\n…

サブ規則の引数リストは遅延バインディング

まんま #!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ { $::species = 'dogs' } inputs : pair { print "match!\n"; } pair : 'two' animal[$::species](s) animal : /$arg[0]/ { $::species = 'cats' } }; my $parse = new Par…

サブ規則の引数リストが反復サブ規則と一緒に使われるとき

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : /some|many/ thing[ $item[1] ](s) thing : 'a' { print "$arg[0]\n"; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) o…

サブ規則の引数リスト ハッシュ形式も書ける

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : keyword rule[keyword => $item[1], 'foo' => $item[2], baz => 3] keyword : 'class' | 'def' rule : 'a' { print "$arg{keyword}|$arg{foo}|$arg{'baz'}\n"; } }; my $…

サブ規則の引数リスト 複数渡せる

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : rule['foo', 'bar', 'baz'] rule : 'a' { print "$arg[0] $arg[1] $arg[2]\n"; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inpu…

サブ規則の引数リスト

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : rule['foo'] rule : 'a' { print "$arg[0]\n"; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) or print "Bad text!\n";…

ディレクティブ nocheck

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : rule rule : subrule(s) subrule }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inputs($_) or print "Bad text!\n"; } で、 Warning…

ディレクティブ score、もう一つの例

まんま #!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : line line : seplist[sep=>','] <score: -@{$item[1]}> { print "*,*\n"; } | seplist[sep=>':'] <score: -@{$item[1]}> { print "*:*\n"; } | seplist[sep=>" "] <score: -@{$item[1]}> { print "* *\n"; } seplist: <skip:""> </skip:""></score:></score:></score:>

ディレクティブ autoscore

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : <autoscore: 1> | 'a' { print "*a1 $score $score_return*\n"; } | 'a' { print "*a2 $score $score_return*\n"; } | 'a' { print "*a3 $score $score_return*\n"; } }; my $parse = n</autoscore:>…

ディレクティブ score、変数 $score, $score_return

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' { print "*a1 $score $score_return*\n"; } <score: 1> | 'a' { print "*a2 $score $score_return*\n"; } <score: 2> | 'a' { print "*a3 $score $score_return*\n"; } <score: 3> }; my $parse = n</score:></score:></score:>…

ディレクティブ score

#!/usr/bin/env perl use strict; use Parse::RecDescent; my $grammar = q{ inputs : 'a' { print "*a1*\n"; } | 'a' { print "*a2*\n"; } | 'a' { print "*a3*\n"; } }; my $parse = new Parse::RecDescent ($grammar); while (<>) { defined $parse->inpu…

leftop を使わない方法?

#!/usr/bin/env perl use strict; use Parse::RecDescent; use Data::Dumper; my $grammar = q{ inputs : list { print Data::Dumper::Dumper($item[1]); } list : '(' list_item(s /,/) ')' { $return = $item[2] } list_item : /\w/ }; my $parse = new Pa…

ディレクティブ leftop のリスト表現で空リストを扱う

#!/usr/bin/env perl use strict; use Parse::RecDescent; use Data::Dumper; my $grammar = q{ inputs : list { print Data::Dumper::Dumper($item[1]); } list : '(' <leftop: list_item /(,|=>)/ list_item>(?) ')' { $return = $item[2] } list_item : /\w/ }; my $parse = new Pa</leftop:>…

ディレクティブ leftop, rightop で演算子も返したい

サブ規則か正規表現の括弧を使用まんま #!/usr/bin/env perl use strict; use Parse::RecDescent; use Data::Dumper; my $grammar = q{ inputs : list { print Data::Dumper::Dumper($item[1]); } list : '(' <leftop: list_item separator list_item> ')' { $return = $item[2] } list_item : /\w/ </leftop:>…