Реализация интерпретатора модифицированной грамматики учебного языка Milan
Заказать уникальную курсовую работу- 38 38 страниц
- 4 + 4 источника
- Добавлена 21.02.2021
- Содержание
- Часть работы
- Список литературы
- Вопросы/Ответы
Лист
1 ПОСТАНОВКА ЗАДАЧИ 4
2 ОПИСАНИЕ ЯЗЫКА MILAN 5
3 ГРАММАТИКА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN 7
4 ОПИСАНИЕ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN 8
4.1 Лексемы языка MILAN 8
4.2 Синтаксическая диаграмма лексического анализатора 9
4.3 Расстановка ссылок передачи управления 11
5 ОПИСАНИЕ ИНТЕРПРЕТАТОРА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN 15
6 ПРОГРАММНАЯ РЕАЛИЗАЦИЯ ИНТЕРПРЕТАТОРА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN (С КОММЕНТАРИЯМИ) 20
6.1 Описание переменных класса интерпретатора 20
6.2 Конструктор класса интерпретатора 20
6.3 Метод расстановки ссылок 21
6.4 Метод выполнения лексического анализа 23
6.5 Метод обработки преддекремента 25
6.6 Метод обработки постдекремента 25
6.7 Метод обработки конструкции «множитель» 26
6.8 Метод обработки конструкции «оператор» 26
6.9 Метод обработки конструкции «содержимое» 31
7 ТЕСТИРОВАНИЕ ИНТЕРПРЕТАТОРА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN 34
7.1 Тестовые примеры без ошибок 34
7.2 Тестовые примеры c ошибками 36
ЗАКЛЮЧЕНИЕ 38
СПИСОК ЛИТЕРАТУРЫ 39
Code == _CASE_)
/* y4: чтение следующей лексемы */
Number_Lexem++;
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
if (Tab_Lexems[Number_Lexem].Code == _CONSTANT_){
/* y22: прочитать (без удаления) вершину стека StekCaseValue в переменную Ai (StekCaseValue -> Ai); значение прочитанной константы занести в Bi; сравнить Ai и Bi: Ai==Bi – движение по TRUE, иначе по FALSE;*/
Ai=StekCaseValue.Peek();
Bi=Tab_Constants[Tab_Lexems[Number_Lexem].Value];
/* y4: чтение следующей лексемы */
Number_Lexem++;
if(Ai==Bi) {//обработка TRUE для ветки CASE
/* y23: снять вершину стека StekDefaultValue в переменную Ai (StekDefaultValue -> Ai); отправить значение 0 в стек StekDefaultValue (0 -> StekDefaultValue) */
Ai=StekDefaultValue.Pop();
StekDefaultValue.Push(0);
if (Tab_Lexems[Number_Lexem].Code == _COLON_)
/* y4: чтение следующей лексемы */
Number_Lexem++;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
/* <последовательность операторов> после : */
ProcedureL();
if (Code_Error != -1) return;
}
else { //обработка FALSE для ветки CASE
if (Tab_Lexems[Number_Lexem].Code == _COLON_){
/* y24: снять значение текущей лексемы в переменную Ai (Tab_Lexems[Number_Lexem].Value -> Ai); номеру текущей лексемы присвоить значение Ai */
Ai = Tab_Lexems[Number_Lexem].Value;
Number_Lexem = Ai;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
}
/* Обработка конструкции <содержимое> после : */
ProcedureZ();
if (Code_Error != -1) return;
if (Tab_Lexems[Number_Lexem].Code == _RBRACE_){
/* y26: снять вершину стека StekCaseValue в перменную Ai (StekCaseValue -> Ai); */
Ai = StekCaseValue.Pop();
/* y4: чтение следующей лексемы */
Number_Lexem++;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
break;
case _FOR_:
/* y4: чтение следующей лексемы */
Number_Lexem++;
if (Tab_Lexems[Number_Lexem].Code == _IDENTIFIER_){
/* y13: добавить значение лексемы с номером Number_Lexem в стек StekIdent */
StekIdent.Push(Tab_Lexems[Number_Lexem].Value);
/* y4: чтение следующей лексемы */
Number_Lexem++;
}
else {
/*Конструкция <оператор>. Неверный оператор FOR*/
Code_Error = 26; return;
}
if (Tab_Lexems[Number_Lexem].Code == _ASSIGNMENT_)
/* y4: чтение следующей лексемы */
Number_Lexem++;
else {
/*Конструкция <оператор>. Неверный оператор FOR*/
Code_Error = 26; return;
}
/* Обработка конструкции <выражение> после := */
ProcedureE();
if (Code_Error != -1) return;
/* y14: в переменную Ai снять элемент со стека StekRes (Ai <- StekRes), прочитать (без удаления) вершину стека StekIdent в переменную Bi (Bi <- StekIdent), идентификатору с номером Bi, присвоить значение Ai */
Ai = StekRes.Pop();
Bi = StekIdent.Peek();
ArrIdent[Bi] = Ai;
if (Tab_Lexems[Number_Lexem].Code == _TO_){
/* y29: значение текущей лексемы занести в стек StekForExit [Tab_Lexems[Number_Lexem].Value -> StekForExit]*/
StekForExit.Push(Tab_Lexems[Number_Lexem].Value);
/* y4: чтение следующей лексемы */
Number_Lexem++;
}
else {
/*Конструкция <оператор>. Неверный оператор FOR*/
Code_Error = 26; return;
}
/* Обработка конструкции <выражение> после TO */
ProcedureE();
if (Code_Error != -1) return;
/* y27: снять вершину стека StekRes в переменную Ai */
Ai = StekRes.Pop();
/* Обработка конструкции U=<шаг> после TO */
if (Tab_Lexems[Number_Lexem].Code == _STEP_){
/* y4: чтение следующей лексемы */
Number_Lexem++;
/*Обработка конструкции <выражение> после STEP*/
ProcedureE();
if (Code_Error != -1) return;
/* y37: снять вершину стека StekRes в переменную Ai*/
Ai = StekRes.Pop();
}
else
/* y38: В переменную Ai занести 1 */
Ai = 1;
/* Обработка конструкции <последовательность операторов> - тела цикла FOR */
ProcedureL();
if (Code_Error != -1) return;
if (Tab_Lexems[Number_Lexem].Code == _ENDFOR_){
/* y28: значение текущей лексемы занести в Ai (Tab_Lexems[Number_Lexem].Value -> Ai); номеру текущей лексемы присвоить значение переменной Ai */
Ai = Tab_Lexems[Number_Lexem].Value;
Number_Lexem = Ai;
}
else {
/*Конструкция <оператор>. Неверный оператор FOR*/
Code_Error = 26; return;
}
// выполнение тела цикла FOR
do {
/* Обработка конструкции <выражение> после TO*/
ProcedureE();
if (Code_Error != -1) return;
/*y30:снять вершину стека StekRes в переменную ForAi*/
ForAi = StekRes.Pop();
/* Обработка конструкции U=<шаг> после TO */
if (Tab_Lexems[Number_Lexem].Code == _STEP_){
/* y4: чтение следующей лексемы */
Number_Lexem++;
/*Обработка конструкции <выражение> после STEP*/
ProcedureE();
if (Code_Error != -1) return;
/*y37:снять вершину стека StekRes в переменную Ai*/
Ai = StekRes.Pop();
}
else
/* y38: В переменную Ai занести 1 */
Ai = 1;
/* y31: значение Ai занести в переменную ForBi (Ai-> ForBi); прочитать (без удаления)вершину стека StekIdent в переменную ForCi (StekIdent -> ForCi); занести в переменную ForDi значение идентификатора с номером ForCi (ForDi=ArrIdent[ForCi]); сравнить ForDi+ForBi и ForAi: ForDi+ForB<=ForAi – движение по ветке TRUE, иначе по FALSE */
ForBi = Ai;
ForCi = StekIdent.Peek();
ForDi = ArrIdent[ForCi];
if (ForDi + ForBi <= ForAi){
//движение по TRUE - продолжение итерации цикла FOR
/* y32: значение идентификатора с номером ForCi увеличить на значение переменной ForBi */
ArrIdent[ForCi] += ForBi;
/* Обработка конструкции <последовательность операторов> - тела цикла FOR */
ProcedureL();
if (Code_Error != -1) return;
/* y28: значение текущей лексемы занести в Ai (Tab_Lexems[Number_Lexem].Value -> Ai); номеру текущей лексемы присвоить значение переменной Ai */
Ai = Tab_Lexems[Number_Lexem].Value;
Number_Lexem = Ai;
}
else {
//движение по ветке FALSE - завершение цикла FOR
/* y33: снять вершину стека StekIdent в переменную Bi (StekIdent -> Bi); снять вершину стека StekForExit в Ai (StekForExit -> Ai); текущему номеру лексемы присвоить значение переменной Ai */
Bi = StekIdent.Pop();
Ai = StekForExit.Pop();
Number_Lexem = Ai;
}
} while (ForDi + ForBi <= ForAi);
break;
}
/* y36: пока в StekPostDec есть элементы выполнять: снять вершину StekPostDec в переменную Ai (StekPostDec -> Ai), идентификатор с номером Ai уменьшить на 1 */
for (int i = StekPostDec.Count; i > 0; i--){
Ai = StekPostDec.Pop();
ArrIdent[Ai]--;
}
return;
} /* End ProcdureS */
6.9 Метод обработки конструкции «содержимое»
/* <содержимое>::= CASE<константа> : <последовательность операторов> <содержимое> | DEFAULT:<последовательность операторов> | <пусто> */
static void ProcedureZ()
{
int Ai, Bi;
if (Tab_Lexems[Number_Lexem].Code== _CASE_) {
/*y4: чтение следующей лексемы */
Number_Lexem++;
if (Tab_Lexems[Number_Lexem].Code == _CONSTANT_){
/* y22: прочитать (без удаления) вершину стека StekCaseValue в переменную Ai (StekCaseValue -> Ai); значение прочитанной константы занести в Bi (Tab_Constants[Tab_Lexems[Number_Lexem].Value] -> Bi); сравнить Ai и Bi: Ai==Bi – движение по TRUE, иначе по FALSE*/
Ai=StekCaseValue.Peek();
Bi=Tab_Constants[Tab_Lexems[Number_Lexem].Value];
/* y4: чтение следующей лексемы */
Number_Lexem++;
if(Ai==Bi) {//обработка TRUE для ветки CASE
/* y23: снять вершину стека StekDefaultValue в переменную Ai (StekDefaultValue -> Ai); отправить значение 0 в стек StekDefaultValue (0 -> StekDefaultValue) */
Ai=StekDefaultValue.Pop();
StekDefaultValue.Push(0);
if (Tab_Lexems[Number_Lexem].Code == _COLON_)
/* y4: чтение следующей лексемы */
Number_Lexem++;
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
/* <последовательность операторов> после : */
ProcedureL();
if (Code_Error != -1) return;
}
else {//обработка FALSE для ветки CASE
if (Tab_Lexems[Number_Lexem].Code == _COLON_){
/* y24: снять значение текущей лексемы в переменную Ai (Tab_Lexems[Number_Lexem].Value -> Ai); номеру текущей лексемы присвоить значение Ai */
Ai = Tab_Lexems[Number_Lexem].Value;
Number_Lexem = Ai;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
}
/* Обработка конструкции <содержимое> после :*/
ProcedureZ();
if (Code_Error != -1) return;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
}
if (Tab_Lexems[Number_Lexem].Code == _DEFAULT_){
/* y25: снять вершину стека StekDefaultValue в переменную Ai (StekDefaultValue -> Ai); сравнить Ai с 1: Ai==1 – движение по TRUE, иначе по FALSE*/
Ai=StekDefaultValue.Pop();
/* y4: чтение следующей лексемы */
Number_Lexem++;
if(Ai==1){//движение по TRUE для ветки DEFAULT
if (Tab_Lexems[Number_Lexem].Code == _COLON_)
/* y4: чтение следующей лексемы */
Number_Lexem++;
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
/* <последовательность операторов> после : */
ProcedureL();
if (Code_Error != -1) return;
}
else {//обработка FALSE для ветки DEFAULT
if (Tab_Lexems[Number_Lexem].Code == _COLON_){
/* y24: снять значение текущей лексемы в переменную Ai (Tab_Lexems[Number_Lexem].Value -> Ai); номеру текущей лексемы присвоить значение Ai */
Ai = Tab_Lexems[Number_Lexem].Value;
Number_Lexem = Ai;
}
else {
/* Неверный оператор SWITCH.*/
Code_Error = 25; return;
}
}
}
}
7 ТЕСТИРОВАНИЕ ИНТЕРПРЕТАТОРА МОДИФИЦИРОВАННОГО ЯЗЫКА MILAN
7.1 Тестовые примеры без ошибок
7.1.1 Тестовый пример №1.
BEGIN
x:=0;
FOR n:=0 TO 100 STEP 10
z:=READ;
x:=x+z;
ENDFOR;
OUTPUT(x)
END
Рисунок 6 – Результат работы тестового примера №1
7.1.2 Тестовый пример №2.
BEGIN /*здесь находится начало программы*/
x:=10;
OUTPUT(x);
OUTPUT(x--); /* постдекремент */
OUTPUT(--x); /* преддекремент */
OUTPUT(x);
END
Рисунок 7 – Результат работы тестового примера №2
7.1.3 Тестовый пример №3.
BEGIN
x:=READ;
n:=READ;
SWITCH ( n ) {
CASE 1 : OUTPUT( x/10) /* если n=1, то поделить */
CASE 2: OUTPUT(x*10) /* если n=2, то умножить */
DEFAULT : OUTPUT(0) } /* иначе, 0 */
END
Рисунок 8 – Результат работы тестового примера №3
7.2 Тестовые примеры c ошибками
7.2.1 Тестовый пример №4.
BEGIN
FOR n:=0 TO
x:=x+1;
ENDFOR;
OUTPUT(x)
END
Рисунок 9 – Результат работы тестового примера №4
7.2.2 Тестовый пример №5.
BEGIN
x:=READ;
n:=READ;
SWITCH(n){
CASE 1 : OUTPUT( x/10) /* если n=1, то поделить */
CASE 2: OUTPUT(x*10) /* если n=2, то умножить */
DEFAULT : OUTPUT(0) /* иначе, 0 */
END
Рисунок 10 – Результат работы тестового примера №5
7.2.3 Тестовый пример №6.
BEGIN
n:=56--;
OUTPUT(n);
END
Рисунок 11 – Результат работы тестового примера №6
7.2.4 Тестовый пример №7.
BEGIN
IF x/2 THEN
x:=2%x;
ENDIF;
OUTPUT(0)
END
Рисунок 12 – Результат работы тестового примера №7
ЗАКЛЮЧЕНИЕ
В рамках выполнения курсовой работы были изучены методы и алгоритмы построения интерпретатора учебного языка MILAN.
Приобретены навыки написания лексического и синтаксического анализаторов языков, описываемых LL(1)-грамматикой.
Согласно заданию, в грамматику языка MILAN были добавлены новые конструкции и произведена разработка лексического и синтаксического анализаторов интерпретатора модифицированного языка.
Также была проделана работа по выявлению возможных ошибок в тестовых программах, проработаны сообщения об ошибках, вывод которых осуществляется на стадиях лексического и синтаксического анализа.
Таким образом, был закреплён изученный курс по дисциплине «Основы трансляции».
СПИСОК ЛИТЕРАТУРЫ
1. Гагарина Л.Г., Кокорева Е.В. Введение в теорию алгоритмических языков и компиляторов: учеб. пособ. [Текст] / Л.Г. Гагарина, Е.В. Кокорева. – М.: ИД «ФОРУМ», 2011. – 176 с.
2. Мозговой М.В. Классика программирования: языки, автоматы, компиляторы. Практический подход [Текст] / М.В. Мозговой. – СПб.: «Наука и техника», 2006. – 320 с.
3. Ахо А., Сети Р., Ульман Д. Компиляторы: принципы, технолигии, инструменты [Текст]: пер. с англ. / А. Ахо, Р. Сети, Д. Ульман. – М.: Изд. дом «Вильямс», 2003. – 768 с.
4. Карпов Ю.Г. Основы построения трансляторов [Текст] / Ю.Г. Карпов. – СПб.: БХВ-Петербург, 2005. – 272 с.
КР 230100. 28 Д. ПЗ
Лист Изм. Лист № докум. Подп. Дата
39
38
\х9
y2
\хa
\хd
y3
\х20
y2
y0, y1
*
y1
A
y4, y1
A
y4, y1
C
y4, y1
*
y5, y6, y11
y9
\x1a
y10
C
y7, y1
C
y1
*
y8, y11
*
+
y11, y1
*’
y11, y1
=
y11, y1
>
y1
*
y11
=
y11, y1
<
y1
>
y11,y1
*
y11
;
y11, y1
=
y11, y1
{
y11, y1
}
y11, y1
=
y11, y1
:
y1
*
y11
-
y11, y1
-
y1
*
y11
(
y11, y1
)
y11, y1
*
y1
*’
y1
*’
y1
/
y1
*
y11
/
y1
*
y1
а)
BEGIN
x:=0;
n:=5;
WHILE n>0 DO
z:=READ;
x:=x+z;
n:=n-1
ENDDO ;
OUTPUT(x)
END
б)
BEGIN
x:=READ;
IF x>2 THEN
OUTPUT(1)
ELSE
OUTPUT(0)
ENDIF
END
в)
BEGIN
x:=READ;
IF x>2 THEN
х:=2
ENDIF ;
OUTPUT(x)
END
г)
BEGIN
x:=5;
y:=0;
SWITCH (x) {
CASE 3 : x:=6;
CASE 4 : x:=7;
DEFAULT : x:=10;
}
END
д)
BEGIN
x:=5;
y:=0;
FOR i:=0 TO 10 STEP 2
x:=x+i
ENDFOR ;
END
y0
WHILE
y1
DO
y1
THEN
y3
:
y8
ENDDO
y2
ELSE
y4
}
y9
CASE
y9
DEFAULT
y9
\x1a
y6
ENDIFy5
TO
y10
ENDFOR
y11
*
y7
SWITCH
y7
:
y8
*
y7
*
y7
DO
B
IF
y4
y18
THEN
true
y4
L
ELSE
false
y4
L
ENDIF
y4
y36
true
y19
ENDIF
y4
false
y19
y16
L
WHILE
false
y17
B
true
y4
ENDDO
y17
zs
y4
OUTPUT
y4
os
y4
E
y15
id
y13, y4
prsv
y4
E
y14
os
y4
E
zs
y4
ofs
y21,y4
int
y22,y4
true
y23
:
y4
SWITCH
y4
CASE
y4
L
Z
zfs
y26,y4
false
:
y24
id
y13,y4
E
y14
E
y27
U
FOR
y4
TO
y29,y4
L
ENDFOR
y28
U
y31
y30
E
false
y33
true
y32
L
ENDFOR
y28
S:
otn
y11,y4
E
y12
E
B:
ots
y7, y4
T
y8
y10
T
ots
y9, y4
E:
P
y6
P
otu
y5, y4
T:
y0
BEGIN
y4
tz
y4
END
L
W:
S
L:
CASE
y4
true
int
y22,y4
Z:
:
y4
L
Z
false
:
y24
true
DEFAULT
y25
:
y4
L
false
:
y24
*
STEP
E
y37
y38
U:
dec
id
y1, y4
X
P:
Y
Y
int
y2, y4
id
y1, y4
READ
y3, y4
E
os
y4
zs
y4
dec
y34, y4
*
X:
dec
y35, y4
*
Y:
Цифра
СПИСОК ЛИТЕРАТУРЫ
1. Гагарина Л.Г., Кокорева Е.В. Введение в теорию алгоритмических языков и компиляторов: учеб. пособ. [Текст] / Л.Г. Гагарина, Е.В. Кокорева. – М.: ИД «ФОРУМ», 2011. – 176 с.
2. Мозговой М.В. Классика программирования: языки, автоматы, компиляторы. Практический подход [Текст] / М.В. Мозговой. – СПб.: «Наука и техника», 2006. – 320 с.
3. Ахо А., Сети Р., Ульман Д. Компиляторы: принципы, технолигии, инструменты [Текст]: пер. с англ. / А. Ахо, Р. Сети, Д. Ульман. – М.: Изд. дом «Вильямс», 2003. – 768 с.
4. Карпов Ю.Г. Основы построения трансляторов [Текст] / Ю.Г. Карпов. – СПб.: БХВ-Петербург, 2005. – 272 с.
Вопрос-ответ:
Каким языком программирования реализован интерпретатор модифицированного языка Milan?
Интерпретатор модифицированного языка Milan реализован с помощью языка программирования С.
Что такое язык Milan?
Язык Milan - это учебный язык программирования, который используется для обучения основам программирования и алгоритмическому мышлению.
Чем отличается модифицированный язык Milan от оригинального?
Модифицированный язык Milan включает в себя некоторые изменения и дополнения, такие как новые операторы и возможности, которые расширяют функциональность языка.
Какие лексемы включает в себя модифицированный язык Milan?
Лексемы модифицированного языка Milan включают в себя ключевые слова, идентификаторы, целые числа, операторы, скобки и разделители.
Как работает интерпретатор модифицированного языка Milan?
Интерпретатор модифицированного языка Milan считывает программу на языке Milan, выполняет лексический анализ, синтаксический анализ и интерпретацию программы, позволяя пользователю видеть результат выполнения своего кода.
Что такое язык Milan?
Язык Milan - это учебный язык программирования, для которого был разработан интерпретатор.
Какие задачи решает интерпретатор языка Milan?
Интерпретатор языка Milan позволяет выполнять программы на этом языке, интерпретируя их и выводя результат в соответствии со спецификацией языка.
Какие лексемы используются в языке Milan?
В языке Milan используются различные лексемы, такие как идентификаторы, числа, операторы и ключевые слова. Каждая лексема имеет свою синтаксическую и семантическую интерпретацию.