У меня есть файл, который содержит грамматику ABNF с тегами, как в этом упрощенном примере:
$name = Bertha {userID=013} | Bob {userID=429} | ( Ben | Benjamin ) {userID=265};
$greet = Hi | Hello | Greetings;
$S = $greet $name;
Теперь задача состоит в том, чтобы получить идентификатор пользователя, анализируя данное предложение для этой грамматики. Например, разбор предложения
Greetings Bob
должен дать нам идентификатор пользователя 429. Грамматики должны быть прочитаны во время выполнения, потому что они могут меняться между запусками.
Мой подход на данный момент заключается в следующем:
разбить грамматику на одно или несколько деревьев, поместив теги на листья или узлы, к которым они принадлежат
проанализируйте предложение с этим / этим деревом (ами), чтобы построить дерево, которое создает данное предложение (я думаю об использовании Эрли для этого)
использовать это дерево для получения тегов (в отличие от примера в таком дереве будет несколько разных тегов)
Мой вопрос: есть ли программные компоненты, которые я могу использовать или, по крайней мере, изменить для решения этой задачи? В особенности шаги 1 и 2 кажутся достаточно общими (1. чтение грамматики ABNF во внутреннее представление C ++ (например, деревья); 2. ранний алгоритм (или что-то в этом роде), работающий с внутренним представлением из 1.) и написание полный, безошибочный парсер ABNF для шага 1 будет для меня действительно трудоемкой задачей.
Я знаю, что грамматики VoiceXML работают так, но я не смог найти для них парсер. По сути, все, что я мог найти, это генераторы парсеров, которые будут генерировать код C ++ для одной грамматики, что для меня не практично, поскольку грамматики не известны во время компиляции.
Есть идеи?
Еще в 2001 году я написал библиотеку C ++, которая будет генерировать парсер из правил, указанных во время выполнения. Это доступно на SourceForge как проект BuildParse с лицензией LGPL. Я использовал его в нескольких других проектах, и я обновил его для работы с C ++ с 2009 года. Если не имеет значения, работает ли парсер быстро, он может сработать для вас или сэкономит вам часть работы.
По сути, вам понадобится парсер, чтобы разобрать вашу грамматику в структурах данных, которые использует buildparse (вы также можете использовать buildparse для этого), а затем запустить генератор парсера buildparse, чтобы сгенерировать что-то, способное распознавать токены.