2013-12-12 70 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

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