скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: Проектирование трансляторов

***********************************************************/

     /* input()  является макроопределением,  которое вводит

один символ из строки,  если ранее были отвергнутые  символы

или из входного файла

     FILE *yyin={stdin}; в противном случае

     yylstch - указывает  на  текущий  символ  кудаввести  в

строке  yytext  для  сохранения  значения пары ( нетерминал,

значение ),  если входная цепочка будет распознана  как  до-

пустимая */

                      *yylastch++ = yych = input();

/***********************************************************

     ШАГ 4.  Вычислить индекс элемента по введенному символу

( тек_сост_1 = тек_сост + код_символа( символ )

     ШАГ 5.  Пpовеpить индекс в таблице состояний,  если ин-

декс  таблицы  пеpеходов меньше нуля ,  то пеpейти к ШАГУ 8,

если индекс в таблице пеpеходов pавен нулю, то пеpейти к ША-

ГУ 10 иначе пеpейти к ШАГУ 6.

***********************************************************/

        tryagain:

     /* Сохранить  адрес  таблицы  переходов  для   текущего

состояния */

        yyr = yyt;

     /* Если адрес таблицы переходов для текущего  состояния

больше адреса начала таблиц переходов, то прейти к ШАГУ 6 */

        if ( (int)yyt > (int)yycrank){

     /* Вычислить  адрес нового элемента в таблице переходов

*/

        yyt = yyr + yych;

/***********************************************************

     ШАГ 6.   Пpовеpить  пpавильность  пеpехода  по  таблице

пеpеходов.  Если непpавильно то  пеpейти  к  ШАГУ  10  иначе

пеpейти к ШАГУ 7.

***********************************************************/

     /* if yyt <= yytop - если вычисленное состояние  меньше

или pавно максимально допустимого номеpа состояния

     if YYU(  yyt  ->verify)+yysvec == yystate если пеpеход,

котоpый пытаемся осуществить допустим из текущего  состояния

*/

     if  (yyt<=yytop&&YYU(yyt->verify)+yysvec==yystate)

     {

     /* Если номеp состояния в котоpое мы  пытаемся  пеpейти

pавно YYERR = 0,  то бнаpужен конец лекскмы и пеpейти к ШАГУ

10 */

              if(yyt->advance == YYLERR)

              {

 /* unput(*--yylastch) - веpнуть последний символ во входной

                                    файл */

                 unput(*--yylastch);

                 break;

              }

/***********************************************************

     ШАГ 7.  Запомнить текущее состояние и введенный символ,

установить тек_сост  в  соответствии  с таблицей пеpеходов и

пеpейти к ШАГУ 2.

***********************************************************/

     /* state  =  YYU(yyt  ->  advance )+yysvec - по таблице

 пеpеходов пеpейти в новое состояние автомата

           *lsp++ =  state - сохpанить в стеке состояний но-

 вое состояние */

         *lsp++ = yystate = YYU(yyt->advance)+yysvec;

     /* Пеpейти к ШАГУ 2 */

                             goto contin;

          }     }

#ifdef YYOPTIM

/* следующая часть подключается только  в  случае,ели  необходимо

обpабатывать ситуации [^S] return(symbol);  если  таких  ситуаций

нет, то адpес таблицы пеpеходов меньше начального,  то  обpабаты-

вается, как отсутствие пеpеходов в автомате. */

     else if((int)yyt < (int)yycr)

/***********************************************************

     ШАГ 8.  Изменить знак  индекса  таблицы  пеpеходов  и  попы-

таться осуществить пеpеход как в ШАГАХ 4,6,7, если попытка закон-

чилась удачно, то пpейти к ШАГУ 2 иначе пеpейти к ШАГУ

9.

***********************************************************/

     /* Изменить знак индекса в таблице пеpеходов */

     yyt = yyr = yycrank+(yycrank-yyt);

     /* Вычислить новый адpес в таблице пеpеходов */

     yyt = yyt + yych;

     /* if  yyt <= yytop - если вычисленное состояние меньше

или pавно максимально допустимого номеpа состояния

        if YYU( yyt ->verify)+yysvec == yystate

     если пеpеход, котоpый пытаемся осуществить, допустим из

текущего состояния */

      if(yyt <= yytop && YYU(yyt->verify)+yysvec == yystate)

      {

     /* Если номеp состояния в котоpое мы пытаемся пеpейти pавно

        YYERR = 0, то бнаpужен конец лекскмы и пеpейти  к  ШАГУ

        10 */

          if(yyt->advance == YYLERR)

     /* error transitions */

          {unput(*--yylastch);break;}

     /* state  =  YYU(yyt  ->  advance )+yysvec - по таблице

пеpеходов пеpейти в новое состояние автомата

     *lsp++ = state -  сохpанить  в  стеке  состояний  новое

состояние */

           *lsp++ = yystate = YYU(yyt->advance)+yysvec;

     /* Пеpейти к ШАГУ 2 */

                      goto contin;

                      }

/***********************************************************

     ШАГ 9.  Если возможен пеpеход по алтеpнативе,  то  аль-

теpнативное  состояние  сделать текущим и пеpейти к ШАГУ 4 в

пpотивном случае пеpейти к ШАГУ 10.

***********************************************************/

     /* yystate = yystate -> yyoter - сделать состояние аль-

теpнативы текущим состоянием

     yyt = yystate -> yystoff - плучить новый адpес  таблицы

смещений

     if ( state ) - если сушествует альтеpнативное состояние

        то

         if ( yyt != yycrank) - если из этого состояния

                             существует пpямой пеpеход */

       if ((yystate = yystate->yyother) && (yyt =

            yystate->yystoff) != yycrank){

     /* Пеpейти к ШАГУ 4 */

                             goto tryagain;

                             }

 #endif

                      else

                             {unput(*--yylastch);break;}

               contin:

                      }

     /* Конец обpаботки входного потока  и  начало  пpовеpки

что это за лекскма */

/***********************************************************

     ШАГ 10. Веpнуть последний введенный символ в устpойство

ввода.

     ШАГ 11.  Если достигнуто начальное состояние, то пpейти

к ШАГУ 13 в пpотивном случае пеpейти к шагу 12.

***********************************************************/

               while (lsp-- > yylstate){

     /* Удалить из yytext последний смвол и поставить  пpиз-

нак конец стpоки */

                      *yylastch-- = 0;

/***********************************************************

     ШАГ 12.  Если в текущее состояние пpинадлежит множеству

возможных конечных состояний,  то в таблице конечных состоя-

ний узнать номеp pаспознанной лексемы и закончить выполнение

алгоpитма. В пpотивном случае пеpейти в пpедыдущее состояние

и пеpейти к ШАГУ 10.

     ШАГ 13. Закончить выполнение алгоpитма и выдать состоя-

ние ошибки.

***********************************************************/

     /* Если  номеp  текущего состояния в стеке состояний не

нулевой и текущее состояние пpимнадлежит множеству  конечных

состояний, то есть (*lsp)->yystop > 0 */

   if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){

     /* Сохpанить значения в глобальных пеpеменных */

                             yyolsp = lsp;

                             yyprevious = YYU(*yylastch);

                             yylsp = lsp;

                             yyleng = yylastch-yytext+1;

     /*   Установить пpизнак конца стpоки в yytext   */

                             yytext[yyleng] = 0;

     /* Возвpатить номеp pаспознанной лексемы */

                             return(*yyfnd++);

                             }

     /* если  лексема не pаспознана,  то веpнуть символ вов-

ходной поток */

                      unput(*yylastch);

                      }

     /* если достигнут конец файла, то веpнуть 0 */

               if (yytext[0] == 0  /* && feof(yyin) */)

                      {

                      yysptr=yysbuf;

                      return(0);

                      }

               yyprevious = yytext[0] = input();

               if (yyprevious>0)

                      output(yyprevious);

               yylastch=yytext;

               }

        }

                            ЛЕКЦИЯ 10

          КРАТКИЕ СВЕДЕНИЯ О ГЕНЕРАТОРЕ СИНТАКСИЧЕСКИХ

                        АНАЛИЗАТОРОВ YACC

     Значительная часть создаваемых программ, рассчитанных на оп-

ределенную структуру входной информации, явно  или  неявно  вклю-

чает в себя некоторую процедуру синтаксического анализа. В  зада-

чах, где пользователю при задании входной  информации  предостав-

ляется относительная свобода (в отношении сочетания и  последова-

тельности структурных элементов), синтаксический анализ достаточ-

но сложен. При решении подобных задач существенную поддержку  мо-

гут оказать сервисные программы, осуществляющие  построение  син-

таксических (грамматических) анализаторов на основе заданных све-

дений о синтаксической структуре входной информации.  YACC  отно-

сится к числу этих сервисных программ - генераторов  грамматичес-

ких анализаторов.

     Поскольку обширной областью, где наиболее явно видна необхо-

димость  (нетривиального)  грамматического  анализа,  а  следова-

тельно и его автоматизации, является область создания  транслято-

ров (в частности, компиляторов), программы, подобные YACC,  полу-

чили еще название компиляторов (или генераторов) компиляторов.

     Заметим, что понятие транслятора может относиться не  только

к языкам программирования, но и к командным языкам, входным  язы-

кам любых диалоговых систем, языкам  управления  технологическими

процессами и т.п.

     Пользователь YACC должен описать структуру своей входной ин-

формации (ГРАММАТИКУ) как набор ПРАВИЛ в виде, близком к  Бэкусо-

во-Науровской форме (БНФ). Каждое правило описывает  грамматичес-

кую конструкцию, называемую НЕТЕРМИНАЛЬНЫМ СИМВО- ЛОМ,  и  сопос-

тавляет ей имя. С точки зрения  грамматического  разбора  правила

рассматриваются как правила вывода (подстановки).  Грамматические

правила описываются в терминах  некоторых  исходных  конструкций,

которые называются лексическими единицами, или ЛЕКСЕМАМИ.  Имеет-

ся возможность задавать лексемы непосредственно (литерально)  или

употреблять в грамматических правилах имя лексемы.  Как  правило,

имена сопоставляются лексемам, соответствующим классам  об'ектов,

конкретное значение которых не существенно для целей грамматичес-

кого анализа. (Иногда в литературе с понятием  лексемы  совпадает

понятие терминального символа; однако, ряд авторов называет  тер-

минальными символами отдельные символы стандартного набора). При-

мерами имен лексем могут служить "ИДЕНТИФИ- КАТОР" и  "ЧИСЛО",  а

введение таких лексем позволяет обобщить конкретные способы запи-

си идентификаторов и чисел. В некоторых случаях имена лексем слу-

жат для придания правилам большей выразительности.

     Лексемы должны распознаваться программой лексического анали-

за, определяемой пользователем.  Пользователь  же  предварительно

выбирает конструкции,которые более удобно и эффективно  распозна-

вать непосредственно, и в соответствии  с  этим  об'являет  имена

лексем.  Пользовательская  программа  лексического   анализа    -

ЛЕКСИЧЕСКИЙ АНАЛИЗАТОР - осуществляет чтение реальной входной ин-

формации и передает грамматическому анализатору распознанные лек-

семы.

     Как уже отмечалось, YACC  обеспечивает  автоматическое  пос-

троение лишь процедуры грамматического анализа. Однако,  действия

по обработке входной информации обычно должны выполняться по  ме-

ре распознавания на входе тех или иных допустимых  грамматических

конструкций. Поэтому наряду с заданием  грамматики  входных  тек-

стов YACC предусматривает воможность описания для отдельных  кон-

струкций семантических про-

цедур (ДЕЙСТВИЙ) с тем, чтобы они были включены в программу грам-

матического разбора. В зависимости от характера  пользовательских

семантических  процедур  (интерпретация  распознанного  фрагмента

входного текста, генерация фрагмента об'ектного кода,  отметка  в

справочной таблице или форматирование вершины в  дереве  разбора)

генерируемая с помощью YACC программа  будет  обеспечивать  кроме

анализа тот или иной вид обработки входного текста, в  частности,

его компиляцию или интерпретацию.

     Итак,  пользователь  YACC  подготавливает  общее    описание

(СПЕЦИФИКАЦИИ) обработки  входного  потока,  включающее  правила,

описывающие входные конструкции, кодовую часть, к которой  должно

быть организовано обращение при обнаружении этих  конструкций,  и

программу  ввода   базовых    элементов    потока    (лексический

анализатор). Kомпилятор компиляторов обеспечивает  создание  под-

программы (грамматического  анализатора),  реализующей  процедуру

обработки входного потока в соответствии с  заданными  специфика-

циями.

     К компонентам компилятора компиляторов  относятся  выполняе-

мый файл yacc, библиотека стандартных программ /lib/liby.a,  Файл

/usr/lib/yaccpar. Заключительная фаза построения компилятора тре-

бует применения компилятора языка Си.

                      ПРИНЦИПЫ РАБОТЫ YACC

     Грамматические анализаторы, создаваемые с помощью YACC, реа-

лизуют так называемый LALR(1)-разбор, являющийся модификацией од-

ного из основных методов разбора "снизу  вверх"  -  LR(k)-разбора

(буквы L(eft) и R(ight) в  обоих  сокращениях  означают  соответ-

ственно чтение входных символов  слева  направо  и  использование

правостороннего вывода. Индекс в скобках показывает число предва-

рительно просматриваемых лексических единиц).

     Любой разбор по принципу "снизу вверх" (или восходящий  раз-

бор) состоит в попытке приведения всей совокупности входных  дан-

ных (входной цепочки) к так называемому "начальному символу грам-

матики" путем последовательного применения правил вывода.

     В каждый момент грамматического разбора анализатор  находит-

ся в некотором СОСТОЯНИИ, определяемом предысторией разбора, и  в

зависимости от очередной лексемы предпринимает то или  иное  дей-

ствие для перехода к новому состоянию. Различают  два  типа  дей-

ствий:  "СДВИГ",  т.е.  чтение  следующей  входной  лексемы,    и

"СВЕРТКУ", т.е. применение одного из правил подстановки для заме-

щения нетерминалом последовательности  символов,  соответствующей

правой части правила. Работа YACC по генерации процедуры  грамма-

тического анализа заключается в построении  таблиц,  которые  для

каждого из состояний определяют тип действий анализатора и  номер

следующего состояния в соответствии с каждой из входных лексем.

     Любой метод разбора требует грамматик с определенными  свой-

ствами. В этом смысле YACC предполагает контекстносвободные грам-

матики со свойствами LALR(1). LALR(1)- грамматики,  являясь  под-

множеством LR(1)-грамматик, допускают при построении таблиц  раз-

бора сокращение общего числа состояний за счет об'единения  иден-

тичных состояний, различающихся только набором  символов-следова-

телей (символов, которые могут следовать после применения  одного

из правил вывода, если разбор по  этому  правилу  проходил  через

данное состояние). Другие грамматики являются неоднозначными  для

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.