有没有办法覆盖 Java 中的行号(例如,通过使用某种预处理器指令)?
我正在“编译”一种高级语言,使用 Janino 编译成 Java 字节码。我需要编译器错误来报告原始文件中的行,而不是生成的 Java 代码。
C# 有#line 指令,我已经成功地利用它来将源文件中的行号映射到编译结果。我需要同样的Java。
谢谢!
有没有办法覆盖 Java 中的行号(例如,通过使用某种预处理器指令)?
我正在“编译”一种高级语言,使用 Janino 编译成 Java 字节码。我需要编译器错误来报告原始文件中的行,而不是生成的 Java 代码。
C# 有#line 指令,我已经成功地利用它来将源文件中的行号映射到编译结果。我需要同样的Java。
谢谢!
我从未见过它用于除 JSP 之外的其他用途,但JSR-45旨在用于任何源语言的此目的。该过程涉及以特殊格式(“SMAP”)创建第二个文件,该文件将原始源代码中的行号映射到生成的 Java 源代码中的行号。
不幸的是,不,Java 中没有等效的#line
指令。您可以做的最好的事情是通过删除/插入换行符以匹配真实源代码(或修改代码生成器)在生成源代码后对其进行修改。或者,您可以在编译后修改二进制类文件中存储的行号,但这可能会更加痛苦。
使用 Janino,您可以派生Scanner
并覆盖该location()
方法。此方法返回一个 Location 对象。您可以重写该read()
方法以查找注释,例如在注释中(在代码生成期间添加),这些注释包含行号信息。
您只需将扫描仪传递给该SimpleCompiler.cook()
方法,您就可以控制报告错误的文件名、行和列。
您可以尝试使用 JVM 汇编器,而不是生成 Java 代码作为中间语言。Jasmin的语法很好,您可以在代码中的适当位置随意插入 .line 指令。您还可以使用 .source 指令指定原始源文件。
诚然,走汇编路线可能比它的价值更麻烦:)
没有简单的解决方案。一种解决方法是在生成代码时生成从 [您的语言] 到 Java 的行号映射。您可以管道编译器输出并使用映射将 Java 的行号替换为您的行号。