1 package Parsers::SimpleCalcParser; 2 # 3 # $RCSfile: SimpleCalcParser.yy,v $ 4 # $Date: 2015/02/28 20:50:55 $ 5 # $Revision: 1.10 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2015 Manish Sud. All rights reserved. 10 # 11 # This file is part of MayaChemTools. 12 # 13 # MayaChemTools is free software; you can redistribute it and/or modify it under 14 # the terms of the GNU Lesser General Public License as published by the Free 15 # Software Foundation; either version 3 of the License, or (at your option) any 16 # later version. 17 # 18 # MayaChemTools is distributed in the hope that it will be useful, but without 19 # any warranty; without even the implied warranty of merchantability of fitness 20 # for a particular purpose. See the GNU Lesser General Public License for more 21 # details. 22 # 23 # You should have received a copy of the GNU Lesser General Public License 24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 26 # Boston, MA, 02111-1307, USA. 27 # 28 # 29 # A WORD TO THE WISE: 30 # 31 # The parser package and token table files, SimpleCalcParser.pm and 32 # SimpleCalcParser.tab.ph, are automatically generated from parser grammar 33 # definition file, SimpleCalcParser.yy, using byacc available through perl-byacc1.8 34 # modified with perl5-byacc-patches-0.5 for generation of object oriented parser: 35 # 36 # byacc -l -P -d -b SimpleCalcParser SimpleCalcParser.yy 37 # mv SimpleCalcParser.tab.pl SimpleCalcParser.pm 38 # 39 40 use Carp; 41 42 # Setup a hash map for mapping of words/letters to values... 43 %LetterToValueMap = (); 44 45 $NUMBER=257; 46 $LETTER=258; 47 $YYERRCODE=256; 48 @yylhs = ( -1, 49 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 50 2, 2, 2, 51 ); 52 @yylen = ( 2, 53 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, 54 3, 1, 1, 55 ); 56 @yydefred = ( 1, 57 0, 0, 12, 0, 0, 0, 0, 3, 0, 13, 58 0, 2, 0, 0, 0, 0, 0, 0, 6, 0, 59 0, 0, 0, 11, 60 ); 61 @yydgoto = ( 1, 62 6, 7, 63 ); 64 @yysindex = ( 0, 65 -40, -7, 0, -57, -38, -5, -18, 0, -38, 0, 66 -31, 0, -38, -38, -38, -38, -38, -18, 0, -16, 67 -16, -30, -30, 0, 68 ); 69 @yyrindex = ( 0, 70 0, 0, 0, -9, 0, 0, -1, 0, 0, 0, 71 0, 0, 0, 0, 0, 0, 0, 3, 0, 8, 72 13, -2, 5, 0, 73 ); 74 @yygindex = ( 0, 75 0, 50, 76 ); 77 $YYTABLESIZE=220; 78 @yytable = ( 5, 79 13, 5, 8, 9, 12, 17, 17, 9, 4, 19, 80 15, 13, 5, 14, 10, 16, 0, 7, 17, 0, 81 17, 0, 8, 15, 13, 15, 14, 13, 16, 0, 82 16, 0, 13, 13, 0, 13, 0, 13, 9, 9, 83 9, 0, 9, 0, 9, 10, 10, 10, 7, 10, 84 7, 10, 7, 8, 11, 8, 0, 8, 18, 0, 85 0, 0, 20, 21, 22, 23, 24, 0, 0, 0, 86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 0, 0, 0, 0, 0, 2, 3, 4, 3, 10, 101 ); 102 @yycheck = ( 40, 103 10, 40, 10, 61, 10, 37, 37, 10, 10, 41, 104 42, 43, 10, 45, 10, 47, -1, 10, 37, -1, 105 37, -1, 10, 42, 43, 42, 45, 37, 47, -1, 106 47, -1, 42, 43, -1, 45, -1, 47, 41, 42, 107 43, -1, 45, -1, 47, 41, 42, 43, 41, 45, 108 43, 47, 45, 41, 5, 43, -1, 45, 9, -1, 109 -1, -1, 13, 14, 15, 16, 17, -1, -1, -1, 110 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 111 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 114 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 116 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 117 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 118 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 119 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 121 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 122 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 123 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124 -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, 125 ); 126 $YYFINAL=1; 127 #ifndef YYDEBUG 128 #define YYDEBUG 0 129 #endif 130 $YYMAXTOKEN=258; 131 #if YYDEBUG 132 @yyname = ( 133 "end-of-file",'','','','','','','','','',"'\\n'",'','','','','','','','','','','','','','','','','','','','', 134 '','','','','','',"'%'",'','',"'('","')'","'*'","'+'",'',"'-'",'',"'/'",'','','','','','','','','', 135 '','','','',"'='",'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', 136 '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', 137 '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', 138 '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', 139 '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','', 140 '','',"NUMBER","LETTER", 141 ); 142 @yyrule = ( 143 "\$accept : list", 144 "list :", 145 "list : list stat '\\n'", 146 "list : list error '\\n'", 147 "stat : expr", 148 "stat : LETTER '=' expr", 149 "expr : '(' expr ')'", 150 "expr : expr '+' expr", 151 "expr : expr '-' expr", 152 "expr : expr '*' expr", 153 "expr : expr '/' expr", 154 "expr : expr '%' expr", 155 "expr : NUMBER", 156 "expr : LETTER", 157 ); 158 #endif 159 160 sub yyclearin { $_[0]->{'yychar'} = -1; } 161 162 sub yyerrok { $_[0]->{'yyerrflag'} = 0; } 163 164 sub new { 165 my $p = {'yylex' => $_[1], 'yyerror' => $_[2], 'yydebug' => $_[3]}; 166 bless $p, $_[0]; 167 } 168 169 sub YYERROR { ++$_[0]->{'yynerrs'}; $_[0]->yy_err_recover; } 170 171 sub yy_err_recover { 172 # 173 # msud@san.rr.com: 174 # 175 # Turn off "exiting" warning to suppress the following warning at "next yyloop": 176 # 177 # Exiting subroutine via next at <LineNum> 178 # 179 # The code does work as expected with or without turning off the warning. 180 # This method is invoked in yyparse method directly or indirectly in another 181 # method and Perl compilers ends up finding "yyloop" as the nearst enclosure 182 # label. 183 # 184 no warnings qw(exiting); 185 186 my ($p) = @_; 187 if ($p->{'yyerrflag'} < 3) 188 { 189 $p->{'yyerrflag'} = 3; 190 while (1) 191 { 192 if (($p->{'yyn'} = $yysindex[$p->{'yyss'}->[$p->{'yyssp'}]]) && 193 ($p->{'yyn'} += $YYERRCODE) >= 0 && 194 $p->{'yyn'} < @yycheck && 195 $yycheck[$p->{'yyn'}] == $YYERRCODE) 196 { 197 warn("yydebug: state " . 198 $p->{'yyss'}->[$p->{'yyssp'}] . 199 ", error recovery shifting to state" . 200 $yytable[$p->{'yyn'}] . "\n") 201 if $p->{'yydebug'}; 202 $p->{'yyss'}->[++$p->{'yyssp'}] = 203 $p->{'yystate'} = $yytable[$p->{'yyn'}]; 204 $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yylval'}; 205 next yyloop; 206 } 207 else 208 { 209 warn("yydebug: error recovery discarding state ". 210 $p->{'yyss'}->[$p->{'yyssp'}]. "\n") 211 if $p->{'yydebug'}; 212 return(undef) if $p->{'yyssp'} <= 0; 213 --$p->{'yyssp'}; 214 --$p->{'yyvsp'}; 215 } 216 } 217 } 218 else 219 { 220 return (undef) if $p->{'yychar'} == 0; 221 if ($p->{'yydebug'}) 222 { 223 $p->{'yys'} = ''; 224 if ($p->{'yychar'} <= $YYMAXTOKEN) { $p->{'yys'} = 225 $yyname[$p->{'yychar'}]; } 226 if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; } 227 warn("yydebug: state " . $p->{'yystate'} . 228 ", error recovery discards " . 229 "token " . $p->{'yychar'} . "(" . 230 $p->{'yys'} . ")\n"); 231 } 232 $p->{'yychar'} = -1; 233 next yyloop; 234 } 235 0; 236 } # yy_err_recover 237 238 sub yyparse { 239 my ($p, $s) = @_; 240 if ($p->{'yys'} = $ENV{'YYDEBUG'}) 241 { 242 $p->{'yydebug'} = int($1) if $p->{'yys'} =~ /^(\d)/; 243 } 244 245 $p->{'yynerrs'} = 0; 246 $p->{'yyerrflag'} = 0; 247 $p->{'yychar'} = (-1); 248 249 $p->{'yyssp'} = 0; 250 $p->{'yyvsp'} = 0; 251 $p->{'yyss'}->[$p->{'yyssp'}] = $p->{'yystate'} = 0; 252 253 yyloop: while(1) 254 { 255 yyreduce: { 256 last yyreduce if ($p->{'yyn'} = $yydefred[$p->{'yystate'}]); 257 if ($p->{'yychar'} < 0) 258 { 259 if ((($p->{'yychar'}, $p->{'yylval'}) = 260 &{$p->{'yylex'}}($s)) < 0) { $p->{'yychar'} = 0; } 261 if ($p->{'yydebug'}) 262 { 263 $p->{'yys'} = ''; 264 if ($p->{'yychar'} <= $#yyname) 265 { $p->{'yys'} = $yyname[$p->{'yychar'}]; } 266 if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; }; 267 warn("yydebug: state " . $p->{'yystate'} . 268 ", reading " . $p->{'yychar'} . " (" . 269 $p->{'yys'} . ")\n"); 270 } 271 } 272 if (($p->{'yyn'} = $yysindex[$p->{'yystate'}]) && 273 ($p->{'yyn'} += $p->{'yychar'}) >= 0 && 274 $yycheck[$p->{'yyn'}] == $p->{'yychar'}) 275 { 276 warn("yydebug: state " . $p->{'yystate'} . 277 ", shifting to state " . 278 $yytable[$p->{'yyn'}] . "\n") if $p->{'yydebug'}; 279 $p->{'yyss'}->[++$p->{'yyssp'}] = $p->{'yystate'} = 280 $yytable[$p->{'yyn'}]; 281 $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yylval'}; 282 $p->{'yychar'} = (-1); 283 --$p->{'yyerrflag'} if $p->{'yyerrflag'} > 0; 284 next yyloop; 285 } 286 if (($p->{'yyn'} = $yyrindex[$p->{'yystate'}]) && 287 ($p->{'yyn'} += $p->{'yychar'}) >= 0 && 288 $yycheck[$p->{'yyn'}] == $p->{'yychar'}) 289 { 290 $p->{'yyn'} = $yytable[$p->{'yyn'}]; 291 last yyreduce; 292 } 293 if (! $p->{'yyerrflag'}) { 294 if ( (defined($EOI) && $p->{'yychar'} == $EOI) || ($p->{'yychar'} == 0) ) { 295 &{$p->{'yyerror'}}("syntax error at or near the end of input text", $s); 296 } 297 else { 298 &{$p->{'yyerror'}}("syntax error at or near input text: '$p->{'yylval'}'", $s); 299 } 300 ++$p->{'yynerrs'}; 301 } 302 return(undef) if $p->yy_err_recover; 303 } # yyreduce 304 warn("yydebug: state " . $p->{'yystate'} . 305 ", reducing by rule " . 306 $p->{'yyn'} . " (" . $yyrule[$p->{'yyn'}] . 307 ")\n") if $p->{'yydebug'}; 308 $p->{'yym'} = $yylen[$p->{'yyn'}]; 309 $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}+1-$p->{'yym'}]; 310 311 if ($p->{'yyn'} == 2) { 312 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-1]; } 313 } 314 315 if ($p->{'yyn'} == 3) { 316 { $p->yyerrok; $p->yyclearin; } 317 } 318 319 if ($p->{'yyn'} == 4) { 320 { $ExprOut = sprintf "%5i", $p->{'yyvs'}->[$p->{'yyvsp'}-0]; print "$ExprOut\n"; $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 321 } 322 323 if ($p->{'yyn'} == 5) { 324 { $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-2]} = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 325 } 326 327 if ($p->{'yyn'} == 6) { 328 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-1]; } 329 } 330 331 if ($p->{'yyn'} == 7) { 332 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] + $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 333 } 334 335 if ($p->{'yyn'} == 8) { 336 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] - $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 337 } 338 339 if ($p->{'yyn'} == 9) { 340 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] * $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 341 } 342 343 if ($p->{'yyn'} == 10) { 344 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] / $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 345 } 346 347 if ($p->{'yyn'} == 11) { 348 { $p->{'yyval'} = $p->{'yyvs'}->[$p->{'yyvsp'}-2] % $p->{'yyvs'}->[$p->{'yyvsp'}-0]; } 349 } 350 351 if ($p->{'yyn'} == 13) { 352 { 353 if (exists $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-0]}) { 354 $p->{'yyval'} = $LetterToValueMap{$p->{'yyvs'}->[$p->{'yyvsp'}-0]}; 355 } 356 else { 357 $Letter = $p->{'yyvs'}->[$p->{'yyvsp'}-0]; 358 print "Undefined variable $Letter encountered by SimpleCalcParser; Value set to 0\n"; 359 $p->{'yyval'} = 0; 360 } 361 } 362 } 363 $p->{'yyssp'} -= $p->{'yym'}; 364 $p->{'yystate'} = $p->{'yyss'}->[$p->{'yyssp'}]; 365 $p->{'yyvsp'} -= $p->{'yym'}; 366 $p->{'yym'} = $yylhs[$p->{'yyn'}]; 367 if ($p->{'yystate'} == 0 && $p->{'yym'} == 0) 368 { 369 warn("yydebug: after reduction, shifting from state 0 ", 370 "to state $YYFINAL\n") if $p->{'yydebug'}; 371 $p->{'yystate'} = $YYFINAL; 372 $p->{'yyss'}->[++$p->{'yyssp'}] = $YYFINAL; 373 $p->{'yyvs'}->[++$p->{'yyvsp'}] = $p->{'yyval'}; 374 if ($p->{'yychar'} < 0) 375 { 376 if ((($p->{'yychar'}, $p->{'yylval'}) = 377 &{$p->{'yylex'}}($s)) < 0) { $p->{'yychar'} = 0; } 378 if ($p->{'yydebug'}) 379 { 380 $p->{'yys'} = ''; 381 if ($p->{'yychar'} <= $#yyname) 382 { $p->{'yys'} = $yyname[$p->{'yychar'}]; } 383 if (!$p->{'yys'}) { $p->{'yys'} = 'illegal-symbol'; } 384 warn("yydebug: state $YYFINAL, reading " . 385 $p->{'yychar'} . " (" . $p->{'yys'} . ")\n"); 386 } 387 } 388 return ($p->{'yyvs'}->[1]) if $p->{'yychar'} == 0; 389 next yyloop; 390 } 391 if (($p->{'yyn'} = $yygindex[$p->{'yym'}]) && 392 ($p->{'yyn'} += $p->{'yystate'}) >= 0 && 393 $p->{'yyn'} <= $#yycheck && 394 $yycheck[$p->{'yyn'}] == $p->{'yystate'}) 395 { 396 $p->{'yystate'} = $yytable[$p->{'yyn'}]; 397 } else { 398 $p->{'yystate'} = $yydgoto[$p->{'yym'}]; 399 } 400 warn("yydebug: after reduction, shifting from state " . 401 $p->{'yyss'}->[$p->{'yyssp'}] . " to state " . 402 $p->{'yystate'} . "\n") if $p->{'yydebug'}; 403 $p->{'yyss'}[++$p->{'yyssp'}] = $p->{'yystate'}; 404 $p->{'yyvs'}[++$p->{'yyvsp'}] = $p->{'yyval'}; 405 } # yyloop 406 } # yyparse 407 408 409 # yyerror function supplied to parser along with a lexer during initialization of 410 # the parser... 411 # 412 413 sub yyerror { 414 my ($msg) = @_; 415 print "yyerror: $msg...\n"; 416 } 417