15

有没有办法覆盖 Java 中的行号(例如,通过使用某种预处理器指令)?

我正在“编译”一种高级语言,使用 Janino 编译成 Java 字节码。我需要编译器错误来报告原始文件中的行,而不是生成的 Java 代码。

C# 有#line 指令,我已经成功地利用它来将源文件中的行号映射到编译结果。我需要同样的Java。

谢谢!

4

5 回答 5

10

我从未见过它用于除 JSP 之外的其他用途,但JSR-45旨在用于任何源语言的此目的。该过程涉及以特殊格式(“SMAP”)创建第二个文件,该文件将原始源代码中的行号映射到生成的 Java 源代码中的行号。

于 2009-02-10T03:25:47.933 回答
4

不幸的是,不,Java 中没有等效的#line指令。您可以做的最好的事情是通过删除/插入换行符以匹配真实源代码(或修改代码生成器)在生成源代码后对其进行修改。或者,您可以在编译后修改二进制类文件中存储的行号,但这可能会更加痛苦。

于 2009-02-10T03:13:15.297 回答
4

使用 Janino,您可以派生Scanner并覆盖该location()方法。此方法返回一个 Location 对象。您可以重写该read()方法以查找注释,例如在注释中(在代码生成期间添加),这些注释包含行号信息。

您只需将扫描仪传递SimpleCompiler.cook()方法,您就可以控制报告错误的文件名、行和列。

于 2009-03-15T13:04:54.547 回答
3

您可以尝试使用 JVM 汇编器,而不是生成 Java 代码作为中间语言。Jasmin的语法很好,您可以在代码中的适当位置随意插入 .line 指令。您还可以使用 .source 指令指定原始源文件。

诚然,走汇编路线可能比它的价值更麻烦:)

于 2009-02-10T10:01:50.570 回答
1

没有简单的解决方案。一种解决方法是在生成代码时生成从 [您的语言] 到 Java 的行号映射。您可以管道编译器输出并使用映射将 Java 的行号替换为您的行号。

于 2009-02-10T03:18:23.100 回答