0. Формулировка задания
Вариант 2.
Необходимо разработать язык программирования, являющийся подмножеством языка Паскаль, и транслятор с этого языка в последовательность триад и в последовательность команд ассемблера.
Язык должен обеспечивать операции над переменными и константами базовых типов (целого, булевского и ограниченного), а также над переменными и компонентами производного типа (булевская матрица). Перечень операций должен включать как предусмотренные базовым типом (сложение, вычитание, умножение и деление), так и операции над переменными производного типа (определение размеров матрицы, конъюнкция и дизъюнкция матриц, инверсия матрицы). В языке должна быть определена операция преобразования типов при структурной эквивалентности типов. В язык должна быть предусмотрена возможность создания пользовательских типов.
Язык должен допускать использование арифметических выражений, в состав которых могут входить константы и простые переменные базовых типов, компоненты структурированного типа, круглые скобки и знаки арифметических операций: сложение, вычитание, умножение и деление. Приоритет операций обычный.
Язык должен допускать использование логических выражений, в состав которых могут входить отношения, круглые скобки и знаки логических операций: И, ИЛИ, НЕ и константы и переменные логического типа. Приоритет операций обычный.
Состав операторов языка:
-
оператор присваивания;
-
оператор ввода;
-
оператор вывода;
-
составной оператор;
-
оператор безусловного перехода;
-
условный оператор, условие в котором задается логическим выражением;
-
оператор цикла с постусловием, условие в котором задается логическим выражением.
Перегрузка операций не разрешается.
Класс грамматик – SLR(1)-грамматики.
Промежуточный язык – триады.
1. Описание входного языка
1.1. Описание синтаксиса входного языка
Для описания входного языка будем использовать металингвистические формулы Бэкуса-Наура (БНФ).
<программа> ::= [program <идентификатор>;]
{<раздел описания>} <составной оператор>.
<раздел описания> ::= type <раздел описания типа> |
const <раздел описания констант> |
var <раздел описания переменных> |
label <раздел описания меток>
<раздел описания типа> ::= <описание типа> {<описание типа>}
<раздел описания констант> ::=
<описание констант> {<описание констант>}
<раздел описания переменных> ::=
<описание переменных> {<описание переменных>}
<раздел описания меток> ::= <описание меток>;
<описание типа> ::= <идентификатор> = <значение типа>;
<значение типа> ::= <базовый тип> | <структурированный тип>
<базовый тип> ::= <идентификатор> | <ограниченный тип > |
integer | boolean
<структурированный тип> ::= <идентификатор> |
array [<индекс>, <индекс>]
<индекс> ::= <идентификатор> | <неотрицательное число>
<ограниченный тип> ::= <идентификатор> | <константа> .. <константа>
<описание констант> ::= <простая константа> | <матрица-константа>
<простая константа> ::= <идентификатор> = <значение константы>;
<значение константы> ::= <константа> | <логическая константа>
<константа> ::= <идентификатор> | <число>
<матрица-константа> ::= <идентификатор>: <структурированный тип> =
((<список би-констант>) {, (<список би-констант>)});
<список би-констант> ::= <би-константа> {, <би-константа>}
<би-константа> ::= <идентификатор> | <логическая константа>
<описание переменных> ::= <список переменных>: <значение типа>;
<список переменных> ::= <идентификатор> {, <идентификатор>}
<описание меток> ::= <имя метки> {, <имя метки>}
<имя метки> ::= <идентификатор> | <неотрицательное число>
<составной оператор> ::= begin <оператор> {; <оператор>} end
<оператор> ::= [<имя метки>:] <непомеченный оператор>
<непомеченный оператор> ::= <оператор присваивания> |
<условный оператор> |
<оператор цикла> | <оператор перехода> |
<оператор ввода> | <оператор вывода> |
<операции над матрицами> | <составной оператор>
<оператор присваивания> ::= <переменная> := < выражение>
<условный оператор> ::=
if < выражение> then <оператор> [else <оператор>]
<оператор цикла> ::= repeat <оператор> until < выражение>
<оператор перехода> ::= goto <имя метки>
<оператор ввода> ::= read(<список переменных>)
<оператор вывода> ::= write(<выражение > {, <выражение>}) |
writes(<строка>)
writem(<идентификатор>)
<операции над матрицами> ::=
con(<идентификатор>, <идентификатор>, <идентификатор>) |
dis(<идентификатор>, <идентификатор>, <идентификатор>) |
inv(<идентификатор>, <идентификатор>) |
size(<идентификатор>, <идентификатор>, <идентификатор>)
<выражение> ::= <подвыражение> |
<выражение> <знак сравнения> <подвыражение>
<подвыпажение> ::= <слагаемое> |
<подвыражение> <слабый знак> <слагаемое>
<слагаемое> ::= <множитель> |
<слагаемое> <средний знак> <множитель>
<множитель> ::= <сильный знак><множитель> | <число> |
<переменная> | (<выражение>)
<знак сравнения> ::= > | < | = | <> | >= | <=
<слабый знак> ::= + | - | or
<средний знак> ::= * | div | mod | and
<сильный знак> ::= - | not
<переменная> ::= <идентификатор> [[<индекс>, <индекс>]]
<число> ::= [-] <неотрицательное число>
<идентификатор> ::= <буква> {<буква> | <цифра> | _}
<неотрицательное число> ::= <цифра> {<цифра>}
<буква> ::= A | a | B | b | C | c | … | Y | y | Z | z
<цифра> ::= 0 | 1 | 2 | … | 8 | 9
<строка> ::= ‘ {<литера>} ‘
<логическая константа> ::= TRUE | FALSE