RSS    

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

ASS := LE ':='E TYPE

LE := id | ^ LE

E1 := E1 MULOP T | T

E2 := E2 ADDOP E1 | E1

T  :=id | const | (E2)

E3 :=E3 COMPOP E2 | id | const

E4 :=E4 BOOLOP E3 | E3

E := E2 | E4

MULOP := '*' | '/'

ADDOP := '+' |'-'

COMPOP := '<' ;'>';'<=';'>=';'='

BOOLOP := 'AND' ;'OR'

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

писи правил КСграмматики и грамматики ван Вейнгардена.  В первой

разделителями символов и метасимволов являются пробелы, раздели-

телями альтернатив являются знаки '|'.  Терминальные символы за-

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

лы-большими.  При записи грамматик ван Вейнгардена разделителями

символов  являются  запятые,  разделителями альтернатив являются

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

представляются цепочками терминалов метаграмматики, начинающими-

ся с терминала symbol.

                            ЛЕКЦИЯ 19

               ПРИМЕР ГРАММАТИКИ ВАН ВЕЙНГААРДЕНА

   Грамматикой ван Вейнгаардена описываются конструкции присваи-

вания вида ( например , преобразование типов в языке СИ) :

   Пусть int  i,j;

         char c,ch;

т.е. описываем  переменные i и j как целые,а c и ch как символь-

ные.Необходимо отметить ,  что для построения  правильной  конс-

трукции, выражающей присвоение переменной одного вида переменной

другого вида ,  в языке СИ необходимо в правой части перед соот-

ветствующим  идентификатором нужно указать тип к которому должна

быть приведена переменная из правой части.  Разумеется, этот тип

-  тип переменной в левой части выражения .  Если же имеет место

присвоение типа (2) ,т.е.  типы переменных правой и левой частей

совпадают,то тип в правой части не указывается.

  (1) c= (char) i;

  (2) ch=c;

  (3) ch= (char) j+c;

  (4) i=(int) ch;

  (5) c= (char) 20;

   Для данных  выражений типы правых частей не везде совпадают с

типами соответствующих им левых  частей.  Необходимо  произвести

преобразование  типа  левой части к типу идентификатора в правой

части.

   assign   : е TYPE l,'=', e TYPE mod.        /*Задание

                              конструкций присваивания*/

   e TYPE l : id./*В левой  части конструкции может быть

                                  только идентификатор*/

             /*Правая часть конструции может быть предс-

               тавлена:                               */

   e TYPE mod: e TYPE r ;    /* выражением  типа  правой

                                             части-(1)*/

               TYPE nomber; /*числовым типом*/

              '(',TYPE,')',e TYPE1 r;/*конструкцией вида

               (тип)выражение_типа_отличного_от_типа_ле-

               вой_части -(4)*/

               '(',TYPE,')',TYPE1 nomber. /*конструкцией

               вида ( тип) номер,имеющий тип,отличный от

               типа левой части конструкции -(5)      */

   e TYPE r : e TYPE l,operation, e TYPE1 l;/* выражение

              в  правой  части  может  быть  представлен

              типом, аналогичным типу  левой части  (2),

              операцией - (3),выражением типа ,отличного

              от типа левой части.                    */

      TYPE  : int symbol;/* в данном  примере  могут ис-

                            пользоваться   данные  цело-

                            численного  или  символьного

              сhar symbol.  типов                     */

       Где :

            е- expression -выражение,

            TYPE- тип,

            l- left -левый,

            r- right - правый,

            mod- modern -новый(англ.),тогда

  e TYPE l -выражение, тип которого  может встретиться в

            левой части выражения,

  e TYPE r -обозначает  выражение , тип  которого  может

            встретиться  в  правой  части  ( простое ) ,

 e TYRE mod-обозначает  выражение , тип  которго  может

            встретиться в правой части  ( составное  или

            простое, т.е.,  может  быть  состоять только

            из выражения типа правой части или из приве-

            денного к  нему, или из суммы приведенной  к

            нужному  типу и типа левой части переменных.

            РАСПРЕДЕЛЕНИЕ ПАМЯТИ ВО ВРЕМЯ ТРАНСЛЯЦИИ

                           1. ДИСПЛЕЙ

               1.1 Взаимодействие Дисплея и стека

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

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

тить соответствующие адреса, где это необходимо, в таблицу симво-

лов. Фаза распределения памяти почти не зависит от языка и  маши-

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

имеющих блочную структуру и реализуемых на многих  типичных  ЭВМ.

Распределение памяти, по существу, заключается в отображении зна-

чений, появляющихся в программе, на запоминающем устройстве маши-

ны. Если допустить, что мы  реализуем  типичный  язык  с  блочной

структурой, а машина имеет линейное запоминающее  устройство,  то

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

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

типа.

     Ниже мы рассмотрим классическую структуру стека времени про-

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

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

называемой "кучей".

     В каждом компиляторе предусмотрена схема распределения памя-

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

В Фортране память, выделенная для значений  идентификаторов,  ни-

когда не освобождается, так что здесь подходящей  структурой  для

нее является одномерный массив. Если считается, что массив  имеет

левую и правую стороны, память можно выделять слево направо.  При

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

мент в массиве. Например, в результате описания

     INTEGER A,B,X,Y

     выделяется память, как показано на рис. 20.1.

     ┌───┬───┬───┬───┬───────────────

     │ A │ B │ X │ Y │

     └───┴───┴───┴───┴───────────────

                       ^

                       │

     Рис. 20.1 Схема выделения памяти в Фортране

     Такая схема не учитывает тот факт, что рабочая  память  (па-

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

весьма неэффективна (в смысле использования  объема  памяти)  для

языка с блочной структурой.

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

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

оптимальным решением было бы разрешить указателю в  вышеприведен-

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

Такой механизм распределения эквивалентен стеку  времени  прогона

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

няющимся снизу вверх.

     │   │      │   │      │   │     (1) begin real x,y

     │   │      │   │      │   │                .

     │   │      ├───┤      ├───┤                .

     │   │      │ d │      │ q │                .

     │   │      ├───┤      ├───┤     (2)     begin int c,d

     │   │      │ c │      │ p │                   .

     ├───┤      ├───┤      ├───┤                   .

     │   │      │   │      │   │             end;

     │   │      │   │      │   │     (3)     begin int p,q

     │ Y │      │ Y │      │ Y │

     ├───┤      ├───┤      ├───┤                   .

     │   │      │   │      │   │                   .

     │   │      │   │      │   │             end;

     │ X │      │ X │      │ X │                .

     └───┘      └───┘      └───┘                .

                                         end.

      (1)        (2)        (3)

     Рис. 20.2 Схема распределения памяти под переменные  в  раз-

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

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40


Новости


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

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

Пока нет

Новости в Twitter и Facebook

                   

Новости

© 2010.