Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЯП_КР_МУ1.doc
Скачиваний:
7
Добавлен:
13.09.2019
Размер:
434.69 Кб
Скачать

2 Описание транслируемого языка

За основу языка высокого уровня транслятора был взят язык программирования Pascal. Он был упрощен, а часть правил изменена или отсутствует.

Отличия заданного языка от Pascal:

  1. Необходимы разделы PROGRAM и VAR.

  2. Определены только 3 типа: INTEGER, REAL, BOOLEAN.

  3. Идентификатор может состоять из сочетания букв и цифр.

  4. Между любыми лексемами обязательно необходим пробел.

  5. Из операторов описаны: оператор присваивания ‘:=’; операторы ввода-вывода WRITELN и READLN; условный оператор IF; выражения сравнения <, >, =; логические выражения NOT, OR, AND, XOR, TRUE FALSE; циклы WHILE, FOR и REPEAT-UNTIL; составной оператор BEGIN-END.

  6. Операторы отделяются друг от друга “;”

3 Синтез транслятора

3.1 Лексический блок

Входом транслятора служит набор двоичных символов (цепочка). Лексический блок предназначен для того, чтобы разбивать цепочку символов на слова, из которых она состоит. В общем виде работа лексического блока выглядит следующим образом:

  1. Входная строка анализируется посимвольно до разделителя, которым могут быть или символ пробел, или символ конца строки.

  2. Если лексема распознана (является ключевым словом, или специальным символом), то она заносится в таблицу лексем, а иначе, мы предполагаем, что данная лексема является идентификатором.

  3. Если лексема не является идентификатором, то выдается сообщение об ошибке и работа программы прекращается.

3.2 Синтаксический блок

Этот блок переводит последовательность лексем, построенную лексическим блоком, в другую последовательность, которая более непосредственно отражает порядок, в котором должны выполняться операции в программе.

Для построения управляющей таблицы МПА необходимо нахождение множества ВЫБОР. Исходной для множества выбора является следующая грамматика:

1. [Программа] → [Заголов][ОписПер][Тело]

2. [Заголов] → program[Имя][ТочЗап]

3. [Заголов] → $

4. [Имя] → ID

5. [ТочЗап] → ;

6. [Точка] →.

7. [ОписПер] → var[СписПер][ДопОпис]

8. [ОписПер] → $

9.[СписПер] → [Перем]:[ТипПерем][ТочЗап]

10.[Перем] → [Имя][ДопПерем]

11.[ДопПерем] → $

12.[ДопПерем] →,[Имя][ДопПерем]

13.[ДопОпис] → $

14.[ДопОпис] → [Перем]:[ТипПерем][ТочЗап][ДопОпис]

15. [ТипПерем] → integer

16. [ТипПерем] → boolean

17. [ТипПерем] → real

18. [Тело] → begin[Опер-ры]end[Точка]

19. [Опер-ры] → $

20. [Опер-ры] → begin[Опер-ры]end[ТочЗап][Опер-ры]

21. [Опер-ры] → writeln[ДопWriteln][ТочЗап][Опер-ры]

22. [ДопWriteln] → [ЛевСкоб][Имя][Список][ПрСкоб]

23. [ДопWriteln] → $

24. [ЛевСкоб] → (

25. [ПрСкоб] →)

26. [Список] → $

27. [Список] →,[Имя][Список]

28. [Опер-ры] → readln[ДопReadln][ТочЗап][Опер-ры]

29. [ДопReadln] → [ЛевСкоб][Имя][Список][ПрСкоб]

30. [ДопReadln] → $

31. [Опер-ры] → for[Имя]:[Равно][Имя][TD][Имя]do[Опер-ры]

32. [TD] → to

33. [TD] → downto

34. [Опер-ры] → [Имя]:[Равно][Выражение][ТочЗап][Опер-ры]

35. [Выражение] → [Имя][ЛогВыр]

36. [Выражение] → true

37. [Выражение] → false

38. [Выражение] → not[Имя]

39. [ЛогВыр] → [ЛогОпер][Имя]

40. [ЛогВыр] → $

41. [ЛогОпер] → xor

42. [ЛогОпер] → or

43. [ЛогОпер] → and

44. [Опер-ры] → if[Условие]then[Опер-ры]

45. [Сравн] → [Равно]

46. [Сравн] → [Больше]

47. [Сравн] → [Меньше]

48. [Равно] → =

49. [Больше] → >

50. [Меньше] → <

51. [Опер-ры] → while[Условие]do[Опер-ры]

52. [Опер-ры] → repeat[Опер-ры]until[Условие][ТочЗап][Опер-ры]

53. [Условие] → [Имя][Далее]

54. [Далее] → [Сравн][Имя]

55. [Далее] → $

ШАГ 1 процедуры определяет аннулирующие нетерминалы и правила .

3. [Заголов] → $

8. [ОписПер] → $

11.[ДопПерем] → $

13.[ДопОпис] → $

18. [Опер-ры] → $

22. [ДопWriteln] → $

25. [Список] → $

29. [ДопReadln] → $

39. [ЛогВыр] → $

54. [Далее] → $

ШАГ 2 процедуры состоит в нахождении отношения, называемого НАЧИНАЕТСЯ ПРЯМО С (НПС).

Эти отношения определяются на множестве символов грамматики и означают, что если, применив к нетерминалу <A> точно одно правило и, возможно, заменив в нем некоторые аннулирующие нетерминалы на $, можно получить цепочку, начинающуюся, например с <B>. В этом случае пишут <A>НПС<B>.

На рисунке 2 показан фрагмент полученных отношений.

ШАГ 3 процедуры - это вычисление отношения НАЧИНАЕТСЯ С (НС).

В общем случае матрица отношений НС определяется рефлексивно-транзитивным замыканием матрицы НПС. Признак рефлексивности определяется тем, что любой символ всегда начинается с самого себя (1 на главной диагонали). Транзитивные отношения характеризуются всеми возможными подстановками при осуществлении вывода.

Формальный алгоритм транзитивного замыкания включает в себя следующие шаги:

  1. для каждого единичного элемента aij исходной матрицы в строку i дописать единичные элементы из строки j;

п.1 повторять сверху вниз и слева направо для всех элементов матрицы.

На рисунке 3 показан фрагмент полученного отношения.

Рисунок 2

ШАГ 4 вычисляет множество ПЕРВЫЙ.

Для каждой строки матрицы отношения НС отмеченные столбцы, соответствующие терминальным символам, указывают терминалы, составляющие множество ПЕРВЫЙ для символа, которым помечена данная строка . Так, в нашем примере:

ПЕРВЫЙ ([Программа])={ program, var, begin}

ПЕРВЫЙ ([Заголов])={ program }

ПЕРВЫЙ ([Имя])={ ID } и.т.д.

ШАГ 5 - вычисление множества ПЕРВЫЙ для правой части каждого правила. Имея информацию, полученную на шаге 4, эти вычисления проделать очень просто.

ПЕРВЫЙ (1)={ program, var, begin}

ПЕРВЫЙ (2)={ program }

ПЕРВЫЙ (3)={ID} и.т.д.

Рисунок 3

ШАГ 6 - это построение отношения, нызываемого ПРЯМО - ПЕРЕД (ПП):

Эти отношения определяются следующим образом: мы пишем А ПП В тогда и только тогда, когда существуют правила вида: <D> → <A> <B> ,

<D> → <A> β <B> , где <А>, <В> - НТ символы, β - аннулирующая цепочка.

На рисунке 4 показан фрагмент полученного отношения.

ШАГ 7 - это построение отношения ПРЯМО-НА-КОНЦЕ (ПНК).

Отношение определяется следующим образом: если <А> и <В> символы грамматики, то <А> ПНК <В> тогда и только тогда, когда есть правила вида <B> →α <A>, <B> →α <A> β, где β - аннулирующая цепочка, α - произвольная цепочка. Это отношение является инверсией отношения НПС, если правую часть правила рассматривать "справа - налево".

На рисунке 5 показан фрагмент полученного отношения.

Рисунок 4

Рисунок 5

ШАГ 8 - построение отношения НА-КОНЦЕ (НК).

Отношение НК - это рефлексивно-транзитивное замыкание отношения ПНК.

На рисунке 6 показан фрагмент полученных отношений.

Рисунок 6

ШАГ 9 - это вычисление отношения, называемого ПЕРЕД (П):

Мы пишем <А> П <В> тогда и только тогда, когда из начального символа можно вывести цепочку, в которой за вхождением <А> сразу же следует вхождение <В>. Можно записать без вывода, что отношение П является произведением отношений НК, ПП и НС. Это отношение также соответствует тем символам, которые находятся НА КОНЦЕ начального нетерминала для всех выводимых из него цепочек.

ШАГ 10 заключается в расширении отношение ПЕРЕД (П+) за счет включения в него концевого маркера (последний столбец)

Это отношение соответствует тем терминальным символам, которые находятся НА КОНЦЕ начального нетерминала для всех выводимых из него цепочек (первый столбец матрицы НК).

На рисунке 7 показан фрагмент полученных отношений для шагов 9 и 10.

Рисунок 7

ШАГ 11 - это вычисление множества СЛЕД для каждого аннулирующего нетерминала. Множество СЛЕД будет содержать все терминальные символы, для которых аннулирующие нетерминалы расположены ПЕРЕД.

ШАГ 12 - вычисление множеств ВЫБОР, которые можно получить из уже вычисленных значений множеств ПЕРВЫЙ и СЛЕД.

На рисунке 8 показан фрагмент множества ВЫБОР, из которого видно, что множества выбора правил, имеющих одинаковые левые части, не пересекаются. Грамматика, порождающая рассматриваемый язык, является LL(1)-грамматикой и для неё можно построить МП-распознаватель.

Управляющая таблица МПА представлена на рисунке 9, а правила его работы на рисунке 10.

Работа синтаксического блока:

  1. Начальное состояние магазина - нетерминал <Программа>.

  2. Автомат считывает очередную лексему и верхний символ из магазина.

  3. Автомат обращается к управляющей таблице по двум значениям и получает управляющее правило — выход таблицы.

  4. Автомат действует согласно управляющему правилу.

Рисунок 8

Рисунок 9

Рисунок 10