我已经使用yacc定义了自己的语法。我的语言让用户可以灵活地在调用编译器时提供额外的头文件,这将适用于使用我的编译器编译的每个文件。
我可以考虑使用两种解决方案来处理这种情况。
1.找到每个文件的标题并分别编译每个文件。这不是一个好主意,因为它涉及编辑在文件开头附加所需的给定源文件。
2.使用yywrap迭代要编译的文件列表,并在每次找到新文件时处理标题。 这不好,因为它涉及重复解析同一个文件。
如果不处理标题,文件就不能满足语法。
请分享想法,如何以最佳方式完成?
答案 0 :(得分:3)
如果您的编译器旨在独立编译多个文件,而不是简单地连接它们并将它们编译为单个单元,并且每个输入文件都需要头文件,那么您别无选择,只能在其中包含它。处理每个输入文件。您可以使用yywrap
机制,或使用yy_create_buffer
和yy_switch_to_buffer
显式切换缓冲区。有关详细信息和示例代码,请参阅flex manual。
正如您所指出的那样,该解决方案涉及为每个输入文件重新解析头文件,这可能非常耗时。
如果您的解析除了创建AST(后来为了生成编译输出或其他分析而处理)之外没有任何效果,那么您可以通过为头文件创建一次AST来提高此过程的效率,并且然后从头文件AST的副本开始为每个输入文件构建AST。
你甚至可以为头文件序列化AST,然后读取序列化版本而不是重新解析它,尽管那时你需要有一些逻辑来验证序列化的AST对应于最新版本的头文件。这个机制(precompiled-headers)由许多C / C ++编译器(例如gcc,clang,Visual Studio)以不同的形式实现。