The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

[ Содержание ] [ Предыдущая ] [ Следующая ]

Приложение A. Простой пример

    В этом примере дана полная спецификация Yacc-а для небольшого настольного калькулятора; у настольного калькулятора 26 регистров, маркированных от "a" до "z", он воспринимает арифметические выражения, составленные из операторов +, -, *, /, % (оператор mod), & (побитовый AND), | (побитовый OR) и = (присваивание). Если выражение на верхнем уровне есть присваивание, то значение не печатается; в противном случае - печатается. Как и в С, целое значение, начинающееся с 0 (нуль) считается записанным в восьмеричной системе счисления; в противном случае - в десятичной.

    В качестве примера спецификации Yacc-а, настольный калькулятор проделывает достаточную работу, показывая использование приоритетов и двусмысленностей и демонстрируя простое восстановление после ошибок. Главное упрощение в том, что фаза лексического анализа значительно проще, чем для большинства приложений, и выходные данные печатаются сразу же, строка за строкой. Заметьте, каким способом грамматическими правилами читаются десятичные и восьмеричные целые; Это, вероятно, лучше делать лексическому анализатору.

 
%{
# include 
# include 
int regs[26];
int base;
%}
%start list
%token DIGIT LETTER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
/* обеспечивает приоритет для унарного минуса */
%left UMINUS 
%% /* начало секции правил */
list : /* пусто */
 | 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; }
 ;
%% /* начало программ */
yylex()
{
/* подпрограмма лексического анализа
 возвращает LETTER для строчных букв, yylval = 0-25
 возвращает DIGIT для цифр, yylval = от 0 до 9
 все остальные символы возвращаются как есть */
 int c;
 /* пропуск пробелов */
 while( (c=getchar()) == ' ' ) { }
 /* c теперь не пробел */
 if( islower( c ) ) {
  yylval = c - 'a'; 
  return ( LETTER );
 }
 if( isdigit( c ) ) {
  yylval = c - '0'; 
  return( DIGIT );
 }
 return( c );
}

[ Содержание ] [ Предыдущая ] [ Следующая ]



c 1998-2000 SoloTony (Antonio Solo) [email protected]



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру