我的一个程序在运行时接受命令(如 kill foo
)。将其视为一种特定领域的小语言。下面是几个例子:
kill
kill client
exit
而且,链式命令是允许的,命令前后的空格不重要,所以下面的例子也是有效的:
kill ; say "that was fun"
kill ; kill ; kill;
我目前已经用 lex/yacc(具体来说是 flex/bison)实现了这个,这引起了很多麻烦。词法分析器在很大程度上取决于上下文(例如通常不返回空白标记,除非在 kill
关键字之后)并且有许多不同的状态。语法曾经有冲突,我真的不喜欢必须指定它的格式(尤其是 $1、$2、$3 ……使用非终结符的参数)。此外,bison 提供的错误消息(在解析时)有时是准确的,但通常不准确(带有可选参数的 kill
命令会导致错误消息,如 Unexpected $undefined, expected $end或 ;
用于 kill clont
而不是 kill client
)。最后,yacc 的 C API 是残酷的(到处都是外部定义)。
我并不是要你解决所有上述问题(如果没有办法绕过 lex/yacc,我将打开单独的线程,提供更具体的描述和代码)。相反,我对 lex/yacc 的替代品很感兴趣。
我的标准如下:
- 输入是一个字符串 (const char *),没有输出,而是应该为每个不同的关键字调用一些代码。
- 我想将其用于 C (C99)。
- 该软件应该已经包含在主要的 Linux 发行版中,或者至少易于捆绑/打包。
- 应妥善记录。
- 描述我的语言的语法应该很简单。
- 它应该在解析错误时输出有意义的错误消息。
- 性能并不是那么重要(当然它应该很快,但典型的用例是交互式使用,而不是处理大量命令)。
最佳答案
至于一个非常简单和小的语法,我会考虑手动编写词法分析器/解析器——通常工作量不大。
几乎所有的 linux 发行版都提供了 lex/yacc 的变体。除此之外,另外两个广泛使用的解析器生成器是 lemon和 antlr .
关于c - 在 C 语言中解析 DSL 比 lex/yacc 更好的解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6011321/