Этот раздел описывает примеры
программ для команд  lex и yacc. Эти программы
описывают простой калькулятор, поддерживающий операции сложения, вычитания,
умножения и деления. Калькулятор также позволяет присваивать значения
переменным (обозначаемым одной строчной буквой) и затем использовать их в
вычислениях. Примеры программ lex и yacc
находятся в следующих файлах:
| Файл | Содержание | 
|---|---|
| calc.lex (Исходный текст лексического анализатора) | Файл спецификаций lex, в котором определяются правила лексического анализа. | 
| calc.yacc (Исходный текст синтаксического анализатора) | Файл грамматики yacc, который содержит правила грамматического разбора. Для ввода информации применяется функция yylex, созданная командой lex. | 
Далее везде предполагается, что программы calc.lex и calc.yacc находятся в текущем каталоге.
Для создания программы калькулятора выполните следующие действия в указанном порядке:
yacc -d calc.yacc
| y.tab.c | Исходный файл на языке C, созданный командой yacc для синтаксического анализатора. | 
| y.tab.h | Файл заголовка, содержащий определения лексем, используемых анализатором. | 
lex calc.lex
| lex.yy.c | Исходный файл на языке C, созданный командой lex для лексического анализатора. | 
cc y.tab.c lex.yy.c
| y.tab.o | Объектный файл для исходного файла y.tab.c | 
| lex.yy.o | Объектный файл для исходного файла lex.yy.c | 
| a.out | Исполняемая программа | 
$ a.out
Или переименуйте файл и запустите программу:
$ mv a.out calculate $ calculate
В любом случае, после запуска программы курсор будет помещен на строку, расположенную ниже приглашения командной строки ($). После этого вы можете работать с калькулятором, вводя числа и операторы. После нажатия клавиши Enter программа выведет результаты операции. Присвойте значение переменной:
m=4 <enter> _
Курсор переместится на следующую строку. После этого вы сможете использовать переменную в дальнейших вычислениях:
m+5 <enter> 9 _
Ниже приведен текст файла calc.yacc. В это файле находится код из всех трех разделов файла грамматики yacc: объявления, правила и программы.
%{
#include <stdio.h>
int regs[26]; int base;
%}
%start list
%token DIGIT LETTER
%left '|' %left '&' %left '+' '-' %left '*' '/' '%' %left UMINUS /* определение приоритета унарного минуса */
%% /* начало раздела правил */
list:                       /*empty */
         |
        list stat '\n'
         |
        list error '\n'
         {
           yyerrok;
         }
         ;
stat:    expr
         {
           printf("%d\n",$1);
         }
         |
         LETTER '=' expr
         {
           regs[$1] = $3;
         }
;
expr:    '(' expr ')'
         {
           $$ = $2;
         }
         |
         expr '*' expr
         {
           $$ = $1 * $3;
         }
         |
         expr '/' expr
         {
           $$ = $1 / $3;
         }
         |
         expr '%' expr
         {
           $$ = $1 % $3;
         }
         |
         expr '+' expr
         {
           $$ = $1 + $3;
         }
          |
         expr '-' expr
         {
           $$ = $1 - $3;
         }
         |
         expr '&' expr
         {
           $$ = $1 & $3;
         }
         |
         expr '|' expr
         {
           $$ = $1 | $3;
         }
         |
        '-' expr %prec UMINUS
         {
           $$ = -$2;
         }
         |
         LETTER
         {
           $$ = regs[$1];
         }
         |
         number
         ;
number:  DIGIT
         {
           $$ = $1;
           base = ($1==0) ? 8 : 10;
         }       |
         number DIGIT
         {
           $$ = base * $1 + $2;
         }
         ;
%%
main()
{
 return(yyparse());
}
yyerror(s)
char *s;
{
  fprintf(stderr, "%s\n",s);
}
yywrap()
{
  return(1);
}
Записи этого раздела выполняют следующие функции:
Раздел правил содержит правила грамматического разбора входного потока.
Раздел программ содержит
описанные ниже функции. В связи с тем, что все необходимые функции
определены в самом файле, при его обработке не требуется подключать библиотеку
yacc.
Ниже приведен текст файла calc.lex. В этом файле подключается библиотека стандартного ввода-вывода и файл y.tab.h. Программа yacc создает этот файл заголовка на основе файла грамматики yacc, если в вызове команды yacc указан флаг -d. Файл y.tab.h содержит определения лексем, используемых синтаксическим анализатором. Файл calc.lex содержит правила формирования этих лексем из входного текста.
%{
 
#include <stdio.h>
#include "y.tab.h"
int c;
extern int yylval;
%}
%%
" "       ;
[a-z]     {
            c = yytext[0];
            yylval = c - 'a';
            return(LETTER);
          }
[0-9]     {
            c = yytext[0];
            yylval = c - '0';
            return(DIGIT);
          }
[^a-z0-9\b]    {
                 c = yytext[0];
                 return(c);
               }
Глава 1, Инструменты и утилиты.
Создание языка ввода с помощью команд lex и yacc.
Работа с программами lex и yacc.
Функция printf