Я хотел бы извлечь информацию из текста и иметь возможность запрашивать ее.
Структура этого текста будет определяться грамматикой БНФ (или ее вариантом), а извлекаемая информация будет указываться во время выполнения (синтаксис запроса в данный момент не имеет значения).
Итак, требования просты, на самом деле:
- Получите структурированный текст
- Загрузите его в пригодной для эксплуатации форме, используя грамматику для его анализа.
- Запустите запрос, чтобы выбрать некоторые его части
Чтобы проиллюстрировать пример, предположим, что у нас есть такая грамматика (в настроенном формате BNF):
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<id> ::= 15 * digit
<hex> ::= 10 * (<digit> | a | b | c | d | e | f)
<anything> ::= <digit> | .... (all characters)
<match> ::= <id> (" " <hex>)*
<nomatch> ::= "." <anything>*
<line> ::= (<match> | <nomatch> | "") [<CR>] <LF>
<text> ::= <line>+
Для чего такой текст будет соответствовать:
012345678901234
012345678901234 abcdef0123
Nor the previous line nor this one would match
И затем я хотел бы перечислить все теги, которые появляются в правиле, например, используя синтаксис, подобный XPath:
match//id
который вернет список.
Это звучит относительно просто, за исключением того, что у меня есть два больших ограничения:
- грамматика BNF должна быть прочитана во время выполнения (из структуры, подобной строке/вектору)
- запросы также будут считываться во время выполнения
Некоторые уточнения:
- ожидается, что грамматика не будет часто меняться, поэтому шаг «компиляции» для создания структуры в памяти приемлем (и, возможно, необходим для достижения хорошей скорости)
- главное скорость, бонусные баллы за оперативный сбор нужных порций
- бонусные баллы за возможность иметь обратные вызовы для устранения неоднозначности (иногда, например, для необходимой информации об устранении неоднозначности может потребоваться доступ к БД)
- бонусные баллы за составные грамматики (в пользу модульности и повторного использования элементов грамматики)
Я знаю, например, lex/yacc и flex/bison, однако они, похоже, создают только код C/C++ для компиляции, а это не то, что мне нужно.
Знаете ли вы о надежной библиотеке (желательно бесплатной и с открытым исходным кодом), которая может преобразовать грамматику BNF в синтаксический анализатор «на лету» и создать структурированный вывод в памяти из основного текста с помощью этого синтаксического анализатора?
EDIT: я открыт для альтернатив. На данный момент идея заключалась в том, что, возможно, регулярные выражения могли бы позволить такое извлечение, однако, учитывая сложность задействованных грамматик, это может быстро стать уродливым, и, таким образом, поддержка регулярных выражений станет довольно ужасной задачей. Кроме того, разделяя грамматики и извлечение, я надеюсь, что смогу повторно использовать одну и ту же грамматику для разных нужд извлечения, а не каждый раз иметь немного разные регулярные выражения.