我正在设计基于CSS-ish(CSS +自定义扩展名)的自定义语言,基本上可以这样工作:
[object.member.value = 5]{
object.member.anothervalue:8
object.member.yetanothervalue:'hello'
object.member.yetyetanothervalue.anothervalue:blue
}
基本上,该语言允许检查某些条件(如果可以嵌套),然后将某些值应用于对象。没有循环。
这将存储在纯文本文件中,并在启动时加载到应用程序(C++)中。
的想法是将该CSS ish文件转换为C++树或类似的树,可以在运行时进行评估。
我正在考虑使用一些词法分析器和标记器(Yacc,Flex,Bison等...)。
您对要使用的工具/库有什么建议?
最佳答案
如果您希望多次执行此类操作,请学习如何使用解析器生成器。从长远来看,它将为您节省很多痛苦。
从简单开始。这些工具将为您做很多事情,并且通常只需很少的精力。让他们那样做。在尝试做复杂的事情之前,先让事情做好。
其余部分假定您将使用flex
和bison
(它们是lex
和yacc
相似)。有很多选择。如果您决定尝试其他方法之一,请忽略此答案的其余部分。
但是flex
和bison
是可靠的,维护良好的,调试良好的软件包,带有大量文档,并且已经被长期使用。首先阅读文档。
flex
将自动从标准输入或提供的文件描述符中读取。让它做到这一点。 flex
将为您跟踪行号。让它做到这一点。 bison
将自动为您生成 token 编号。让它做到这一点。 bison
和flex
针对单字符 token 进行了优化。您不仅不需要提供 token 编号,甚至不需要提供 token 名称。在flex文件中,只需将其放在末尾即可:. { return yytext[0]; }
并且不必费心编写规则来处理单字符 token 。不必担心会标记非法字符。
bison
将为您生成一条错误消息。 flex
插入默认规则。 (%option nodefault
足以抑制它。)其他一些技巧:
yytext
是全局的,也要假装它不是全局的。您必须复制进一步处理所需的任何字符串。 strdup
是你的 friend ;使用它而不是搞乱malloc
和strcpy
。也使用asprintf
; char* out; asprintf(&out, "%s%s%s", s1, s2, s3);
是连接三个字符串的最简单方法。对于没有这些功能的平台,可以轻松获得不受限制的实现,因此不必担心“但它们不是Posix / Standard C / yadda yadda yadda”参数。而且甚至不用考虑固定长度的缓冲区。您不需要它们。诚实。 strtol
更加容易,然后您甚至无需考虑内存分配。 free()
字符串时,请不要忘记,但是如果发现困难首先从泄漏内存开始,然后在解析器工作之后修复问题。 (我知道有些人会觉得这很不礼貌,但是只要您记得在生产前就这么做了,那就很好了;一旦掌握了基础知识,就会感到更有动力。)最后:
bison
。如果发现自己遇到神秘的移位/减少冲突,请使用glr
解析器:是的,它的速度稍慢一些,但是如果可以减轻您的痛苦,那是值得的。您随时可以返回并稍后进行修复。 (GLR解析器不会使您摆脱所有语法问题。您仍然需要确保语法没有歧义。但是它们可以提供帮助。)C
接口(interface)。可以使用C++进行编译,并且可以使用标准的C++容器和其他不错的功能。只是不要在您的语义值中使用它们,因为bison
的内部堆栈管理不能很好地发挥作用。 (不过,指向C++容器的指针就可以了。)请记住flex
和bison
只是控制流;程序的大部分将用C / C++编写,因此您不会通过使用编译器工具进入一个新的世界。您还没有获得免费通行证:开始编写解析器之前,您需要了解如何使用C / C++。 希望能有所帮助。祝好运。
关于c++ - 词法和语法分析器软件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25604940/