МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ Санкт-Петербургский государственный электротехнический университет
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА К КУРСОВОЙ РАБОТЕ по дисциплине «Разработка языковых процессоров»
Выполнил студент гр. 0351 Преподаватель Безруков Ю. В. Самойленко В. П.
Санкт-Петербург 2005
Содержание.
Id 12
S 12
F 12
C 13
C 13
T 13
D 13
S 14
Id 14
F 14
C 14
Next1 14
Next4 14
Next3 14
Next2 14
T 14
D 14
Задание к курсовой работе.
Разработать язык программирования, являющийся подмножеством языка ПАСКАЛЬ, и транслятор с этого языка в последовательность тетрад.
Язык должен обеспечивать работу с переменными и константами целого и вещественного типов и векторами с вещественными компонентами.
Язык должен допускать использование арифметических выражений, в состав которых могут входить константы и простые переменные целого и вещественного типов, компоненты векторов, круглые скобки и знаки операций: сложение, вычитание, умножение и деление. Приоритет операций - обычный.
В языке должны быть определены следующие операции над векторами:
- определение длины вектора;
- сумма векторов;
- скалярное произведение векторов;
- умножение константы или простой переменной целого или вещественного типа на вектор.
Состав операторов:
- оператор присваивания;
- оператор ввода;
- оператор вывода;
- составной оператор;
- оператор безусловного перехода;
- условный оператор, условие в котором задается отношением;
- оператор цикла с предусловием, условие в котором задается отношением.
Программа на входном языке может содержать комментарии.
Синтаксический анализ должен быть выполнен с использованием грамматик слабого предшествования.
1. Описание входного языка.
1. 1. Описание синтаксиса входного языка.
<программа>::=program <идентификатор> ; <объявления> begin [ <оператор> { ; <оператор> }] end .
<объявления>::=[label <объявление_меток>] [const <определение_констант> ] [var <объявление_переменных>]
<объявление_меток>::=<метка>{,<метка>} ;
<определение_констант>::=<имя_константы>=<константа> ; {<определение_констант>}
<объявление_переменных>::=<идентификатор> {, <идентификатор> } : <тип> ; {<объявление_переменных>}
<оператор>::=[<метка> : ] <простой_оператор> | [<метка> : ] <составной_оператор>
<составной_оператор>::=begin [ <оператор> {; <оператор>}] end
<простой_оператор>::=<оператор_присваивания> | <оператор_ввода> | <оператор_вывода> | <оператор_безусловного_перехода> | <условный_оператор> | <оператор_цикла_с_предусловием>
<оператор_присваивания>::=<переменная> := <арифметическое_выражение> | <компонента_вектора> := <арифметическое_выражение> | <имя_вектора> := <арифметическое_выражение>
<оператор_ввода>::=read ( <строка_ввода> {, <строка_ввода> } ) | readln ( <строка_ввода> {, <строка_ввода> } )
<строка_ввода>::=<переменная> | <компонента_вектора>
<оператор_вывода>::=write ( <строка_вывода> {, <строка_вывода> } ) | writeln ( <строка_вывода> {, <строка_вывода> } )
<строка_вывода>::=<арифметическое_выражение> [: < арифметическое_выражение > [: < арифметическое_выражение >] ]
<оператор_безусловного_перехода>::=goto <метка>
<условный_оператор>::=if <выражение> then <оператор> [else <оператор>]
<оператор_цикла_с_предусловием>::=while <выражение> do <оператор>
<выражение>::=<арифметическое_выражение> <знак_отношения> <арифметическое_выражение>
<арифметическое_выражение>::=<арифметическое_выражение> + <терм> | <арифметическое_выражение> - <терм> | <терм>
<терм>::=<терм> * <множитель> | <терм> / <множитель> | <множитель>
<множитель>::=<константа> | <имя_константы> | <переменная> | <компонента_вектора> | <операция_над_векторами> | ( <арифметическое_выражение> )
<операция_над_векторами>::=length ( <вектор> ) | sum ( <вектор> , <вектор> ) | multscal ( <вектор> , <вектор> ) | multconst ( <вектор> , <константа> ) | multconst ( <вектор> , <имя_константы> ) | multconst ( <вектор> , <переменная> )
<вектор>::=<имя_вектора> | <операция_над_векторами>
<компонента_вектора>::=< идентификатор> [ <индекс_вектора> ]
<тип>::=real | integer | vector [ <размерность_вектора> ]
<константа>::=[ + | - ] <число_без_знака>
<индекс_вектора>::=<переменная> | <целое_без_знака> | <имя_константы> | <арифметическое_выражение>
<размерность_вектора>::=<целое_без_знака> | <имя_константы>
<метка>::=<целое_без_знака>
<имя_константы>::=<идентификатор>
<переменная>::=< идентификатор>
<имя_вектора>::=<идентификатор>
<знак_отношения>::=< | > | = | <= | >= | <>
<число_без_знака>::=<целое_без_знака> | <целое_без_знака> . <целое_без_знака> | <целое_без_знака> E <порядок>
<порядок>::= + <целое_без_знака> | - <целое_без_знака>
<целое_без_знака>::=<цифра> {<цифра>}
<идентификатор>::=<буква> {<буква> | <цифра>}
<буква>::=A | a | … | Z | z
<цифра>::=0 | 1 | … | 9
1. 2. Описание семантики входного языка.
Представление данных различных типов в оперативной памяти.
Тип |
Размер, байт |
Диапазон значений |
real |
4 |
3.4e-38 .. 3.4e+38 |
integer |
2 |
-32768 .. 32767 |
Приоритет операций и порядок выполнения операций с одинаковым приоритетом (в порядке убывания приоритета).
Знак операции |
Название операции |
Порядок выполнения |
* |
Умножение |
Слева направо |
/ |
Деление |
Слева направо |
+ |
Сложение |
Слева направо |
- |
Вычитание |
Слева направо |
< |
Меньше |
Слева направо |
<= |
Меньше или равно |
Слева направо |
> |
Больше |
Слева направо |
>= |
Больше или равно |
Слева направо |
= |
Равно |
Слева направо |
<> |
Не равно |
Слева направо |
Правила преобразования типов.
1) Правила преобразования типов для бинарных арифметических операций.
Операция |
Тип операнда1 |
Тип операнда2 |
Тип результата |
+ , -, * |
integer |
integer |
integer |
+, -, * |
integer |
real |
real |
+, -, * |
real |
integer |
real |
+, -, * |
real |
real |
real |
/ |
integer |
integer |
real |
/ |
integer |
real |
real |
/ |
real |
integer |
real |
/ |
real |
real |
real |
2) Выполнение оператора присваивания.
Тип переменной до выполнения оператора |
Тип значения арифметического выражения |
Тип переменной после выполнения оператора |
integer |
integer |
integer |
real |
real |
real |
real |
integer |
real |
vector |
vector |
vector, если вектора одинаковой размерности |
vector |
vector |
Ошибка выполнения оператора присваивания, если ветора различной размерности |
vector |
real, integer |
Ошибка выполнения оператора присваивания |
real, integer |
vector |
Ошибка выполнения оператора присваивания |
integer |
real |
Ошибка выполнения оператора присваивания |
3) Преобразование типов для выполнения операции отношения.
Операнд1 |
Операнд2 |
Преобразование |
integer |
integer |
Не требуется |
real |
real |
Не требуется |
integer |
real |
операнд1 real |
real |
integer |
операнд2 real |
Правила выполнения операторов языка.
1) Оператор присваивания.
Порядок выполнения:
-
вычисляется значение арифметического выражения;
-
производится преобразование типов в соответствии с таблицей (см. таблицу преобразования типов для оператора присваивания);
-
переменной в левой части оператора присваивания присваивается значение арифметического выражения.
2) Оператор ввода.
Выполнение оператора read: работа программы приостанавливается, пользователь должен ввести с клавиатуры значения, которые по очереди будут присваиваться переменным из списка в круглых скобках. При вводе значения переменных разделяются пробелом или маркером конца строки. Когда значения всех переменных будут введены, программа продолжит работу. Выполнение оператора readln аналогично, кроме того, что значения переменных могут разделяться только пробелом, а после выполнения оператора readln происходит автоматический переход на следующую строку.
3) Оператор вывода.
Выполнение оператора write: оператор write вычисляет значение первого арифметического выражения (должно быть целым или вещественным числом) в строке вывода и выводит его на экран. Значение второго арифметического выражения (должно быть целым числом) в строке вывода определяет ширину поля вывода. Значение третьего арифметического выражения (должно быть целым числом) – число дробных цифр в выводимом дробном числе, если оно не задано, вещественное число будет выводиться в экспоненциальной форме. Выполнение оператора writeln аналогично, кроме того, что оператор writeln после вывода арифметического выражения на экран осуществляет переход на следующую строку.
4) Составной оператор.
Выполнение составного оператора: последовательно выполняются операторы между ключевыми словами begin и end.
5) Оператор безусловного перехода.
Выполнение оператора goto: передает управление оператору, помеченному меткой, следующей за ключевым словом goto. Если метка, следующая за ключевым словом goto, не была описана в разделе описаний или в программе нет оператора, помеченного данной меткой, то ошибка выполнения оператора безусловного перехода.
6) Условный оператор.
Порядок выполнения оператора if.
a) вычисляется значение выражения следующим образом:
-
вычисляется значение арифметического выражения слева от знака отношения;
-
вычисляется значение арифметического выражения справа от знака отношения;
-
если значения арифметических выражений не являются векторами, то производится преобразование типов в соответствии с таблицей, проверяется, выполняется ли соотношение между арифметическими выражениями; если да, то выражению присваивается значение «истина», ели нет – «ложь»;
-
если значения арифметических выражений являются векторами, то ошибка.
b) если значение выражения «истина», то выполняется оператор, следующий за ключевым словом then;
c) если значение выражения «ложь» и есть конструкция с ключевым словом else, то выполняется оператор, следующий за ключевым словом else;
d) если значение выражения «ложь» и нет конструкции с ключевым словом else, то управление передается оператору, следующему за условным оператором.
7) Оператор цикла с предусловием.
Порядок выполнения оператора while:
-
вычисляется значение выражения (аналогично вычислению выражения при выполнении оператора if);
-
если значение выражения «истина», то выполняется оператор, следующий за ключевым словом do, после его выполнения управление передается оператору while;
-
если значение выражения «ложь», то управление передается следующему за оператором while оператору.
Правила выполнения операций над векторами.
Вектор – заключенная в круглые скобки последовательность вещественных чисел типа real (компонент), разделенных запятыми.
1) Операция length (длина вектора).
Для аргумента-вектора (x1, x2,.. xN) размерности N возвращается числовое значение вещественного типа .
2) Операция sum (сумма векторов).
Для аргументов-векторов (x1, x2,.. xN) и (y1, y2,.. yN) размерности N возвращается вектор (z1, z2,.. zN) размерности N, где zK=xK+yK, K=1, 2,.. N.
3) Операция multscal (скалярное произведение векторов).
Для аргументов-векторов (x1, x2,.. xN) и (y1, y2,.. yN) размерности N возвращается числовое значение вещественного типа x1*y1+x2*y2+…+xN+yN.
4) Операция multconst (умножение константы или простой переменной на вектор).
Для аргумента-вектора (x1, x2,.. xN) размерности N и аргумента C (константа или простая переменная целого или вещественного типов) возвращается вектор (y1, y2,.. yN) размерности N, где yK=С*xK, K=1, 2,.. N.
Правила реализации конструкций языка.
-
Операции целочисленной арифметики выполняются без учета переполнения.
-
Каждая переменная, используемая в программе, должна быть описана в разделе описаний переменных.
-
Переменная не может быть описана более одного раза.
-
Значение константы не может быть переопределено.
-
Переменные при описании инициализируются нулевыми значениями.
-
Использование неинициализированной переменной в любом выражении или операторе, кроме левой части оператора присваивания, приводит к ошибке.
-
Имена переменных, констант и меток не могут совпадать.
-
Имена переменных, констант и меток не могут совпадать с ключевыми словами.
-
Программа на входном языке может содержать комментарии: заключенный в фигурные скобки текст из любых символов, кроме символа закрывающей фигурной скобки. Комментарии могут находиться в любом месте программы, если они не разрывают лексемы.
-
Значения размерности вектора и индекса вектора должны быть натуральными числами.
-
В разделе описаний переменных при формировании размерности вектора нельзя использовать имена переменных.
-
Аргументом операции над векторами может быть операция над векторами, результатом которой является вектор.
2. Описание этапа лексического анализа.
2. 1. Определение типов лексем.
Типы лексем, выделяемых лексическим анализатором из программы на входном языке, определяются входным языком. Лексический анализатор исключает из текста исходной программы комментарии, незначащие пробелы, символы табуляции и перевода строки и выделяет лексемы следующих типов:
-
идентификаторы;
-
целые и вещественные беззнаковые константы;
-
ключевые слова входного языка;
-
однолитерные и двухлитерные разделители.
Соотношение между токенами и лексемами.
Токен |
Лексемы |
Языковая конструкция |
Id |
count, index |
Идентификатор |
Nat |
0, 1, 10, 100 |
Целое число без знака |
Num |
1.2, 1E+10, 1E-10 |
Вещественное число без знака |
program |
program |
Ключевое слово program |
begin |
begin |
Ключевое слово begin |
end |
end |
Ключевое слово end |
label |
label |
Ключевое слово label |
const |
const |
Ключевое слово const |
var |
var |
Ключевое слово var |
real |
real |
Ключевое слово real |
integer |
integer |
Ключевое слово integer |
vector |
vector |
Ключевое слово vector |
read |
read |
Ключевое слово read |
readln |
readln |
Ключевое слово readln |
write |
write |
Ключевое слово write |
writeln |
writeln |
Ключевое слово writeln |
goto |
goto |
Ключевое слово goto |
if |
if |
Ключевое слово if |
then |
then |
Ключевое слово then |
while |
while |
Ключевое слово while |
do |
do |
Ключевое слово do |
length |
length |
Ключевое слово length |
sum |
sum |
Ключевое слово sum |
multscal |
multscal |
Ключевое слово mult_scal |
multconst |
multconst |
Ключевое слово mult_const |
:= |
:= |
Оператор присваивания |
rel |
<, >, <=, >=, <> |
Операция отношения |
+ |
+, - |
Операция типа «сложение» |
* |
*, / |
Операция типа «умножение» |
( |
( |
Открывающая круглая скобка |
) |
) |
Закрывающая круглая скобка |
[ |
[ |
Открывающая квадратная скобка |
] |
] |
Закрывающая квадратная скобка |
; |
; |
Символ «;» |
, |
, |
Символ «,» |
: |
: |
Символ «:» |
= |
= |
Знак равенства |
. |
. |
Символ конца программы |
2. 2. Определение синтаксиса лексем.
Определение автоматных грамматик, описывающих синтаксис лексем.
2. 2. 1. Классы литер, с помощью которых записываются программы на входном языке:
-
класс «буква»: a A … z Z
-
класс «цифра»: 0 1 2 3 4 5 6 7 8 9
-
класс «однолитерные разделители»: ; , * / ( ) [ ]
-
класс «литеры однолитерных и двухлитерных разделителей»: < > = +, -
2. 2. 2. Составление автоматных грамматик, описывающих синтаксис лексем.
Терминальными символами грамматики являются классы литер, а начальным символом грамматики – символ S.
-
Автоматная грамматика, описывающая синтаксис идентификатора и ключевого слова. Здесь буква – класс «буква», цифра – класс «цифра», 1 – класс, включающий все литеры, за исключением букв и цифр.
Правила грамматики:
S |
|
буква Id |
Id |
|
буква Id |
Id |
|
цифра Id |
Id |
|
1 |
-
Автоматная грамматика, описывающая синтаксис целого числа без знака и метки. Здесь цифра – класс «цифра», 2 – класс, включающий все литеры, за исключением цифр.
Правила грамматики:
S |
|
цифра C |
C |
|
цифра C |
C |
|
2 |
-
Автоматная грамматика, описывающая синтаксис вещественного числа без знака. Здесь 2 – класс, включающий все литеры, за исключением цифр.
Правила грамматики:
S |
|
цифра C |
C |
|
цифра C |
C |
|
. T |
C |
|
E + T |
C |
|
E – T |
T |
|
D |
D |
|
цифра D |
D |
|
2 |
-
Автоматные грамматики, описывающие синтаксис однолитерного и двухлитерного разделителей. Здесь знак – класс «однолитерные разделители», 3 – класс, включающий все литеры.
Правила грамматики:
S |
|
знак L |
L |
|
3 |
S |
|
: Next |
Next |
|
= E |
E |
|
3 |
S |
|
< Next |
Next |
|
= E |
E |
|
3 |
S |
|
> Next |
Next |
|
= E |
E |
|
3 |
S |
|
< Next |
Next |
|
> E |
E |
|
3 |
2. 3. Построение диаграммы лексического анализатора.
2. 3. 1. Построение графов конечных автоматов для распознавания лексем.
Здесь S – начальное состояние конечного автомата, F- конечное состояние, соответствующее концу разбора лексемы.
Граф конечного автомата для распознавания лексем «идентификатор» и «ключевое слово».
Буква, цифра
Id Буква
S F 1
Граф конечного автомата для распознавания лексемы «целая константа без знака».
2 Цифра S F C Цифра
Граф конечного автомата для распознавания лексемы «вещественная константа без знака».
S
Цифра
F
Цифра .,
E+ E- C T 2
2 Цифра D 2 Цифра
Графы конечных автоматов для распознавания лексем «однолитерный разделитель» и «двухлитерный разделитель».
Знак 3 S L F
S Next E F 3 : = S Next E F = < 3 S Next E F 3 = > 3 3 3
S Next E F > < 3
3