Язык Си в примерах/Калькулятор выражений в обратной польской нотации на Bison

Язык Си в примерах


  1. Компиляция программ
  2. Простейшая программа «Hello World»
  3. Учимся складывать
  4. Максимум
  5. Таблица умножения
  6. ASCII-коды символов
  7. Верхний регистр
  8. Скобочки
  9. Факториал
  10. Степень числа
  11. Треугольник Паскаля
  12. Корень уравнения
  13. Система счисления
  14. Сортировка
  15. Библиотека complex
  16. Сортировка на основе qsort
  17. RPN-калькулятор
  18. RPN-калькулятор на Bison
  19. Простая грамматика
  20. Задача «Расчёт сопротивления схемы»
  21. Простая реализация конечного автомата
  22. Использование аргументов командной строки
  23. Чтение и печать без использования stdio
  24. Декодирование звукозаписи в формате ADX
  25. Другие примеры
  26. XCC C

Калькулятор на Bison

править

GNU Bison

Файл с правилами bison

править

Примечание: Пример реально удалось запустить... НО... при выполнении этого примера в VM-Linux под SuSe-11.1 относительно оригинала статьи пришлось сделать следующие изменения:

1. В данный файл описания грамматики(сразу после "#include <stdio.h>" и до "%}") пришлось добавить прототипы ф-ий "yylex", "yyerror" (определенных в «main»):

2. Вместо команды «cpp» - трансляцию-сборку всего примера пришлось выполнять при помощи команды «c++».

Файл на языке Си с функциями 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>
$