繁体   English   中英

在运行时从语法构建解析器

[英]Build parser from grammar at runtime

C ++的许多(大多数)正则表达式库允许在运行时从字符串创建表达式。 是否有人知道任何允许在运行时将表示为字符串的语法(最好是BNF)输入生成器的C ++解析器生成器? 我发现的所有实现都需要运行显式的代码生成器,或者需要通过聪明的模板元编程来表达语法。

建立一个接受语法作为输入的递归下降,回溯解析器应该很容易。 您可以将所有规则简化为以下形式(或按照您的方式行事):

 A = B C D ;

通过递归下降来解析这样的规则很容易:调用一个例程,该例程对应于找到一个B,然后一个例程找到一个C,然后一个例程找到一个D。给定您正在执行的通用解析器,您始终可以调用“ parse_next_sentential_form( x)”函数,并将所需形式的名称(终止或非终止令牌)作为x传递(例如“ B”,“ C”,“ D”)。

在处理这样的规则时,解析器希望通过找到B,然后是C,然后是D来产生A。要找到B(或C或D),您希望有一组索引的规则,其中所有左侧相同,因此可以轻松枚举B生成规则,然后递归处理它们的内容。 如果您的解析器失败,它只会回溯。

这不会是一个闪电般的快速解析器,但如果实施得当,也不应该太糟糕。

人们还可以使用Earley解析器,该解析器通过创建部分处理的规则的状态进行解析。

如果您希望它快一些,我想您可以简单地将Bison的胆量纳入图书馆。 然后,如果您有语法文本或语法规则(Bison的不同入口点),则可以启动它并让它在内存中生成其表(必须以某种形式执行)。 不要吐出来; 只需构建一个使用它们的LR解析引擎即可。 Voila,即时高效的解析器生成。 如果这样做,您将不得不担心歧义和语法的LALR(1); 前两个解决方案适用于任何上下文无关的语法。

我刚刚遇到了这个http://cocom.sourceforge.net/ammunition++-13.html
最后一个是Earley Parser,它似乎将语法作为字符串。
功能之一是:

公共功能`parse_grammar'

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

是另一个将解析器调整为给定语法的函数。 语法由字符串“ description”给出。 描述是类似的YACC之一。

实际代码位于http://sourceforge.net/projects/cocom/

编辑

较新的版本位于https://github.com/vnmakarov/yaep

我不知道这个已有的库。 但是,如果性能和健壮性不是很关键,则可以剥离bison或其他任何生成C代码的工具(通过popen(3)或类似工具),剥离gcc生成的代码,将其链接到共享库中并加载该库通过dlopen(3)/ dlsym(3)。 在Windows上-用DLL和LoadLibrary()代替。

最简单的选择是嵌入一些脚本语言甚至是成熟的VM(例如Mono),然后在其之上运行生成的解析器。 Lua具有相当强大的JIT编译器,不错的元编程功能和数个可以使用的Packrat实现,因此这可能是最省力的方法。

boost :: spirit是一个C ++解析框架,可用于在运行时动态构造解析器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM