Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2218 / 892 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 8:

Грамматики и YACC

Пример (продолжение)

Секция правил грамматики содержит правила для двух нетерминалов lines и expression. Правила для нетерминала lines порождают последовательность строчек входного потока, каждая из которых содержит одну формулу (нетерминал expression):

lines:   lines expression '\n' { printf ("%I \n", &2); }
        |   lines '\n'
        |   /* empty */
        ;

expression:   NUMBER_LC  { && = &1; }
                 |    '(' expression ')'          {&& = &2; }
                 |    expression '+'  expression  {&& = &1+&2; }   
                 |    expression '-'  expression  {&& = &1-&2; }
                 |    expression '*'  expression  {&& = &1*&2; }
                 |    expression '/'  expression  {&& = &1/&2; }

%%

Пример (продолжение)

Секция процедур содержит описание функций yylex, yyerror и, конечно, функции main. Хотя, как уже было сказано, эта секция может быть опущена, если все необходимые функции содержатся в некотором другом файле, который будет компилироваться отдельно.

Итак, секция процедур для нашего примера может выглядеть следующим образом. Для полноты картины описание функции yylex приводится вновь, но на этот раз без комментариев.

int yylex (void)
{
      int ch;
      /* пропускаем пробелы в начале строки */
      while ((ch = getchar ()) == ' ');
      
      if (isdigit (ch))
      {
          ungetc (ch, stdin);
          scanf ("%i", &yylval);
          return NUMBER_LC;
      }
      
      return ch;
}

yyerror (char *s)
{
      printf ("error: %s", s); 
}

main ()
{
     return yyparse ();
}

Пример (продолжение)

Для того, чтобы получить управляющую таблицу анализатора достаточно запустить программу YACC с ключом -v.

Рассмотрим фрагмент таблицы для состояния 2.

+-------------------------     STATE 2     -------------------------+
+ CONFLICTS:
+ RULES:
          lines :  lines expression^\n 
     expression :  expression^+ expression 
     expression :  expression^- expression 
     expression :  expression^* expression 
     expression :  expression^/ expression 
+ ACTIONS AND GOTOS:
              + : shift & new state 7
              - : shift & new state 8
              * : shift & new state 9
              / : shift & new state 10
             \n : shift & new state 6
                : error

В первой строке фрагмента приведено название состояния. Секция CONFLICTS перечисляет встреченные конфликты (подробнее о конфликтах - см. в "лекции 9" ). Секция RULES перечисляет все правила, задействованные в конфигурациях данного состояния (вместо символа точки, используемого в курсе, иcпользуется ^ ). Секция ACTIONS AND GOTOS представляет собой столбец управляющей таблицы анализатора, соответствующий 2-му состоянию. Подробнее о составлении управляющей таблицы можно узнать в "лекции 7" .