5

我正在使用 antlr 将自定义语言翻译成 C++ 代码。在这种语言中,用户可以在指令之间嵌入 C++ 代码片段$code...$endcode,并按原样插入到翻译后的 C++ 代码中。

我有以下问题:当代码片段中有错误时,我希望编译器指向源文件而不是翻译后的 C++ 代码。

我尝试如下使用行指令,但它不起作用:

"foo.custom_laguage"
1 $code
2 ...some c++ code...
3 $endcode

被翻译成

"auto-generated.cpp"
42 #line 2 "foo.custom_language"
43 ...some c++ code...
44 #line __LINE__ __FILE__

我认为这不起作用,因为#line 指令修改了__LINE__稍后由宏写入的内容。如何将行号设置回翻译后的 C++ 代码中的实际行号?antlr 是如何做到这一点的?

这是我希望自动生成的代码的样子:

"auto-generated.cpp"
42 #line 2 "foo.custom_language"
43 ...some c++ code...
44 #line 44 "auto-generated.cpp"  //actual line in this file
45 ..some more C++ code ...

编辑: 我刚刚发现有一种方法可以通过使用#line default指令在 C# 语言中执行此操作:http: //msdn.microsoft.com/en-us/library/34dk387t.aspx 但找不到任何类似的 C++

4

1 回答 1

1

从问题中不清楚,但是您正在生成#line自己给出的指令source-line,并且source-file?对不起,我对 Antlr 不熟悉。

实际上,除了将宏#line __LINE__ __FILE__分配给自身之外什么也不做。__LINE__

由于预处理器的求值语义,您不能轻易地将数值赋给__LINE__宏。(你只能定义一个新的宏来映射到宏__LINE__,返回它的当前值。)但是你为什么需要它呢?除非 Antlr 本身使用该__LINE__宏,否则您不需要将其恢复为之前的值。

如果这是一个问题,最直接的解决方案是将原始 C++ 代码放在单独include的文件中并放弃内联嵌入。为了防止头文件的扩散,您可以使用类似的构造

$code
#define USE_SNIPPET_FOO
#include "snippets.h"
$endcode

$code
#define USE_SNIPPET_BAR
#include "snippets.h"
$endcode

在标题中,一种反向标题保护:

#ifdef USE_SNIPPET_FOO
#undef USE_SNIPPET_FOO
class foo {};

#elif defined USE_SNIPPET_BAR
#undef USE_SNIPPET_BAR
class bar {};

#else
#error no snippet selected
#endif
于 2012-05-27T08:52:41.347 回答