我希望从一段文本中提取信息并进行查询。
这段文本的结构由BNF语法(或其变体)指定,提取的信息在运行时指定(查询语法目前不重要)。
所以,要求非常简单:
- 接收一些结构化的文本 - 使用语法分析器将其加载为可利用的形式 - 运行查询以选择其中的某些部分
举个例子,假设我们有这样的语法(使用自定义的BNF格式):
这段文本的结构由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语法转换为解析器并“即时”产生结构化的内存输出,使用此解析器从文本体中获取内容?
编辑:我对其他替代方案也很开放。目前的想法是,也许正则表达式可以允许此提取,但是由于语法的复杂性,这可能会很快变得混乱,并且因此维护正则表达式将是一项相当可怕的任务。此外,通过分离语法和提取,我希望能够重用同一语法以满足不同的提取需求,而不是每次都有略微不同的正则表达式。