Описание. Базовые типы данных
Имеются несколько базовых типов данных: 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 могут иметь только два значения: True и False. Над ними определены операции Or (или), And (и), Not (не).


Кроме того, над всеми базовыми типами определены операции сравнения ("<", ">", "=", "<=", ">=", "<>"), которые возвращают результат типа Boolean. При этом False<True
 

Конструкторы типов
Из описанных базовых типов мы можем конструировать новые типы при помощи следующих конструкторов типов:

<тип> ::= <имя типа> | <имя базового типа> | <ограниченный тип> | <перечислимый тип> | <тип-последовательность> | <тип-множество> | <тип-выражение>

Здесь:

  1. <имя типа> – это идентификатор типа, который может быть определен как до, так и после данного описания

  2. <перечислимый тип> ::= (<идентификатор 0> {,<идентификатор i>}) (i = 1,...,N)


По этому описанию заводится N+1 константа с указанными идентификаторами и им ставятся в соответствие значения от 0 до N по порядку. Константами данного типа являются только указанные идентификаторы. Возможны следующие операции над константами перечислимого типа:

  • операции сравнения (константы перечислимого типа сравниваются как соответствующие им числовые значения)

  • Ord(<идентификатор>) – возвращает значение (типа Integer), соответствующее константе

  • Pred(<идентификатор>) – возвращает предыдущую константу этого типа (Pred(<идентификатор 0>)=<идентификатор N>)

  • Succ(<идентификатор>) – возвращает следующую константу этого типа (Succ(<идентификатор N>)=<идентификатор 0>)
     

  1. <ограниченный тип> ::= <значение 1>..<значение 2>
    Здесь <значение 1> и <значение 2> – константы одинакового типа, который может быть одним из следующих: Integer, Char, Boolean, либо каким-то из <перечислимых типов>. Если <значение 1>
    <значение 2>, то константы <ограниченного типа> могут принимать любое значение из промежутка [<значение 1>,<значение 2>]. Иначе множество констант этого типа пусто. Над константами <ограниченного типа> допустимы те же операции, что и над константами того типа, которому принадлежат <значение 1> и <значение 2>

  2. <тип-последовательность> ::= Sequence Of <тип> | Sequence (<поле> {, <поле>})
    <поле> ::= [Optional] <тип>

    Константами <типа-последовательности>, описанного как Sequence Of <тип>, являются конечные последовательности констант типа <тип>. Константами <типа-последовательности>, описанного как Sequence (<поле> {, <поле>}), являются упорядоченные наборы из констант указанных типов (в том порядке, в котором они встречаются в описании). Однако при этом можно опускать те элементы, перед типами которых указано ключевое слово Optional. Константы <типа-последовательности> записываются следующим образом: {<Константа> {, <Константа>}}. Пустая последовательность обозначается символами "{ }"

    Над <типами-последовательностями> определена операция конкатенации <тип 1>@<тип 2>, результатом которой является новый тип, все константы которого получаются дописыванием к произвольной константе-последовательности <типа 1> справа константы-последовательности <типа 2>. К образованным таким способом новым типам опять можно применять операцию конкатенации

    Аналогично, операция конкатенации определена и для констант рассматриваемых типов. Кроме того, если для констант каждого из типов из описания <типа-последовательности> определена некоторая операция, то такая же операция, действующая поэлементно, определена и над константами этого <типа-последовательности> одинаковой длины. Например, {1,'a'}+{2,'b'}={3,'ab'}
     

  3. <тип-множество> ::= [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}
     

  4. <тип-выражение> ::= <тип>@<тип> | <тип> Plus <тип> | <тип> Minus <тип> | <тип> Mul <тип>. Определения этих операций см. выше



Структура программы
Программа на языке DDL (Data Description Language) имеет следующую структуру:

<программа> ::= <предложение> {; <предложение>}
<предложение> ::= <описание типа> | <описание константы> | <пусто>
<пусто> ::=
<описание типа> ::= Define type <имя типа> = <тип>
<описание константы> ::= Define constant <имя константы> = <выражение>
<имя типа> ::= <идентификатор>
<имя константы> ::= <идентификатор>

Здесь <выражение> – это корректно записанное с помощью допустимых операций, операндов и круглых скобок выражение, значение которого присваивается константе

<Идентификатор> – это непустая последовательность символов, состоящая из больших и маленьких латинских и русских букв, цифр и знаков ".", "$", "_", "?", которая удовлетворяет следующим требованиям:

  • идентификатор не может начинаться с цифры

  • точка может быть только первым символом идентификатора

  • длина идентификатора – любая, но значащими являются только первые 8 символов

  • идентификатор не может совпадать ни с одним из ключевых слов, описанных выше


Большие и маленькие буквы в тексте программы не различаются. Ни один из идентификаторов (в т.ч. идентификаторы констант перечислимых типов) не описывается дважды. Там, где допустим один пробел (перевод строки), допустимо любое количество пробелов и переводов строки

Комментарий – это последовательность символов любой длины, начинающаяся с символов "//" и заканчивающаяся символами перевода строки. Комментарии могут располагаться в любом месте программы и должны опускаться при разборе.

Задача
Во входном файле находится программа на языке DDL, содержащая описания типов данных и констант. Длина программы не превышает 60 килобайт, а общее число идентификаторов в ней не более 100. Требуется написать программу, которая:

  1. проверяет заданное описание на наличие ошибок и при наличии таковых выводит соответствующее сообщение в выходной файл

  2. если ошибок не обнаружено, то выводит в выходной файл все константы из исходной программы (определенные оператором Define constant) с указанием для каждой из них ее имени, списка имен возможных типов для этой константы и ее значения по формату: <имя константы>: <тип 1> {, <тип>} = <значение>

  3. если ни одного допустимого типа для заданной константы нет, то вместо списка возможных типов должен идти конструктор, описывающий любой из типов, соответствующих этой константе.
    Имена констант и имена типов должны быть выведены строчными буквами. Имена констант должны следовать в алфавитном порядке (сначала цифры, потом по порядку буквы английского, затем русского алфавитов)



Например:

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



Список ключевых слов

Integer
Char
Boolean
String
True
False
Or
And
Not
Sequence
Set
Multi
Of
Optional
Plus
Minus
Mul
Ord
Chr
Pred
Succ
Mod
Define
Constant
Type


 Приоритеты операций

Not  +  -
*  /  Mod  And  Mul 
+  -  Or  @  Plus  Minus
<  >  =  <=  >=  <>

унарные
мультипликативные
аддитивные
сравнения

Высший


Низший






Комментарии

Для решения задачи необходимо владеть темами: синтаксический анализ, динамическое программирование, алгоритмы на графах



Решение
Авторское решение не представлено
 


© Особенности национальных задач по информатике