Язык Си в примерах/Калькулятор выражений в обратной польской нотации на Bison: различия между версиями
Содержимое удалено Содержимое добавлено
Karagota (обсуждение | вклад) Нет описания правки |
(нет различий)
|
Версия от 20:34, 28 марта 2006
Калькулятор на Bison
Файл с правилами bison
/* file: rpn.yy title: Reverse polish notation calculator rules. */ %{ #define YYSTYPE double #include <math.h> #include <stdio.h> %} %token NUM %% /* Grammar rules and actions follow */ input: /* empty */ | input line ; line: '\n' | exp '\n' { printf ("\t%.10g\n", $1); } ; exp: NUM { $$ = $1; } | exp exp '+' { $$ = $1 + $2; } | exp exp '-' { $$ = $1 - $2; } | exp exp '*' { $$ = $1 * $2; } | exp exp '/' { $$ = $1 / $2; } /* Exponentiation */ | exp exp '^' { $$ = pow ($1, $2); } /* Unary minus */ | exp 'n' { $$ = -$1; } ; %%
Файл на языке Си с функциями main и yylex
/* file: rpn.cc title: Tokenizer functions yylex -- функция разбиения входного потока на токены. yyerror -- функция обработки ошибок main -- главная функция */ #include <stdio.h> #include <ctype.h> #include "rpn.tab.hh" int yyparse(void); int yyerror (const char *s) /* Called by yyparse on error */ { printf ("%s\n", s); } /* Lexical analyzer returns a double floating point number on the stack and the token NUM, or the ASCII character read if not a number. Skips all blanks and tabs, returns 0 for EOF. */ int yylex (void) { int c; /* skip white space */ while ((c = getchar ()) == ' ' || c == '\t') ; /* process numbers */ if (c == '.' || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval); return NUM; } /* return end-of-file */ if (c == EOF) return 0; /* return single chars */ return c; } int main (void) { return yyparse (); }
Команды компиляции
$ bison -d rpn.yy # -> produce files rpn.tab.cc and rpn.tab.hh $ gcc rpn.tab.cc rpn.cc -lm -o rpn # produce executable file rpn
Пример использования калькулятора:
$ ./rpn 1 2 + 3 1 2 3 * + 100 + 107 <Ctrl+D> $