Описание. Базовые типы данных Имеются несколько базовых типов данных: Integer, Char, Boolean и String. Константы этих типов записываются следующим образом:Константа типа String – это последовательность (длиной от 0 до 255) символов, заключенная либо в апострофы ('), либо в двойные кавычки ("). При этом, если ограничители – апострофы, то внутри них апостроф удваивается, а кавычка нет. Аналогично, внутри кавычек двойная кавычка удваивается, а апостроф нет. В качестве символов будут использоваться ASCII-символы с кодами от 32 до 255. Единственная допустимая операция над строками – конкатенация (+) Константа типа Char – это константа типа String длины 1. Определена операция Ord(<символ>), возвращающая ASCII-код заданного символа (значение типа Integer), и Chr(<ASCII-код>), возвращающая символ с указанным ASCII-кодом (значение типа Char) Константы типа Integer – целые числа из диапазона [-32768,32767] – записываются в следующей форме (здесь и далее символы "<", ">", "[", "]", "{", "}", набранные курсивом, используются в качестве метасимволов, т.е. относятся к языку формул Бэкуса-Науэра, а не к описываемому языку): <число> ::= [<знак>]<цифра>{<цифра>} <знак> ::= +|- <цифра> ::= 0|1|2|3|4|5|6|7|8|9
Над константами этого типа определены следующие операции: унарные "+" и "-", бинарные "+" (сложение) и "-" (вычитание), а также "*" (умножение), / (целочисленное деление), Mod (остаток от деления нацело)
Кроме того, над всеми базовыми типами определены операции сравнения ("<", ">", "=", "<=", ">=", "<>"), которые возвращают результат типа Boolean. При этом False<True
Конструкторы типов Из описанных базовых типов мы можем конструировать новые типы при помощи следующих конструкторов типов:
<тип> ::= <имя типа> | <имя базового типа> | <ограниченный тип> | <перечислимый тип> | <тип-последовательность> | <тип-множество> | <тип-выражение> Здесь: <имя типа> – это идентификатор типа, который может быть определен как до, так и после данного описания <перечислимый тип> ::= (<идентификатор 0> {,<идентификатор i>}) (i = 1,...,N)
По этому описанию заводится N+1 константа с указанными идентификаторами и им ставятся в соответствие значения от 0 до N по порядку. Константами данного типа являются только указанные идентификаторы. Возможны следующие операции над константами перечислимого типа:
операции сравнения (константы перечислимого типа сравниваются как соответствующие им числовые значения) Ord(<идентификатор>) – возвращает значение (типа Integer), соответствующее константе Pred(<идентификатор>) – возвращает предыдущую константу этого типа (Pred(<идентификатор 0>)=<идентификатор N>) Succ(<идентификатор>) – возвращает следующую константу этого типа (Succ(<идентификатор N>)=<идентификатор 0>)
<ограниченный тип> ::= <значение 1>..<значение 2> Здесь <значение 1> и <значение 2> – константы одинакового типа, который может быть одним из следующих: Integer, Char, Boolean, либо каким-то из <перечислимых типов>. Если <значение 1>≤<значение 2>, то константы <ограниченного типа> могут принимать любое значение из промежутка [<значение 1>,<значение 2>]. Иначе множество констант этого типа пусто. Над константами <ограниченного типа> допустимы те же операции, что и над константами того типа, которому принадлежат <значение 1> и <значение 2> <тип-последовательность> ::= Sequence Of <тип> | Sequence (<поле> {, <поле>}) <поле> ::= [Optional] <тип> Константами <типа-последовательности>, описанного как Sequence Of <тип>, являются конечные последовательности констант типа <тип>. Константами <типа-последовательности>, описанного как Sequence (<поле> {, <поле>}), являются упорядоченные наборы из констант указанных типов (в том порядке, в котором они встречаются в описании). Однако при этом можно опускать те элементы, перед типами которых указано ключевое слово Optional. Константы <типа-последовательности> записываются следующим образом: {<Константа> {, <Константа>}}. Пустая последовательность обозначается символами "{ }" Над <типами-последовательностями> определена операция конкатенации <тип 1>@<тип 2>, результатом которой является новый тип, все константы которого получаются дописыванием к произвольной константе-последовательности <типа 1> справа константы-последовательности <типа 2>. К образованным таким способом новым типам опять можно применять операцию конкатенации Аналогично, операция конкатенации определена и для констант рассматриваемых типов. Кроме того, если для констант каждого из типов из описания <типа-последовательности> определена некоторая операция, то такая же операция, действующая поэлементно, определена и над константами этого <типа-последовательности> одинаковой длины. Например, {1,'a'}+{2,'b'}={3,'ab'} <тип-множество> ::= [Multi] Set Of <тип> | Set (<тип> {, <тип>}) Константами <типа-множества>, описанного как Set Of <тип>, являются конечные множества констант указанного типа <тип>. В случае описания Multi Set Of <тип> это будут конечные мультимножества (т.е. множества, в которых элементы могут повторяться более одного раза) Константами <типа-множества>, описанного как Set (<тип> {, <тип>}) являются конечные мультимножества, полученные взятием произвольных констант указанных в описании типов (по одной константе каждого типа с учетом кратности) Константы <типа-множества> записываются следующим образом: {<Константа> {, <Константа>}}. Пустое множество обозначается символами "{ }" Над <типами-множествами> возможны следующие операции (результатом которых является, как легко заметить, опять некоторый <тип-множество>): Plus (объединение), Minus (разность), Mul (пересечение). Например, константы типа A Mul B – это те (мульти-) множества, которые одновременно являются константами типа A и константами типа B. Эти же операции определены (с учетом кратности элементов) и для констант <типов-множеств>. Например, {1,2,2} Minus {2,3} = {1,2},{3,3,5} Mul {3,5,5} = {3, 5} <тип-выражение> ::= <тип>@<тип> | <тип> Plus <тип> | <тип> Minus <тип> | <тип> Mul <тип>. Определения этих операций см. выше
Структура программы Программа на языке DDL (Data Description Language) имеет следующую структуру:
<программа> ::= <предложение> {; <предложение>} <предложение> ::= <описание типа> | <описание константы> | <пусто> <пусто> ::= <описание типа> ::= Define type <имя типа> = <тип> <описание константы> ::= Define constant <имя константы> = <выражение> <имя типа> ::= <идентификатор> <имя константы> ::= <идентификатор>
Здесь <выражение> – это корректно записанное с помощью допустимых операций, операндов и круглых скобок выражение, значение которого присваивается константе <Идентификатор> – это непустая последовательность символов, состоящая из больших и маленьких латинских и русских букв, цифр и знаков ".", "$", "_", "?", которая удовлетворяет следующим требованиям: идентификатор не может начинаться с цифры точка может быть только первым символом идентификатора длина идентификатора – любая, но значащими являются только первые 8 символов идентификатор не может совпадать ни с одним из ключевых слов, описанных выше
Большие и маленькие буквы в тексте программы не различаются. Ни один из идентификаторов (в т.ч. идентификаторы констант перечислимых типов) не описывается дважды. Там, где допустим один пробел (перевод строки), допустимо любое количество пробелов и переводов строки Комментарий – это последовательность символов любой длины, начинающаяся с символов "//" и заканчивающаяся символами перевода строки. Комментарии могут располагаться в любом месте программы и должны опускаться при разборе. Задача Во входном файле находится программа на языке DDL, содержащая описания типов данных и констант. Длина программы не превышает 60 килобайт, а общее число идентификаторов в ней не более 100. Требуется написать программу, которая:
проверяет заданное описание на наличие ошибок и при наличии таковых выводит соответствующее сообщение в выходной файл если ошибок не обнаружено, то выводит в выходной файл все константы из исходной программы (определенные оператором Define constant) с указанием для каждой из них ее имени, списка имен возможных типов для этой константы и ее значения по формату: <имя константы>: <тип 1> {, <тип>} = <значение> если ни одного допустимого типа для заданной константы нет, то вместо списка возможных типов должен идти конструктор, описывающий любой из типов, соответствующих этой константе. Имена констант и имена типов должны быть выведены строчными буквами. Имена констант должны следовать в алфавитном порядке (сначала цифры, потом по порядку буквы английского, затем русского алфавитов)
Например: DLL.IN Define Constant целое=(23/54); Define Type seq = sequence of integer; // Это комментарий DeFiNe CoNsTaNt abc={12, 12, 14, 'Жюри', 'Жюри'} ; Define Constant cba={6/2,14, 'Жюри'}; Define Type Тип_для_abc1 = sequence (integer, integer, integer, string, string ); Define Type Тип2 = sequence (optional integer, optional integer, optional string); Define Type St=Set (integer, integer, integer, integer, string, string, string) Define Type st2=set (integer, integer, string) Define constant q={{123},{'Жюри'},{}} Define Type Type1=sequence of Тип2
DLL.OUT abc: st, тип_для_abc1, тип_для_abc2 = {12, 12, 14, 'Жюри', 'Жюри'} cba: st, st2, тип2 = {3, 14, 'Жюри'} q: type1 = {{123}, {'Жюри'}, {}} целое: integer = 0
Список ключевых слов
Приоритеты операций
Комментарии Для решения задачи необходимо владеть темами: синтаксический анализ, динамическое программирование, алгоритмы на графах
Решение Авторское решение не представлено
|