使用 Lex/yacc 扫描具有特定 header 的文件数量的最佳方法?
best way to scan number of files with a specific header using Lex/yacc?
我使用 yacc.My 语言定义了自己的语法,使用户可以灵活地在调用编译器时显式提供额外的 header,这将适用于使用我的编译器编译的每个文件。
我可以想到两种解决方案来处理这种情况。
1.Append header 到每个文件并编译每个文件 separately.This 不是一个好主意,因为它涉及编辑给定的源文件,这是必要的追加文件开头。
2.Use yywrap 遍历要编译的文件列表并在每次找到新文件时处理 header。
这不好,因为它涉及对同一文件的重复解析。
不处理header,文件不满足语法。
请分享想法,如何以最佳方式完成?
如果您的编译器打算独立编译多个文件,而不是简单地将它们连接起来并将它们编译为一个单元,并且每个输入文件都需要头文件,那么您别无选择,只能包含它在每个输入文件的处理过程中。您可以使用 yywrap
机制,或使用 yy_create_buffer
和 yy_switch_to_buffer
显式切换缓冲区。有关详细信息和示例代码,请参阅 flex manual。
正如您所指出的,该解决方案涉及为每个输入文件重新解析头文件,这可能很耗时。
如果您的解析除了创建 AST 之外没有其他作用,稍后会对其进行处理以生成编译输出或其他分析,那么您可以通过为头文件创建一次 AST 来提高此过程的效率,然后通过从头文件的 AST 副本开始为每个输入文件构建 AST。
您甚至可以序列化头文件的 AST,然后读取序列化版本而不是重新解析它,尽管这样您将需要一些逻辑来验证序列化 AST 是否对应于最新版本的头文件。这种机制(例如precompiled-headers) is implemented in different forms by a number of C/C++ compilers (gcc, clang, Visual Studio)。
我使用 yacc.My 语言定义了自己的语法,使用户可以灵活地在调用编译器时显式提供额外的 header,这将适用于使用我的编译器编译的每个文件。
我可以想到两种解决方案来处理这种情况。
1.Append header 到每个文件并编译每个文件 separately.This 不是一个好主意,因为它涉及编辑给定的源文件,这是必要的追加文件开头。
2.Use yywrap 遍历要编译的文件列表并在每次找到新文件时处理 header。 这不好,因为它涉及对同一文件的重复解析。
不处理header,文件不满足语法。
请分享想法,如何以最佳方式完成?
如果您的编译器打算独立编译多个文件,而不是简单地将它们连接起来并将它们编译为一个单元,并且每个输入文件都需要头文件,那么您别无选择,只能包含它在每个输入文件的处理过程中。您可以使用 yywrap
机制,或使用 yy_create_buffer
和 yy_switch_to_buffer
显式切换缓冲区。有关详细信息和示例代码,请参阅 flex manual。
正如您所指出的,该解决方案涉及为每个输入文件重新解析头文件,这可能很耗时。
如果您的解析除了创建 AST 之外没有其他作用,稍后会对其进行处理以生成编译输出或其他分析,那么您可以通过为头文件创建一次 AST 来提高此过程的效率,然后通过从头文件的 AST 副本开始为每个输入文件构建 AST。
您甚至可以序列化头文件的 AST,然后读取序列化版本而不是重新解析它,尽管这样您将需要一些逻辑来验证序列化 AST 是否对应于最新版本的头文件。这种机制(例如precompiled-headers) is implemented in different forms by a number of C/C++ compilers (gcc, clang, Visual Studio)。