Mercurial > repos > deepakjadmin > r_caret_test
diff mayachemtool/mayachemtools/lib/Parsers/SimpleCalcParser.pm @ 0:68300206e90d draft default tip
Uploaded
author | deepakjadmin |
---|---|
date | Thu, 05 Nov 2015 02:41:30 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mayachemtool/mayachemtools/lib/Parsers/SimpleCalcParser.pm Thu Nov 05 02:41:30 2015 -0500 @@ -0,0 +1,561 @@ +package Parsers::SimpleCalcParser; +# +# $RCSfile: SimpleCalcParser.yy,v $ +# $Date: 2015/02/28 20:50:55 $ +# $Revision: 1.10 $ +# +# Author: Manish Sud <msud@san.rr.com> +# +# Copyright (C) 2015 Manish Sud. All rights reserved. +# +# This file is part of MayaChemTools. +# +# MayaChemTools is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. +# +# MayaChemTools is distributed in the hope that it will be useful, but without +# any warranty; without even the implied warranty of merchantability of fitness +# for a particular purpose. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or +# write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, +# Boston, MA, 02111-1307, USA. +# +# +# A WORD TO THE WISE: +# +# The parser package and token table files, SimpleCalcParser.pm and +# SimpleCalcParser.tab.ph, are automatically generated from parser grammar +# definition file, SimpleCalcParser.yy, using byacc available through perl-byacc1.8 +# modified with perl5-byacc-patches-0.5 for generation of object oriented parser: +# +# byacc -l -P -d -b SimpleCalcParser SimpleCalcParser.yy +# mv SimpleCalcParser.tab.pl SimpleCalcParser.pm +# + +use Carp; + +# Setup a hash map for mapping of words/letters to values... +%LetterToValueMap = (); + +$NUMBER=257; +$LETTER=258; +$YYERRCODE=256; +@yylhs = ( -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, +); +@yylen = ( 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 1, 1, +); +@yydefred = ( 1, + 0, 0, 12, 0, 0, 0, 0, 3, 0, 13, + 0, 2, 0, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 11, +); +@yydgoto = ( 1, + 6, 7, +); +@yysindex = ( 0, + -40, -7, 0, -57, -38, -5, -18, 0, -38, 0, + -31, 0, -38, -38, -38, -38, -38, -18, 0, -16, + -16, -30, -30, 0, +); +@yyrindex = ( 0, + 0, 0, 0, -9, 0, 0, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 8, + 13, -2, 5, 0, +); +@yygindex = ( 0, + 0, 50, +); +$YYTABLESIZE=220; +@yytable = ( 5, + 13, 5, 8, 9, 12, 17, 17, 9, 4, 19, + 15, 13, 5, 14, 10, 16, 0, 7, 17, 0, + 17, 0, 8, 15, 13, 15, 14, 13, 16, 0, + 16, 0, 13, 13, 0, 13, 0, 13, 9, 9, + 9, 0, 9, 0, 9, 10, 10, 10, 7, 10, + 7, 10, 7, 8, 11, 8, 0, 8, 18, 0, + 0, 0, 20, 21, 22, 23, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 3, 10, +); +@yycheck = ( 40, + 10, 40, 10, 61, 10, 37, 37, 10, 10, 41, + 42, 43, 10, 45, 10, 47, -1, 10, 37, -1, + 37, -1, 10, 42, 43, 42, 45, 37, 47, -1, + 47, -1, 42, 43, -1, 45, -1, 47, 41, 42, + 43, -1, 45, -1, 47, 41, 42, 43, 41, 45, + 43, 47, 45, 41, 5, 43, -1, 45, 9, -1, + -1, -1, 13, 14, 15, 16, 17, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, +); +$YYFINAL=1; +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +$YYMAXTOKEN=258; +#if YYDEBUG +@yyname = ( +"end-of-file",'','','','','','','','','',"'\\n'",'','','','','','','','','','','','','','','','','','','','', +'','','','','','',"'%'",'','',"'('","')'","'*'","'+'",'',"'-'",'',"'/'",'','','','','','','','','', +'','','','',"'='",'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', +'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', +'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', +'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', +'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', +'','',"NUMBER","LETTER", +); +@yyrule = ( +"\$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : NUMBER", +"expr : LETTER", +); +#endif + +sub yyclearin { $_[0]->{'yychar'} = -1; } + +sub yyerrok { $_[0]->{'yyerrflag'} = 0; } + +sub new { + my $p = {'yylex' => $_[1], 'yyerror' => $_[2], 'yydebug' => $_[3]}; + bless $p, $_[0]; +} + +sub YYERROR { ++$_[0]->{'yynerrs'}; $_[0]->yy_err_recover; } + +sub yy_err_recover { + # + # msud@san.rr.com: + # + # Turn off "exiting" warning to suppress the following warning at "next yyloop": + # + # Exiting subroutine via next at <LineNum> + # + # The code does work as expected with or without turning off the warning. + # This method is invoked in yyparse method directly or indirectly in another + # method and Perl compilers ends up finding "yyloop" as the nearst enclosure + # label. + # + no warnings qw(exiting); + + my ($p) = @_; + if ($p->{'yyerrflag'} < 3) + { + $p->{'yyerrflag'} = 3; + while (1) + { + if (($p->{'yyn'} = $yysindex[$p->{'yyss'}->[$p->{'yyssp'}]]) && + ($p->{'yyn'} += $YYERRCODE) >= 0 && + $p->{'yyn'} < @yycheck && + $yycheck[$p->{'yyn'}] == $YYERRCODE) + { + warn("yydebug: state " . + $p->{'yyss'}->[$p->{'yyssp'}] . + ", error recovery shifting to state" . + $yytable[$p->{'yyn'}] . "\n") + if $p->{'yydebug'}; + $p->{'yyss'}->[++$p->{'yyssp'}] = + $p->{'yystate'} = $yytable[$p->{'yyn'}]; + $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yylval'}; + next yyloop; + } + else + { + warn("yydebug: error recovery discarding state ". + $p->{'yyss'}->[$p->{'yyssp'}]. "\n") + if $p->{'yydebug'}; + return(undef) if $p->{'yyssp'} <= 0; + --$p->{'yyssp'}; + --$p->{'yyvsp'}; + } + } + } + else + { + return (undef) if $p->{'yychar'} == 0; + if ($p->{'yydebug'}) + { + $p->{'yys'} = ''; + if ($p->{'yychar'} <= $YYMAXTOKEN) { $p->{'yys'} = + $yyname[$p->{'yychar'}]; } + if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; } + warn("yydebug: state " . $p->{'yystate'} . + ", error recovery discards " . + "token " . $p->{'yychar'} . "(" . + $p->{'yys'} . ")\n"); + } + $p->{'yychar'} = -1; + next yyloop; + } +0; +} # yy_err_recover + +sub yyparse { + my ($p, $s) = @_; + if ($p->{'yys'} = $ENV{'YYDEBUG'}) + { + $p->{'yydebug'} = int($1) if $p->{'yys'} =~ /^(\d)/; + } + + $p->{'yynerrs'} = 0; + $p->{'yyerrflag'} = 0; + $p->{'yychar'} = (-1); + + $p->{'yyssp'} = 0; + $p->{'yyvsp'} = 0; + $p->{'yyss'}->[$p->{'yyssp'}] = $p->{'yystate'} = 0; + + yyloop: while(1) + { + yyreduce: { + last yyreduce if ($p->{'yyn'} = $yydefred[$p->{'yystate'}]); + if ($p->{'yychar'} < 0) + { + if ((($p->{'yychar'}, $p->{'yylval'}) = + &{$p->{'yylex'}}($s)) < 0) { $p->{'yychar'} = 0; } + if ($p->{'yydebug'}) + { + $p->{'yys'} = ''; + if ($p->{'yychar'} <= $#yyname) + { $p->{'yys'} = $yyname[$p->{'yychar'}]; } + if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; }; + warn("yydebug: state " . $p->{'yystate'} . + ", reading " . $p->{'yychar'} . " (" . + $p->{'yys'} . ")\n"); + } + } + if (($p->{'yyn'} = $yysindex[$p->{'yystate'}]) && + ($p->{'yyn'} += $p->{'yychar'}) >= 0 && + $yycheck[$p->{'yyn'}] == $p->{'yychar'}) + { + warn("yydebug: state " . $p->{'yystate'} . + ", shifting to state " . + $yytable[$p->{'yyn'}] . "\n") if $p->{'yydebug'}; + $p->{'yyss'}->[++$p->{'yyssp'}] = $p->{'yystate'} = + $yytable[$p->{'yyn'}]; + $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yylval'}; + $p->{'yychar'} = (-1); + --$p->{'yyerrflag'} if $p->{'yyerrflag'} > 0; + next yyloop; + } + if (($p->{'yyn'} = $yyrindex[$p->{'yystate'}]) && + ($p->{'yyn'} += $p->{'yychar'}) >= 0 && + $yycheck[$p->{'yyn'}] == $p->{'yychar'}) + { + $p->{'yyn'} = $yytable[$p->{'yyn'}]; + last yyreduce; + } + if (! $p->{'yyerrflag'}) { + if ( (defined($EOI) && $p->{'yychar'} == $EOI) || ($p->{'yychar'} == 0) ) { + &{$p->{'yyerror'}}("syntax error at or near the end of input text", $s); + } + else { + &{$p->{'yyerror'}}("syntax error at or near input text: '$p->{'yylval'}'", $s); + } + ++$p->{'yynerrs'}; + } + return(undef) if $p->yy_err_recover; + } # yyreduce + warn("yydebug: state " . $p->{'yystate'} . + ", reducing by rule " . + $p->{'yyn'} . " (" . $yyrule[$p->{'yyn'}] . + ")\n") if $p->{'yydebug'}; + $p->{'yym'} = $yylen[$p->{'yyn'}]; + $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}+1-$p->{'yym'}]; + + if ($p->{'yyn'} == 2) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-1]; } + } + + if ($p->{'yyn'} == 3) { + { $p->yyerrok; $p->yyclearin; } + } + + if ($p->{'yyn'} == 4) { + { $ExprOut = sprintf "%5i", $p->{'yyvs'}->[$p->{'yyvsp'}-0]; print "$ExprOut\n"; $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 5) { + { $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-2]} = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 6) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-1]; } + } + + if ($p->{'yyn'} == 7) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] + $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 8) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] - $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 9) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] * $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 10) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] / $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 11) { + { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] % $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } + } + + if ($p->{'yyn'} == 13) { + { + if (exists $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-0]}) { + $p->{'yyval'} = $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-0]}; + } + else { + $Letter = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; + print "Undefined variable $Letter encountered by SimpleCalcParser; Value set to 0\n"; + $p->{'yyval'} = 0; + } + } + } + $p->{'yyssp'} -= $p->{'yym'}; + $p->{'yystate'} = $p->{'yyss'}->[$p->{'yyssp'}]; + $p->{'yyvsp'} -= $p->{'yym'}; + $p->{'yym'} = $yylhs[$p->{'yyn'}]; + if ($p->{'yystate'} == 0 && $p->{'yym'} == 0) + { + warn("yydebug: after reduction, shifting from state 0 ", + "to state $YYFINAL\n") if $p->{'yydebug'}; + $p->{'yystate'} = $YYFINAL; + $p->{'yyss'}->[++$p->{'yyssp'}] = $YYFINAL; + $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yyval'}; + if ($p->{'yychar'} < 0) + { + if ((($p->{'yychar'}, $p->{'yylval'}) = + &{$p->{'yylex'}}($s)) < 0) { $p->{'yychar'} = 0; } + if ($p->{'yydebug'}) + { + $p->{'yys'} = ''; + if ($p->{'yychar'} <= $#yyname) + { $p->{'yys'} = $yyname[$p->{'yychar'}]; } + if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; } + warn("yydebug: state $YYFINAL, reading " . + $p->{'yychar'} . " (" . $p->{'yys'} . ")\n"); + } + } + return ($p->{'yyvs'}->[1]) if $p->{'yychar'} == 0; + next yyloop; + } + if (($p->{'yyn'} = $yygindex[$p->{'yym'}]) && + ($p->{'yyn'} += $p->{'yystate'}) >= 0 && + $p->{'yyn'} <= $#yycheck && + $yycheck[$p->{'yyn'}] == $p->{'yystate'}) + { + $p->{'yystate'} = $yytable[$p->{'yyn'}]; + } else { + $p->{'yystate'} = $yydgoto[$p->{'yym'}]; + } + warn("yydebug: after reduction, shifting from state " . + $p->{'yyss'}->[$p->{'yyssp'}] . " to state " . + $p->{'yystate'} . "\n") if $p->{'yydebug'}; + $p->{'yyss'}[++$p->{'yyssp'}] = $p->{'yystate'}; + $p->{'yyvs'}[++$p->{'yyvsp'}] = $p->{'yyval'}; + } # yyloop +} # yyparse + + +# yyerror function supplied to parser along with a lexer during initialization of +# the parser... +# + +sub yyerror { + my ($msg) = @_; + print "yyerror: $msg...\n"; +} + +1; + +__END__ + +=head1 NAME + +Parsers::SimpleCalcParser + +=head1 SYNOPSIS + +use Parsers::SimpleCalcParser ; + +use Parsers::SimpleCalcParser qw(:all); + +=head1 DESCRIPTION + +B<Parsers::SimpleCalcParser> class provides the following methods: + +new, yyclearin, yyerrok, yyerror, yyparse + +B<Parsers::SimpleCalcParse.yy> parser grammer definition file implements a simple +calculator and is provided to highlight usage of lexer capability available through +B<Parsers::SimpleCalcYYLexer>, which in turn uses B<Parsers::YYLexer> and +B<Parsers::Lexer> classes to procide underlying lexer functionality. + +The parser package and token table files, B<Parsers::SimpleCalcParser.pm> and +B<SimpleCalcParser.tab.ph>, are automatically generated from parser grammar definition +file, B<Parsers::SimpleCalcParser.yy>, using byacc available through perl-byacc1.8 modified +with perl5-byacc-patches-0.5 for generation of object oriented parser: + + byacc -l -P -d -b SimpleCalcParser SimpleCalcParser.yy + mv SimpleCalcParser.tab.pl SimpleCalcParser.pm + +=head2 METHODS + +=over 4 + +=item B<new> + + $SimpleCalcParser = new Parsers::SimpleCalcParser($YYLex, + \&Parsers::SimpleCalcParser::yyerror); + $SimpleCalcParser = new Parsers::SimpleCalcParser($YYLex, + \&Parsers::SimpleCalcParser::yyerror, $Debug); + +Using specified I<YYLex> I<YYError> functions, B<new> method generates a new +B<SimpleCalcParser> and returns a reference to newly created B<SimpleCalcYYParser> object. + +Examples: + + # Input string... + $InputText = "3 + 4 +6\nx=3\ny=5\nx+y\nx+z\n"; + $YYLexer = new Parsers::SimpleCalcYYLexer($InputText); + $YYLex = $YYLexer->GetYYLex(); + + $Debug = 0; + $SimpleCalcParser = new Parsers::SimpleCalcParser($YYLex, + \&Parsers::SimpleCalcParser::yyerror, $Debug); + $Value = $SimpleCalcParser->yyparse(); + print "Value = " . (defined($Value) ? "$Value" : "Undefined") . "\n"; + + # Input file... + $InputFile = "TestSimpleCalcParser.txt"; + open INPUTFILE, "$InputFile" or die "Couldn't open $InputFile: $!\n"; + + $YYLexer = new Parsers::SimpleCalcYYLexer(\*INPUTFILE); + $YYLex = $YYLexer->GetYYLex(); + + $Debug = 0; + $SimpleCalcParser = new Parsers::SimpleCalcParser($YYLex, + \&Parsers::SimpleCalcParser::yyerror, $Debug); + $Value = $SimpleCalcParser->yyparse(); + print "Value = " . (defined($Value) ? "$Value" : "Undefined") . "\n"; + + close INPUTFILE; + + # Input iterator... + $InputFile = "TestSimpleCalcParser.txt"; + open INPUTFILE, "$InputFile" or die "Couldn't open $InputFile: $!\n"; + $InputIterator = sub { return <INPUTFILE>; }; + + $YYLexer = new Parsers::SimpleCalcYYLexer($InputIterator); + $YYLex = $YYLexer->GetYYLex(); + + $Debug = 0; + $SimpleCalcParser = new Parsers::SimpleCalcParser($YYLex, + \&Parsers::SimpleCalcParser::yyerror, $Debug); + $Value = $SimpleCalcParser->yyparse(); + print "Value = " . (defined($Value) ? "$Value" : "Undefined") . "\n"; + + close INPUTFILE; + +=item B<yyclearin> + + $SimpleCalcParser->yyclearin(); + +B<yyclearin> method clears any previous look-ahead token after encountering a syntax error +during parsing. It can be used after B<yyerrok> in a grammer rule with the reserved word +B<error>. + +=item B<yyerrok> + + $SimpleCalcParser->yyerrok(); + +B<yyerrok> method is used with the reserved word B<error> in grammer rule to indcate +error recovery is complete after encountering a syntax error during parsing. + +=item B<yyerror> + + $SimpleCalcParser->yyerror(); + +B<yyerror> function is provided for the caller to use during initialization of a parser. It +is used by B<yyparse> to print any error messages encountered during parsing of the +input. + +=item B<yyparse> + + $Value = $SimpleCalcParser->yyparse(); + +Returns I<Value> after parsing all the input from a input stream using specified +grammer rules. + +=back + +=head1 AUTHOR + +Manish Sud <msud@san.rr.com> + +=head1 SEE ALSO + +Lexer.pm, YYLexer.pm, SimpleCalcYYLexer.pm + +=head1 COPYRIGHT + +Copyright (C) 2015 Manish Sud. All rights reserved. + +This file is part of MayaChemTools. + +MayaChemTools is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 3 of the License, or (at your option) +any later version. + +=cut +