Сборка парсера из грамматики во время выполнения - PullRequest
10 голосов
/ 12 сентября 2011

Многие (большинство) библиотек регулярных выражений для C ++ позволяют создавать выражения из строки во время выполнения. Кто-нибудь знает о каких-либо генераторах синтаксического анализатора C ++, которые позволяют вводить грамматику (предпочтительно BNF), представленную в виде строки, в генератор во время выполнения? Все найденные мной реализации либо требуют запуска явного генератора кода, либо требуют, чтобы грамматика была выражена посредством умного метапрограммирования шаблонов.

Ответы [ 5 ]

4 голосов
/ 13 сентября 2011

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

 A = B C D ;

Анализ такого правила с помощью рекурсивного спуска очень прост: вызов подпрограммы, соответствующей поиску B, затем одинкоторый находит C, затем тот, который находит D. Учитывая, что вы выполняете общий анализатор, вы всегда можете вызвать функцию "parse_next_sentential_form (x)" и передать имя нужной формы (терминальный или нетерминальный токен) как x (например, "B", "C", "D").

При обработке такого правила синтаксический анализатор хочет создать A, найдя B, затем C, затем D. Чтобы найти B (или C или D), вы хотели бы иметь индексированный набор правил, в котором все левые части одинаковы, так что можно легко перечислить правила, производящие B, и вернуться к обработке их содержимого.Если ваш парсер получает ошибку, он просто возвращается назад.

Это не будет молниеносным парсером, но не должен быть ужасным, если его правильно реализовать.

Можно также использовать парсер Earley, который анализирует путем создания состояний частично обработанных правил.

Если вы хотите, чтобы это было быстро, я полагаю, вы могли бы просто взять смелость Бизона и превратить его в библиотеку.Затем, если у вас есть грамматический текст или грамматические правила (разные точки входа в Bison), вы можете запустить его и заставить его создавать свои таблицы в памяти (что он должен делать в некоторой форме).Не выплевывайте их;просто создайте механизм синтаксического анализа LR, который их использует.Вуаля, эффективное поколение анализаторов на лету.Если вы делаете это, вам нужно беспокоиться о неясностях и LALR (1) вашей грамматики;предыдущие два решения работают с любой контекстно-свободной грамматикой.

1 голос
/ 02 апреля 2014

Я только что натолкнулся на это http://cocom.sourceforge.net/ammunition++-13.html
Последний из них - парсер Эрли, и он, кажется, воспринимает грамматику как строку.
Одна из функций:

Открытая функция `parse_grammar '

         `int parse_grammar (int strict_p, const char *description)'

- это еще одна функция, которая настраивает синтаксический анализатор на данную грамматику.Грамматика задается строкой "описание".Описание похоже на YACC one.

Фактический код: http://sourceforge.net/projects/cocom/

РЕДАКТИРОВАТЬ

Более новая версия - https://github.com/vnmakarov/yaep

1 голос
/ 13 сентября 2011

Самый простой вариант - встроить некоторый язык сценариев или даже полноценную виртуальную машину (например, Mono) и запустить над ней сгенерированные парсеры.Lua имеет довольно мощный JIT-компилятор, приличные возможности метапрограммирования и несколько готовых к использованию реализаций Packrat, так что, вероятно, это будет наименьшим усилием.

1 голос
/ 13 сентября 2011

Я не знаю о существующей библиотеке для этого.Однако, если производительность и надежность не являются критическими, вы можете раскрутить бизон или любой другой инструмент, который генерирует код C (через popen (3) или аналогичный), раскрутить gcc на сгенерированном коде, связать его с общей библиотекой и загрузить библиотеку.через dlopen (3) / dlsym (3).В Windows - DLL и LoadLibrary () вместо этого.

0 голосов
/ 13 сентября 2011

boost :: spirit - это среда синтаксического анализа C ++, которая может использоваться для динамического создания синтаксических анализаторов во время выполнения.

...