Parse::Yapp
関数定義可能。変数スコープあり。コードを理解できていないので、意味(動作)から推測(IntpFrame クラスはなし) package Node; sub new { my $class = shift; bless {}, $class; } sub exec_list { my $self = shift; my ($nodes) = @_; foreach my $i (@$no…
関数定義可能に。ただし、変数スコープなし、グローバル package Node; sub new { my $class = shift; bless {}, $class; } sub exec_list { my $self = shift; my ($nodes) = @_; foreach my $i (@$nodes) { $i->evaluate(); } } package RootNode; @ISA = …
%{ use Data::Dumper; package Node; sub new { my $class = shift; bless {}, $class; } sub exec_list { my $self = shift; my ($nodes) = @_; foreach my $i (@$nodes) { $i->evaluate(); } } package RootNode; @RootNode::ISA = qw(Node); sub new { my…
四則演算ができるように %left '+' '-' %left '*' '/' %left UMINUS %% program : | program stmt '\n' { $_[0]->YYData->{LINENO}++; } | program '\n' { $_[0]->YYData->{LINENO}++; } | error '\n' { $_[0]->YYErrok } ; stmt : expr | assign | IDENT re…
%% program : | program stmt '\n' { $_[0]->YYData->{LINENO}++; } | program '\n' { $_[0]->YYData->{LINENO}++; } | error '\n' { $_[0]->YYErrok } ; stmt : primary | assign | IDENT args { $_[0]->do_funcall($_[1], $_[2]); } ; funcall : IDENT '('…
未知変数は引数のない関数呼び出しと解釈 %% program : | program stmt '\n' | error '\n' { $_[0]->YYErrok } ; stmt : primary | assign | IDENT args { $_[0]->do_funcall($_[1], $_[2]); } ; funcall : IDENT '(' args ')' { $_[0]->do_funcall($_[1], $…
括弧なし関数呼び出し %% program : | program stmt '\n' | error '\n' { $_[0]->YYErrok } ; stmt : funcall | assign | IDENT args { $_[0]->do_funcall($_[1], $_[2]); } ; funcall : IDENT '(' args ')' { $_[0]->do_funcall($_[1], $_[3]); } | IDENT '…
%% program : | program stmt '\n' | error '\n' { $_[0]->YYErrok } ; stmt : funcall | assign ; funcall : IDENT '(' args ')' { $_[0]->do_funcall($_[1], $_[3]); } | IDENT '(' ')' { $_[0]->do_funcall($_[1], []); } ; args : primary { [$_[1]]; } …
%% program : | program stmt '\n' | error '\n' { $_[0]->YYErrok } ; stmt : funcall | assign ; funcall : IDENT '(' args ')' { $_[0]->do_funcall($_[1], $_[3]); } | IDENT '(' ')' { $_[0]->do_funcall($_[1], []); } ; args : primary { [$_[1]]; } …
出力例 Rules: ------ 0: $start -> input $end 1: input -> /* empty */ 2: input -> input line 3: line -> '\n' 4: line -> 'a' '\n' 5: line -> error '\n' States: ------- State 0: $start -> . input $end (Rule 0) $default reduce using rule 1 (in…
Parse::Yapp::Driver が内蔵されるようだ
$parser->YYParse() にパラメーターを渡す %% input: #empty | input line ; line: '\n' | 'a' '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; %% sub _Error { exists $_[0]->YYData->{ERRMSG} and do { print $_[0]->YYData->{ERRMSG}; dele…
%% input: #empty | input line ; line: '\n' | 'a' '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; %% sub _Error { exists $_[0]->YYData->{ERRMSG} and do { print $_[0]->YYData->{ERRMSG}; delete $_[0]->YYData->{ERRMSG}; return; }; p…
マニュアルでは「($tok,$val)=&{$_[0]->Lexer}」となっていたぞ確認用コードも書いてみた。 適切な使用場面か分からないし、結果も良く分からない。 %% input: #empty | input line ; line: '\n' | 'a' '\n' { my ($tok,$val)=&{$_[0]->YYLexer}; print "$to…
%% input: #empty | input line ; line: '\n' | 'a' '\n' { print "$_[1]\n" } | error '\n' { } ; %% sub _Error { exists $_[0]->YYData->{ERRMSG} and do { print $_[0]->YYData->{ERRMSG}; delete $_[0]->YYData->{ERRMSG}; return; }; print "Syntax er…
ルールを書かないと「{ $_[1] }」と同じ 確認用のコード %% input: #empty | input line ; line: '\n' { $_[1] } | x '\n' { print "$_[1]\n"; } | error '\n' { $_[0]->YYErrok } ; x: 'a' 'b' 'c' ; %% sub _Error { exists $_[0]->YYData->{ERRMSG} and d…
$_[0]->YYData 経由だと遅くなるらしい $_[0]->YYData を使った場合のコード %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; exp: NUM ; %% sub benchmark { my($self)=shift; fo…
index が 1 以上の場合は $_[n] と同じ index が 0 以下の場合は $-n と同じようなもの。$_[0], $_[-n] とは書けない ということらしいが、どういう状況で使うのかは不明。 yacc で $-n と書けることさえ知らなかったし。 0 以上の場合を確認 %% input: #emp…
確認用のコード %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; exp: NUM ; %% sub _Error { print "Syntax error.\n"; print "* ", $_[0]->YYCurtok, "\n"; print "* ", $_[0]->…
yacc の yyerrok は $_[0]->YYErrok yacc の YYERROR は $_[0]->YYError yacc の YYACCEPT は $_[0]->YYAccept yacc の YYABORT は $_[0]->YYAbort yacc の YYRECOVERING は $_[0]->YYRecovering だそうな。ここらへん良く分かっていないからな〜
yacc の $1 や $n は $_[1] や $_[n] なんとなくコードから予想はついていたけど、「$_[0]」 は parser object
中括弧の扱いに注意する必要があるらしい。 コメントを含め、なんとか対になるようにしないとダメらしい。 確認用のコード。その1 %% input: #empty | input line ; line: '\n' { $_[1] } | 'a' '\n' { print "{ My string block }\n"; print "\{ My other …
どうやら複数の規則は「|」でつないで書かないとダメらしいつまり以下の記述はダメ %% input: #empty | input line ; line: '\n' { $_[1] } line: exp '\n' { print "$_[1]\n" } line: error '\n' { $_[0]->YYErrok } ; exp: NUM ; %% sub _Error { exists $…
yacc と同じように %prec が使える。実はいまいち良く分かっていなかったりするが、 既に以下で使っているので特に確認はしない。 d:id:noritsugu:20080105:parser d:id:noritsugu:20080106:parser d:id:noritsugu:20080107:parser
「#empty が複数ある場合はワーニング出すよ、 だって間違ってるだろ〜」ということらしい。 確認用のコード %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; exp: #empty | NUM ;…
yacc と同じように %expect が使える。 衝突警告の出るような確認用のコード %% input: #empty | input line ; line: '\n' { $_[1] } | stmt '\n' | error '\n' { $_[0]->YYErrok } ; stmt: exp | if_stmt ; if_stmt: 'I' exp 'T' stmt | 'I' exp 'T' stmt '…
yacc と同じように %union が書けるが無視される。 %type 宣言と違って本当に無視されているのかな? 確認用のコード %union { int ival; double dval; } %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n…
yacc と同じように %type が書けるが無視される。 確認用のコード %type <hogehoge> exp %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; exp: NUM ; %% sub _Error { exists $_[0]->YYData-</hogehoge>…
yacc と同じように %token が書けるが、書く必要はない。 確認用のコード %token NUM %% input: #empty | input line ; line: '\n' { $_[1] } | NUM '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; %% sub _Error { exists $_[0]->YYData->{ER…
yacc と同じように %start が使える。トップのルールは先頭に書くので、普段使う必要がないのだけど…