Генератор LL(1) таблицы
Всего лишь мелкая проба пера)). Поэтому не ждите хорошего исполнения или подробного описания.
Так что перейду сразу к делу :
- lex3.cpp сам генератор
- 3.lex грамматика генератора
- x.test тестовый файл генератора
- 1.pas исходный файл паскаля
- syn.cpp препроцессор, который строил тестовый файл
syn.cpp
написан несколько глуповато. Был выдран из какой-то моей программы и наспех переправлен под другие нужды.
x.text
приблизительно описывает язык паскаль. Во первых я вполне мог что-то упустить из виду. Во вторых функции типа
length, close, delete в грамматике не нужны, их лучше определить отдельным списком. В третьих не удалось сделать такую важную
вещь, как возврат значения функции с помощью <имя функции> := <value>. Вместо этого значение возвращается с помощью
return (в стиле gnu pascal) , или с помощью зарезервированной переменной result:=<value> Причина кроется в конфликте двух
конструкций 1) возврат значения FuncName:=value и 2) и вызове FuncName(1,2,3); Одновременно два этих понятия в класс LL(1) грамматик
не вписываются.
Формат файла очень простой. Допустим в нас есть грамматика:
В файле она будет записана вот так:
Т.е. пробелы везде где можно - обязательны, точка в конце файла обязательна. | - это или. Надеюсь больше ничего объяснять не нужно.
Обозначения
- ID - имя переменной и т.п.
- STR - строка в кавычках
- NUM - целое число
- PID - имя функции
Есть ещё одно но. Вместо простых типов переменных надо было внести только один тип var-type , а уже под само
это определение подогнать список типов. И всё ради того чтобы я мог задавать новые типы с помощью оператора type.
Но это у меня в данном примере не работает.
lex3.cpp
Собственно сам генератор. Прошу не судить строго, потому что STL я знаю не слишком хорошо и доводить эту
штуку до ума особенно не старался.
О файлах
- FILENAME_GR (3.lex) - входная грамматика для теста
- FILENAME_TST (x.test) - входной файл для проверки парсера
- FILENAME_NEW (new_Gr.txt) - результат рабочего преобразования грамматики
- FILENAME_ERR (error.log) - лог ошибок (в него помойму ничего не заносится)
- FILENAME_TAB (table.txt) - сама сгенерированная таблица (можно загрузить в Excel)
- FILENAME_SET (set.txt) - найденые first, follow множества
- FILENAME_XML (dump.xml) - дерево в результате парсинга (бред бесполезный)
- FILENAME_LOG (log.txt) - токены которые прошли через парсер в процессе работы
Немного о генерации множеств. В данном случае , для того чтобы избежать возможных сбоев или зацикливанний в программе
я пошёл простым путём. Вместо явного применения правил, программа просто линейно проходит по списку продукций
тихо применяя допустимые правила. Затем процесс повторяется снова, до тех пор пока во множествах не прекращаются
изменения. В данном примере на грамматику паскаля тратится около 6 проходов (время одного прохода фактически линейное).