|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Anatoly Moskovsky 2:5020/400 19 Apr 2004 16:55:43 To : Sergey Ermakov Subject : Re: Парсинг "формулы" -------------------------------------------------------------------------------- Hi! *** Sergey Ermakov wrote: SE> SE> Подскажите, чем можно пропарсить такую конструкцию?.. SE> В общем случае может быть и такое: SE> a + b * (c + d) + (e + f) * g + h ... SE> Hо ведь есть и готовое?.. Конечно есть. Используй генератор парсеров. Hапример Parse::Yapp. Вот пример тебе для затравки: #файл t.pl use strict; use MyParser; my $p = new MyParser; my $tree = $p->parse("a + b *(c + d) + (e + f) * g + h"); $p->printpostfix($tree) if $tree; # файл MyParser.yp %{ use strict; %} %token ID INT '(' ')' %left '+' '-' %left '*' '/' %start syntax %% syntax : expr ; expr: ID { {TYPE => 'ID', VALUE => $_[1]} } | INT { {TYPE => 'INT', VALUE => $_[1]} } | expr '+' expr { {TYPE => 'BINOP', OP=>'+', L=> $_[1], R=>$_[3]}} | expr '-' expr { {TYPE => 'BINOP', OP=>'-', L=> $_[1], R=>$_[3]}} | expr '*' expr { {TYPE => 'BINOP', OP=>'*', L=> $_[1], R=>$_[3]}} | expr '/' expr { {TYPE => 'BINOP', OP=>'/', L=> $_[1], R=>$_[3]}} | '(' expr ')' { $_[2] } ; %% sub lexer { my ($me) = @_; for ($me->YYData->{INPUT}) { s/^\s+//s; #игнорируем пробелы s/^(\d+)// and return ('INT', $1); s/^([\w]+)// and return ('ID', $1); s/^([+\-*\/\)\(])// and return ($1, $1); s/^(.)// and return ('UNKNOWN', $1); } return ('', undef); #EOF } sub parse { my ($me, $syntax) = @_; $me->YYData->{INPUT} = $syntax; return $me->YYParse(yylex => \&lexer, yydebug => 0 * (0x01|0x04)); } sub printpostfix { my ($me, $tree) = @_; if ($tree->{TYPE} =~ /^ID|INT$/) { print $tree->{VALUE}; }elsif ($tree->{TYPE} eq 'BINOP') { $me->printpostfix($tree->{L}); $me->printpostfix($tree->{R}); print $tree->{OP}; }else { print "???"; } print " "; } Bye --- ifmail v.2.15dev5.3 * Origin: Alkar Teleport News Server (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/12829c49b6f6f.html, оценка из 5, голосов 10
|