Antlr不匹配'>'包括宏

时间:2013-12-12 14:16:29

标签: parsing antlr grammar lexer

几天前我开始使用antlr。我想用它来解析c中的#include宏。只有包括我的兴趣,所有其他部分都是无关紧要的。在这里我写了一个简单的语法文件:

... 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而不是处理&#34 ;;&#34;作为运营商。

我听说有一个叫做句法谓词的运算符,但我不知道在这种情况下如何正确使用它。

如何以Antlr鼓励的方式解决这个问题?

1 个答案:

答案 0 :(得分: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指令中的所需字符串。 '&lt;'FILE_NAME'&gt;'东西会产生歧义,必须从词法分析器分解为基本标记或使用更高级的上下文感知检查。我不熟悉后来的技术,所以我在解析器规则中写了这个:

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

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

虽然这种方法有效,但它看起来很丑陋。 我希望有经验的用户可以用更好的解决方案发表评论。