我想从正文中提取信息并能够查询它。
该文本正文的结构将由 BNF 语法(或变体)指定,要提取的信息将在运行时指定(此时查询的语法无关紧要)。
所以要求很简单,真的:
- 接收一些结构化的正文
- 使用语法以可利用的形式加载它来解析它
- 运行查询以选择其中的某些部分
举个例子,假设我们有这样的语法(定制的 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 语法“即时”转换为解析器,并使用该解析器从文本体中生成结构化的内存输出?
编辑:我对替代品持开放态度。目前的想法是,也许正则表达式可以允许这种提取,但是考虑到所涉及的语法的复杂性,这可能会很快变得丑陋,因此维护正则表达式将是一项非常可怕的任务。此外,通过分离语法和提取,我希望能够针对不同的提取需求重用相同的语法,而不是每次都有稍微不同的正则表达式。