ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 18.04.2025

Просмотров: 391

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Национальный исследовательский университет «Московский энергетический институт» Институт автоматики и вычислительной техники Кафедра математического моделирования

Лабораторная работа №4

«Построение транслятора»

Выполнил студент Киришко Ф.С.

вариант №8 учебной группы А-14-10.

Проверил Анатолий Васильевич Князев

Москва 2012

  1. Задание

  1. Преобразовать заданную грамматику в L-атрибутную транслирующую грамматику в форме простого присваивания.

  2. Разработать атрибутный автомат для трансляции предложений данной грамматики

  3. Разработать программу, реализующую МП-транслятор.

  4. Разработать программу-интерпретатор для данного объектного языка.

  1. Описание языка

Оператор присваивания:

<идентификатор>=<ар.выр>;

Условный оператор:

if(<лог.выр.>)then<оператор>[else<оператор>]

Оператор цикла:

while(<лог.выр.>)

<совокупность операторов>

end_while

Арифметическое выражение:

<E>::=<T><E-список>

<E-список>::=+<T><E-список>

<E-список>::=!

<T>::=<F><T-список>

<T-список>::=*<F><T-список>

<T-список>::=!

<F>::=<P>

<F>::=<R>

<P>::=<Id>

<P>::=<Int>

Логическое выражение:

<лог.выр.>::=<P><лог.опер.><P>

<лог.опер.>::= =

<лог.опер.>::= #

  1. LL-1 грамматика

  1. <S><совок.операторов>

  2. <совок.операторов><оператор><совок.операторов>

  3. <совок.операторов> !

  4. <оператор><операторприсваивания>

  5. <оператор><условныйоператор>

  6. <оператор><операторцикла>

  7. <оператор присваивания>Id= <E>;

  8. <E><T><E-список>

  9. <E-список>+<T> <E-список>

  10. <E-список>!

  11. <T><F><T-список>

  12. <T-список>* <F> <T-список>

  13. <T-список> !

  14. <F><P><F-список>

  15. <F-список>^ <P><F-список>

  16. <F-список> !

  17. <P>Id

  18. <P>Con

  19. <условный оператор>if<лог.выр.>then<оператор><else-часть>

  20. <else-часть>else<оператор>

  21. <else-часть>!

  22. <оператор цикла>for(<Id>=<E>;<лог.выр.>;<Id> = <E>) <совокупность операторов>end

  23. <лог.выр.>(<P><лог.-список>)

  24. <лог.-список>= <P>

  25. <лог.-список># <P>


  1. L – атрибутная транслирующая грамматика в форме простого присваивания для заданного языка

  1. <S><совок.операторов>

  2. <совок.операторов><оператор><совок.операторов>

  3. <совок.операторов> !

  4. <оператор><операторприсваивания>

  5. <оператор><условныйоператор>

  6. <оператор><операторцикла>

  7. <оператор присваивания>Idp1= <E>q1{Присвоитьp2,q2};

p2p1, q2q1

  1. <E>q2<T>p1<E-список>p2,q1

p2  p1, q2  q1

  1. <E-список>p1,t2 +<T>q1 {Сложитьp2,q2,r1} <E-список>r2,t1

p2  p1, q2  q1, (r1, r2) Нов, t2  t1

  1. <E-список>p1,t2!

t2  p1

  1. <T>q2<F>p1<T-список>p2,q1

p2  p1, q2  q1

  1. <T-список>p1,t2 * <F>q1 {Умножитьp2,q2,r1} <T-список>r2,t1

p2 p1, q2 q1, (r1, r2) Нов, t2 t1

  1. <T-список>p1,t2 !

t2  p1

  1. <F>q2<P>p1<F-список>p2,q1

p2  p1, q2  q1

  1. <F-список>p1,t2^ <P>q1{В степеньp2,q2,r1} <F-список>r2,t1

p2 p1, q2 q1, (r1, r2) Нов, t2 t1

  1. <F-список>p1,t2 !

t2  p1

  1. <P>pIdq

pq

  1. <P>pConq

pq

  1. <условный оператор>if<лог.выр.>p1{Переход по 0p2,z1}

then<оператор><else-часть>z2

p2p1, (z1,z2)НовМ

  1. <else-часть>z1else{Безусловный переходw1}{Меткаz2} <оператор> {Меткаw2}

z1  z2, (w1,w2)НовМ

  1. <else-часть>z1{Меткаz2}

z2z1

  1. <оператор цикла>for(<Idp1>=<Eq1>{Присвоитьp2,q2};<лог.выр.t1>;<Idr1> = <Es1>){Меткаz1} {Переход по сравнениюt2,w1} <совокупность операторов> {Присвоитьr2,s2} {Безусловный переходz2} {Меткаw2}end

p2p1,q2q1,t2t1,r2r1,s2s1, (z1,z2)НовМ, (w1,w2)НовМ

  1. <лог.выр.>t2(<P>p1<лог.-список>p2,t1)

p2p1,t2t1

  1. <лог.-список>p1,t2 =<P>q1 {Равноp2,q2,t1}


p2p1,q2q1, (t1,t2)Нов

  1. <лог.-список>p1,t2#<P>q1{Не равноp2,q2,t1}

p2  p1, q2  q1, (t1, t2) Нов

  1. Множества выбора для L-атрибутной грамматики

¶ - концевой маркер

  1. Найти аннулирующие нетерминалы и правила:

    1. Вычеркивание правил, содержащих терминальные символы:

      1. <S><совок.операторов>

      2. <совок.операторов> <оператор> <совок.операторов>

      3. <совок.операторов> !

      4. <оператор> <оператор присваивания>

      5. <оператор> <условный оператор>

      6. <оператор> <оператор цикла>

      7. <оператор присваивания> Id = <E>;

      8. <E><T><E-список>

      9. <E-список> +<T><E-список>

      10. <E-список>  !

      11. <T>  <F><T-список>

      12. <T-список> *<F><T-список>

      13. <T-список>  !

      14. <F>  <P><F-список>

      15. <F-список> ^<P><F-список>

      16. <F-список>  !

      17. <P> Id

      18. <P> Con

      19. <условный оператор> if <лог.выр.> then <оператор> <else-часть>

      20. <else-часть> else <оператор>

      21. <else-часть>!

      22. <оператор цикла> while <лог.выр.> <совок.операторов> end_while

      23. <лог.выр.> (<P> <лог.спис.>)

      24. <лог.спис.> = <P>

      25. <лог.спис.> # <P>

    2. Список аннулирующих нетерминальных грамматик:

      1. <совок.операторов>

      2. <E-список>

      3. <T-список>

      4. <F-список>

      5. <else-часть>

    3. Дополнение списка:

      1. <S>

    4. Полный список аннулирующих правил: 1,3,10,13,16,21

  2. Построение отношения Начинается-Прямо-С:


  1. Вычисление отношения Начинается-С:

  2. Вычисление множества Первдля каждого нетерминала:

Перв(<S>) = {Id, if, while}

Перв(<совок.операторов>) = { Id,if,while}

Перв(<оператор>) = { Id,if,while}

Перв(<оператор присваивания>) = {Id}

Перв(<E>) = {Con,Id}

Перв(<E-список>) = { + }

Перв(<T>) = {Con,Id}

Перв(<T-список>) = { * }

Перв(<F>) = {Con,Id}

Перв(<F-список>) = { ^ }

Перв(<P>) = {Con,Id}

Перв(<условный оператор>) = {if}

Перв(<else-часть>) = {else}

Перв(<оператор цикла>) = {while}

Перв(<лог.выр.>) = { ( }

Перв(<лог.-список>) = {=, #}

  1. Вычисление множества Первдля каждого правила:

Перв(<совок.операторов>) = { Id,if,while}

Перв(<оператор><совок.операторов>)= Перв(<оператор>) = { Id,if,while}

Перв( ! ) = { }

Перв(<оператор присваивания>) = {Id}

Перв(<условный оператор>) = {if}

Перв(<оператор цикла>) = {while}

Перв(Id= <E>;) = {Id}

Перв(<T><E-список>) = Перв(<T>) = {Con,Id}

Перв( +<T> <E-список>) = { + }

Перв( ! ) = { }

Перв(<F><T-список>) = Перв(<F>) = {Con,Id}

Перв( * <F> <T-список>) = { * }

Перв( ! ) = { }

Перв(<P><F-список>) = Перв(<P>) = {Con,Id}

Перв( ^ <P><F-список>) = { ^ }

Перв( ! ) = { }

Перв(Id) = {Id}

Перв(Con) = {Con}

Перв(if<лог.выр.>then<оператор><else-часть>) = {if}

Перв(else<оператор> ) = {else}

Перв( ! ) = { }

Перв(while<лог.выр.><совокупность операторов>end_while) = {while}

Перв( (<P><лог.-список>) ) = { ( }

Перв( =<P>) = { = }

Перв( #<P>) = { # }

  1. Построение отношения Прямо-Перед:

  1. Построение отношения Прямо-На-Конце:

  2. Вычисление отношения На-Конце:

  3. Вычисление отношения Перед= (На-Конце*Прямо-Перед) *Начинается-С.

  4. Расширение отношения Передпутем включения концевого маркера.


  1. Вычисление множества След для каждого аннулирующего нетерминала:

След(<S>) = {}

След(<совок.операторов>) = { end_while,}

След(<E-список>) = { ; }

След(<T-список>) = { + , ; }

След(<F-список>) = { *, +, ; }

След(<else-часть>) = { Id, if, while, else, end_while, }

  1. Вычисление множества Выбора:

    1. Перв(<совок.операторов>) + След(<S>) = {Id,if,while,}

    2. Перв(<оператор><совок.операторов>)= Перв(<оператор>) = { Id,if,while}

    3. Перв( ! ) + След(<совок.операторов>) = { end_while,}

    4. Перв(<оператор присваивания>) = {Id}

    5. Перв(<условный оператор>) = {if}

    6. Перв(<оператор цикла>) = {while}

    7. Перв(Id= <E>;) = {Id}

    8. Перв(<T><E-список>) = Перв(<T>) = {Con,Id}

    9. Перв( +<T> <E-список>) = { + }

    10. Перв( ! ) + След(<E-список>) = { ; }

    11. Перв(<F><T-список>) = Перв(<F>) = {Con,Id}

    12. Перв( * <F> <T-список>) = { * }

    13. Перв( ! ) + След(<T-список>) = { + , ; }

    14. Перв(<P><F-список>) = Перв(<P>) = {Con,Id}

    15. Перв( ^ <P><F-список>) = { ^ }

    16. Перв( ! ) + След(<F-список>) = { *, +, ; }

    17. Перв(Id) = {Id}

    18. Перв(Con) = {Con}

    19. Перв(if<лог.выр.>then<оператор><else-часть>) = {if}

    20. Перв(else<оператор> ) = {else}

    21. Перв( ! ) + След(<else-часть>) = { Id, if, while, else, end_while, }

    22. Перв(while<лог.выр.><совокупность операторов>end_while) = { while }

    23. Перв( (<P><лог.-список>) ) = { ( }

    24. Перв( =<P>) = { = }

    25. Перв( #<P>) = { # }

//Вообще говоря, множество выбора правил 20 и 21 пересекаются, но прога работает. =)

  1. Управляющая таблица МП-автомата транслирующей грамматики

Con

Id

if

while

else

#

=

^

*

+

;

(

)

then

end_while

<S>

#1

#1

#1

#1

<совокупность операторов>

#2

#2

#2

#3

#3

<оператор>

#4

#5

#6

<оператор присваивания>

#7

<E>

#8

#8

<E-список>

#9

#10

<T>

#11

#11

<T-список>

#12

#13

#13

<F>

#14

#14

<F-список>

#15

#16

#16

#16

<P>

#18

#17

<условный оператор>

#19

<else-часть>

#21

#21

#21

#20

#21

<оператор цикла>

#22

<логическое выражение>

#23

<логический-список>

#25

#24

=

ВС

;

ВС

)

ВС

Then

ВС

end_while

ВС

Д

{Присвоить}

Выдать (Присвоить), Вытолкнуть, Держать

{Сложить}

Выдать (Сложить), Вытолкнуть, Держать

{Умножить}

Выдать (Умножить), Вытолкнуть, Держать

{В степень}

Выдать (В степень), Вытолкнуть, Держать

{Переход по 0}

Выдать (Переход по 0), Вытолкнуть, Держать

{Безусловный переход}

Выдать (Безусловный переход), Вытолкнуть, Держать

{Метка}

Выдать (Метка), Вытолкнуть, Держать

{Переход по сравнению}

Выдать (Переход по сравнению), Вытолкнуть, Держать

{Равно}

Выдать (Равно), Вытолкнуть, Держать

{Не равно}

Выдать (Не равно), Вытолкнуть, Держать