Магазинный автомат описывается текстовым файлом следующего содержания:
- На первой строке файла записаны все состояния автомата.
- На второй строке файла записано начальное состояние автомата.
- На третьей строке файла записаны принимающие состояния автомата.
- На четвёртой строке файла записаны конечные состояния автомата.
- На пятой строке файла записаны символы входного алфавита.
- На шестой строке файла записаны символы стекового алфавита.
- Далее идут сколько-то строк с описаниями правил перехода между состояниями
со следующими особенностями:
"AUTOMATA_STATE" 'INPUT_ALPABET' `STACK_ALPHABET` ~ something
- добавление к состоянию автомата перехода по символу исходного алфавита и стекового алфавита с некоторым набором результатов.- Набор результатов представляет из себя сколько-то пар из
"AUTOMATA_STATE"
(состояние автомата, в которое выполняется переход) и`STACK_ALPHABET`
(стековые символы, которые будут добавлены в стек справа налево). Пары разделены альтернативой|
. Значению пустой строки исходного алфавита соответствует словоEPS
, отсутствию удаления / добавления символов из стека соответствует словоNULL
, пустому состоянию стека соответствует словоEMPTY
. - В конце каждой строки, кроме последней, стоит разделитель
,
. При этом строкой в узком смысле является последовательность символов между двумя,
. Таким образом, разрешается писать списки состояний / символов или переходы в многострочном формате. Например, следующие два фрагмента файла эквивалентны:"I" 'love' `multi` ~ "string" `definition`,
"I" 'love' `multi` ~ "string" `definition`,
- Помимо значащих элементов языка, разрешается добавлять комментарии в формате
<COMMENT>
, гдеCOMMENT
состоит из любой последовательности символов ASCII, пробелы внутри комментария важны. Комментарии могут быть вложенными и многострочными. В случае многострочности, каждый переход на новую строку интерпретируется как пробел. В случае вложенности комментариев, весь комментарий проинтерпретируется как строки, разделённые|
, где сначала идёт объединённый комментарий, а затем вложенные в порядке обхода (см. примеры обработки). - Состояниям стека, символам входного алфавита и символам стекового алфавита
соответствуют любые последовательности символов ASCII;
если очень хочется написать в названии
`\`
,"\"
,'\'
,'
,"
или`
, то придётся их экранировать с помощью бэкслэша вот так:\\
,\'
,\"
,\`
. - Гарантируется, что помимо
,
,~
,`
,'
,"
,<>
,|
,EPS
,NULL
иEMPTY
в файле с описанием автомата нет другой специальной лексики. Такие пробельные символы, как' '
,\t
,\r
,\f
и\n
, в общем случае игнорируются.
Лексер реализован с помощью библиотеки ply
на языке Python. Он содержится в файле
pda-lexer.py
. Запускается через консоль в формате:
python3 pda-lexer.py <имя_файла>
где <имя_файла>
- имя файла, в котором содержится грамматика в формате, указанном
выше. После исполнения программы, лексер сохраняет разобранную по токенам грамматику в
файл <имя_файла>.out
.
Пример ввода-вывода доступен в папке lexer-examples
.
Реализована небольшая библиотека, которая помогает конструировать описание магазинных автоматов в заявленном формате. Она умеет добавлять / удалять состояния, добавлять / удалять переходы между состояниями, добавлять комментарии к переходам и сохранять описание в файле в нужном формате.
Материалы конструктора доступны в папке constructor-examples
. Библиотека описана
в файле pda_constructor.py
, пример использования доступен в файле driver.py
.