Parse::Yapp

『Rubyを256倍使うための本 無道編』の 13.defun/intp.y を移植

関数定義可能。変数スコープあり。コードを理解できていないので、意味(動作)から推測(IntpFrame クラスはなし) package Node; sub new { my $class = shift; bless {}, $class; } sub exec_list { my $self = shift; my ($nodes) = @_; foreach my $i (@$no…

『Rubyを256倍使うための本 無道編』の 13.defun/intp.y を移植

関数定義可能に。ただし、変数スコープなし、グローバル 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 = …

『Rubyを256倍使うための本 無道編』の 12.if_while/intp.y を移植

%{ 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…

『Rubyを256倍使うための本 無道編』の 11.op_ok/intp.y を移植

四則演算ができるように %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…

『Rubyを256倍使うための本 無道編』の 09.errmsg/intp.y を移植

%% 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 '('…

『Rubyを256倍使うための本 無道編』の 08.noarg/intp.y を移植

未知変数は引数のない関数呼び出しと解釈 %% 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], $…

『Rubyを256倍使うための本 無道編』の 07.parenomit/intp.y を移植

括弧なし関数呼び出し %% 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 '…

『Rubyを256倍使うための本 無道編』の 03.func/intp.y を移植

%% 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]]; } …

『Rubyを256倍使うための本 無道編』の 01.first/intp.y を移植

%% 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]]; } …

.output 出力 -v オプション

出力例 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…

スタンドアローン動作 -s オプション

Parse::Yapp::Driver が内蔵されるようだ

debug parameter

$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…

$parser->YYNberr()

%% 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…

$_[0]->YYLexer

マニュアルでは「($tok,$val)=&{$_[0]->Lexer}」となっていたぞ確認用コードも書いてみた。 適切な使用場面か分からないし、結果も良く分からない。 %% input: #empty | input line ; line: '\n' | 'a' '\n' { my ($tok,$val)=&{$_[0]->YYLexer}; print "$to…

$_[0]->YYErrok を呼ばないと

%% 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]->{USER}

$_[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…

$_[0]->YYSemval( index )

index が 1 以上の場合は $_[n] と同じ index が 0 以下の場合は $-n と同じようなもの。$_[0], $_[-n] とは書けない ということらしいが、どういう状況で使うのかは不明。 yacc で $-n と書けることさえ知らなかったし。 0 以上の場合を確認 %% input: #emp…

$_[0]->YYCur{tok,val}, $_[0]->YYExpect, $_[0]->YYLexer

確認用のコード %% 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 だそうな。ここらへん良く分かっていないからな〜

$_[n]

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 $…

%prec

yacc と同じように %prec が使える。実はいまいち良く分かっていなかったりするが、 既に以下で使っているので特に確認はしない。 d:id:noritsugu:20080105:parser d:id:noritsugu:20080106:parser d:id:noritsugu:20080107:parser

#empty を複数書くと

「#empty が複数ある場合はワーニング出すよ、 だって間違ってるだろ〜」ということらしい。 確認用のコード %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n' { $_[0]->YYErrok } ; exp: #empty | NUM ;…

%expect 宣言

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 '…

%union 宣言

yacc と同じように %union が書けるが無視される。 %type 宣言と違って本当に無視されているのかな? 確認用のコード %union { int ival; double dval; } %% input: #empty | input line ; line: '\n' { $_[1] } | exp '\n' { print "$_[1]\n" } | error '\n…

%type 宣言

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>…

%token 宣言

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…

%start 宣言

yacc と同じように %start が使える。トップのルールは先頭に書くので、普段使う必要がないのだけど…