c++ - 词法和语法分析器软件

标签 c++ yacc flex-lexer analyzer lexical

我正在设计基于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等...)。

您对要使用的工具/库有什么建议?

最佳答案

如果您希望多次执行此类操作,请学习如何使用解析器生成器。从长远来看,它将为您节省很多痛苦。

从简单开始。这些工具将为您做很多事情,并且通常只需很少的精力。让他们那样做。在尝试做复杂的事情之前,先让事情做好。

其余部分假定您将使用flexbison(它们是lexyacc相似)。有很多选择。如果您决定尝试其他方法之一,请忽略此答案的其余部分。

但是flexbison是可靠的,维护良好的,调试良好的软件包,带有大量文档,并且已经被长期使用。首先阅读文档。

  • flex将自动从标准输入或提供的文件描述符中读取。让它做到这一点。
  • flex将为您跟踪行号。让它做到这一点。
  • bison将自动为您生成 token 编号。让它做到这一点。
  • bisonflex针对单字符 token 进行了优化。您不仅不需要提供 token 编号,甚至不需要提供 token 名称。在flex文件中,只需将其放在末尾即可:
    . { return yytext[0]; }
    

    并且不必费心编写规则来处理单字符 token 。不必担心会标记非法字符。 bison将为您生成一条错误消息。
  • 但是,不允许flex插入默认规则。 (%option nodefault足以抑制它。)

  • 其他一些技巧:
  • 即使yytext是全局的,也要假装它不是全局的。您必须复制进一步处理所需的任何字符串。 strdup是你的 friend ;使用它而不是搞乱mallocstrcpy。也使用asprintf; char* out; asprintf(&out, "%s%s%s", s1, s2, s3);是连接三个字符串的最简单方法。对于没有这些功能的平台,可以轻松获得不受限制的实现,因此不必担心“但它们不是Posix / Standard C / yadda yadda yadda”参数。而且甚至不用考虑固定长度的缓冲区。您不需要它们。诚实。
  • 另一方面,如果可以在扫描仪中处理 token ,请在此处进行处理。例如数字;在扫描器中执行一次strtol更加容易,然后您甚至无需考虑内存分配。
  • 当您不再需要free()字符串时,请不要忘记,但是如果发现困难首先从泄漏内存开始,然后在解析器工作之后修复问题。 (我知道有些人会觉得这很不礼貌,但是只要您记得在生产前就这么做了,那就很好了;一旦掌握了基础知识,就会感到更有动力。)

  • 最后:
  • 使用合理的最新版本的bison。如果发现自己遇到神秘的移位/减少冲突,请使用glr解析器:是的,它的速度稍慢一些,但是如果可以减轻您的痛苦,那是值得的。您随时可以返回并稍后进行修复。 (GLR解析器不会使您摆脱所有语法问题。您仍然需要确保语法没有歧义。但是它们可以提供帮助。)
  • 我的个人建议:使用C接口(interface)。可以使用C++进行编译,并且可以使用标准的C++容器和其他不错的功能。只是不要在您的语义值中使用它们,因为bison的内部堆栈管理不能很好地发挥作用。 (不过,指向C++容器的指针就可以了。)请记住flexbison只是控制流;程序的大部分将用C / C++编写,因此您不会通过使用编译器工具进入一个新的世界。您还没有获得免费通行证:开始编写解析器之前,您需要了解如何使用C / C++。

  • 希望能有所帮助。祝好运。

    关于c++ - 词法和语法分析器软件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25604940/

    相关文章:

    c - Flex - 在 C 中比较字符串的函数

    c++ - Qt如何申请管理员权限?

    android - 没有适用于 Android 的 Qt 控件样式吗?

    c++ - 指针和静态和新对象

    java - 检测图像中的物体(单词)

    c - Yacc/Flex 中的移位/减少冲突

    error-handling - 如何在Bison中防止默认 “syntax error”

    bison - 如何管理相互递归,并保留关联性规则?

    windows - 无法识别的 %option bison-bridge with flex 2.5.4

    c - Bison和Flex到达EOF时不会停止,只说 "Reading a token:"并等待输入