2013-12-12 104 views
0

幾天前我開始與antlr一起工作。我想用它來解析c中的#include宏。只包括我的興趣,其他所有部分都是不相關的。在這裏,我寫了一個簡單的語法文件:Antlr不匹配包含宏的'>'

... parser part omitted... 

INCLUDE : '#include'; 
INCLUDE_FILE_QUOTE: '"'FILE_NAME'"'; 
INCLUDE_FILE_ANGLE: '<'FILE_NAME'>'; 

fragment 
FILE_NAME: ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|' ')+; 

MACROS: '#'('if' | 'ifdef' | 'define' | 'endif' | 'undef' | 'elif' | 'else'); 
//MACROS: '#'('a'..'z'|'A'..'Z')+; 

OPERATORS: ('+'|'-'|'*'|'/'|'='|'=='|'!='|'>'|'>='|'<'|'<='|'>>'|'<<'|'<<<'|'|'|'&'|','|';'|'.'|'->'|'#'); 

... other supporting tokens like ID, WS and COMMENT ... 

這個語法歧義產生這樣的時候語句中遇到:

(;i<listLength;i++) 

output: mismatched character ';' expecting '>' 

好像它試圖匹配INCLUDE_FILE_ANGLE,而不是治療「;」作爲運營商。

我聽說有一個運算符稱爲語法謂詞,但我不知道如何在這種情況下正確使用它。

我如何解決Antlr鼓勵的方式中的這個問題?

回答

1

看起來好像沒有太多有關antlr的活動。

無論如何,我想通了。

INCLUDE_MACRO: ('#include')=>'#include'; 
VERSION_MACRO: ('#version')=>'#version'; 
OTHER_MACRO: 
    (
    |('#if')=>'#if' 
    |('#ifndef')=>'#ifndef' 
    |('#ifdef')=>'#ifdef' 
    |('#else')=>'#else' 
    |('#elif')=>'#elif' 
    |('#endif')=>'#endif' 
    ); 

這隻能解決問題的前半部分。其次,不能使用INCLUDE_FILE_ANGLE來匹配#include指令中所需的字符串。 '<'FILE_NAME'''stuffs會產生不明確性,必須將其分解爲詞法分析器中的基本標記或使用更高級的上下文感知檢查。 IM不熟悉以後的技​​術,所以我在解析器規則中寫道的:

include_statement : 
    INCLUDE_MACRO include_file 
    -> ^(INCLUDE_MACRO include_file); 

include_file 
    : STRING 
    | LEFT_ANGLE(INT|ID|OPERATORS)+RIGHT_ANGLE 
    ; 

雖然這個工程,但不可否認長相醜陋。 我希望有經驗的用戶可以用更好的解決方案發表評論。

+0

您被允許接受您自己的答案..... –