2012-05-27 51 views
4

我使用antlr將自定義語言翻譯爲C++代碼。 用這種語言,用戶可以在$code...$endcode指令之間嵌入C++代碼片段,這些代碼片段按照原樣插入到翻譯後的C++代碼中。使用antlr和行指令插入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++

+0

我只是檢查生產(使用C目標)是什麼ANTLR - 它似乎沒有在嵌入代碼中插入任何行指令。它只是將源的文件名和行號插入註釋 –

+0

爲什麼你想要將文件和行號設置爲*翻譯*文件? –

+0

我想這樣做,使這些代碼片段中的調試更容易。用戶應該更正來源,而不是自動生成的代碼。我知道這會使得必須始終使用自動生成的代碼來分發源文件,但在我的應用程序中,不需要維護自動生成的代碼。它立即編譯,並使用可執行文件。 –

回答

1

它不是從問題明確了類似的話,但你產生#line指令給自己和source-linesource-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 
+0

感謝您的回答。儘管如此,我很想知道是否有一種方法可以將__LINE__'恢復爲其實際值,然後使用#line指令進行更改。 –

+1

我不確定有沒有辦法。你想要的是在'$ code'塊的開始處評估'__LINE__'並將結果傳遞給預處理器。但PP使用延遲評估,只在生成代碼或使用表達式作爲條件時進行評估。代碼生成是無用的,因爲你不能生成指令。條件編譯是無用的,因爲'__LINE__'將在hack內的'#if'的位置進行評估,而不是與$ code相同的文件。所以對我來說這看起來不可能。 – Potatoswatter

+0

謝謝。猜猜我將不得不堅持在文件之間手動跳轉以進行調試。 –