/* Parser for rpcalc. -*- C -*- Copyright (C) 1988-1993, 1995, 1998-2015, 2018-2021 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Reverse Polish Notation calculator. */ %{ #include #include int yylex (void); void yyerror (char const *); %} %define api.value.type {double} %token NUM %% /* Grammar rules and actions follow. */ input: %empty | input line ; line: '\n' | exp '\n' { printf ("%.10g\n", $1); } ; exp: NUM | exp exp '+' { $$ = $1 + $2; } | exp exp '-' { $$ = $1 - $2; } | exp exp '*' { $$ = $1 * $2; } | exp exp '/' { $$ = $1 / $2; } | exp exp '^' { $$ = pow ($1, $2); } /* Exponentiation */ | exp 'n' { $$ = -$1; } /* Unary minus */ ; %% /* The lexical analyzer returns a double floating point number on the stack and the token NUM, or the numeric code of the character read if not a number. It skips all blanks and tabs, and returns 0 for end-of-input. */ #include #include int yylex (void) { int c = getchar (); /* Skip white space. */ while (c == ' ' || c == '\t') c = getchar (); /* Process numbers. */ if (c == '.' || isdigit (c)) { ungetc (c, stdin); if (scanf ("%lf", &yylval) != 1) abort (); return NUM; } /* Return end-of-input. */ else if (c == EOF) return YYEOF; /* Return a single char. */ else return c; } int main (void) { return yyparse (); } #include /* Called by yyparse on error. */ void yyerror (char const *s) { fprintf (stderr, "%s\n", s); }