Язык Си в примерах/Калькулятор выражений в обратной польской нотации на Bison
Материал из Викиучебника
Язык Си в примерах
- Компиляция программ
- Простейшая программа «Hello World»
- Учимся складывать
- Максимум
- Таблица умножения
- ASCII коды символов
- Верхний регистр
- Скобочки
- Факториал
- Степень числа
- Треугольник Паскаля
- Корень уравнения
- Система счисления
- Сортировка
- Библиотека complex
- Сортировка на основе qsort
- RPN калькулятор
- RPN калькулятор на Bison
- Простая грамматика
- Задача «Расчёт сопротивления схемы»
- Простая реализация конечного автомата
- Использование аргументов командной строки
- Чтение и печать без использования stdio
Содержание |
[править] Калькулятор на 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>
$

