Для получения варианта курсового задания введите свою фамилию, затем имя, разделяя их одним пробелом.
Вариант курсового задания для
Написать интерпретатор для учебного языка.
Задача 1. Используя CAIO, выделить лексемы учебного языка.
Для каждой лексемы, кроме пробельных (игнорируемых) символов и комментариев, нужно напечатать на отдельной строке тип лексемы и саму лексему. Тип лексемы выбирается из "резервированное слово", "идентификатор", "операция", "строка", "число", "символ" (скобки, разделитель операторов, запятая). Например, для программы
input b a=bдолжно быть выведено
?резервированное-слово? : "input" ?идентификатор? : "b" ?символ? : "\n" ?идентификатор? : "a" ?операция? : "=" ?идентификатор? : "b" ?символ? : "\n"
Пример решения:
%option lexprint %type <string> ?идентификатор? ?символ? ?резервированное-слово? ?операция? %% input ?резервированное-слово? [a-zA-Z]\w* ?идентификатор? [ \t] ; = ?операция? .|\n ?символ? %%
При запуске программы используйте команду zadacha1.exe -d1 test.txt
Задача 2. Используя CAIO, написать программу для проверки корректности синтаксиса программы на учебном языке.
Задача 3. Добавьте в правила грамматики операторы для построения AST и напишите интерпретатор для учебного языка.
Описание учебного языка
A. Комментарии:
/* текст до */
// текст до конца строки
{ текст до }
REM текст до конца строки
B. Числа:
целые десятичные и
восьмеричные, начинающиеся с префикса 0
шестнадцатиричные, начинающиеся с префикса 0x
шестнадцатиричные, начинающиеся с цифры и заканчивающиеся буквой H
двоичные, состоящие из 0 и 1 и заканчивающиеся буквой B
C. Строки (для оператора вывода):
'текст'
если в строке необходим символ ', он удваивается
Пример: 'It''s sample'
"текст"
если в строке необходим символ ", перед ним ставится \, для символа \ используется комбинация \\
Пример: "Крейсер \"Варяг\""
$текст$
если в строке необходим символ $, он удваивается
Пример: $Pay $$100$
[текст]
если в строке необходим символ ], перед ним ставится \, для символа \ используется комбинация \\
Пример: [текст в [\] ]
Символ перехода на новую строку в строке недопустим, и специального обозначения для него как в С нет.
D. Переменные и регистр резервированных слов:
Идентификатор переменной начинается с буквы, затем идут буквы и цифры, длиной до 10 символов.
Регистр букв в резервированных словах и идентификаторах является существенным.
Идентификатор переменной начинается с буквы или символа _, затем идут буквы, цифры или символ _, длиной до 10 символов
Регистр букв в резервированных словах и идентификаторах игнорируется.
Идентификатор переменной начинается с буквы или символа $, затем идут буквы, цифры или символ $, длиной до 16 символов
Регистр букв в резервированных словах и идентификаторах является существенным.
При использовании для строк символа $ заменить в идентификаторах $ на _ .
Идентификатор переменной начинается с буквы, затем идут буквы, цифры или символ . (точка, не может быть последним символом идентификатора), длиной до 16 символов.
Регистр букв в резервированных словах и идентификаторах игнорируется.
E. Выражения: Операции +, -, *, / и сравнения >, <, =, !=, <=, >=, круглые скобки, операция смена знака -, обычный приоритет
Можно разделить логические и арифметические выражения.
F. Оператор присваивания:
переменная:=выражение
переменная=выражение
PUT выражение IN переменная
выражение->переменная
G. Операторы ввода-вывода:
READ переменная1, переменная2...
WRITE строка1|переменная1 (,|\) строка2|переменная2...
Символ \, используемый вместо , означает вывод новой строки, например:
WRITE 'Координаты:'\x,' ',y
Также символом \ список вывода может завершаться, если необходим переход на новую строку:
WRITE a\
INPUT переменная1, переменная2...
PRINT строка1|переменная1, строка2|переменная2...
После вывода оператором PRINT автоматически печатается символ перехода на новую строку, кроме варианта, когда список выводимых значений заканчивается запятой:
PRINT 'Введите a:',
READ(переменная1, переменная2...)
WRITE(строка1|переменная1, строка2|переменная2...)
WRITELN(строка1|переменная1, строка2|переменная2...)
Оператор WRITELN завершает вывод символом перехода на новую строку, а WRITE - нет.
GET IN переменная1 переменная2...
GET OUT строка1|переменная1|LINE строка2|переменная2|LINE...
Слово LINE используется для вывода перехода на новую строку.
H. Сложные операторы:
Операторы разделяются символом ;
BEGIN операторы END
IF выражение THEN оператор
IF выражение THEN оператор ELSE оператор
WHILE выражение DO оператор
Операторы разделяются концом строки
IF выражение THEN
операторы
ENDIF
IF выражение THEN
операторы
ELSE
операторы
ENDIF
WHILE выражение
операторы
WEND
Операторы разделяются символом ;
IF выражение THEN операторы END
IF выражение THEN операторы ELSE операторы END
WHILE выражение DO операторы END
Операторы разделяются концом строки
IF выражение THEN
операторы
END IF
IF выражение THEN
операторы
ELSE
операторы
END IF
WHILE выражение DO
операторы
END DO
I. Расширения:
Одномерные массивы, которые определяются оператором:
ARRAY имя1[число1:число2], имя2[число1:число2]...
где первое число указывает нижнюю границу индекса массива, второе - верхнюю.
Обращение к элементу: имя[выражение]
Массивы должны объявляться до первого использования. При попытке обращения к массиву как к простой переменной и наоборот должна быть ошибка компиляции.
Массивы и переменные должны храниться в одной области памяти, компилятор должен вычислять адреса переменных и массивов в этой области памяти.
При использовании для строк символов [] заменить в массивах [] на ().
Функции (без рекурсии)
FUNCTION имя(переменная1, переменная2...)
END
Результат функции возвращается через оператор
RETURN выражение
Вызов функции: имя(выражение1, выражение2...)
Глобальные переменные и параметры разных функций, имеющие одинаковые имена, должны хранится в ячейках с разными адресами. При компиляции тела функции идентификатор должен искаться сначала среди параметров функции, а затем среди глобальных переменных.
При попытке обращения к функции как к переменной и наоборот должна быть ошибка компиляции. Также ошибка компиляции должна возникать при вызове функции с неверным количеством параметров.
Одномерные массивы, которые определяются оператором:
DIM имя1(число1), имя2(число2)...
Обращение к элементу: имя(выражение)
Массивы должны объявляться до первого использования. При попытке обращения к массиву как к простой переменной и наоборот должна быть ошибка компиляции.
Массивы и переменные должны храниться в одной области памяти, компилятор должен вычислять адреса переменных и массивов в этой области памяти.
Логические операции && || ! и условная операция выр1?выр2:выр3 как в языке С.
Для тех, кто забыл С: условная операция выглядит так: max := a>b?a:b, а выражения с && и || могут вычисляться частично.