首页 文章

ANTRL4 Parser语法测试隐藏的通道令牌

提问于
浏览
0

我想解析cpp预处理指令,同时跳过所有其他cpp语法 . 特别是,我需要区分函数和像宏这样的对象:

# define abc(x,y) x##y  //function like macro & token pasting operator
# define abc (a,b,c)   //object like macro, replace 'abc' by '(a,b,c)'

关键的区别在于像宏这样的函数在标识符 abc 和它后面的左括号之间没有任何隐藏标记(空白或多行注释) .

但问题是,我已经将所有多行注释和空格中的空格放到了隐藏的通道中 . 那么如何在左括号之前识别空格呢?

我试过的词法分析器语法是这样的:

CRLF: '\r'? '\n' -> channel(LINEBREAK);

WS: [ \t\f]+ -> channel(WHITESPACE);

ML_COMMENT: '/*'  .*? '*/' -> channel(COMMENTS);
SL_COMMENT: '//' ~[\r\n]*  -> channel(COMMENTS); 

PPHASH: {getCharPositionInLine() == 0}? (ML_COMMENT | [ \t\f])* '#'
; //any line starts with a # as the first char (comments, ws before it skipped)

CHARACTER_LITERAL : 'L'? '\'' (CH_ESC |~['\r\n\\])*? '\'' ;  //not exactly 1 char between '' e.g. '0x05'
fragment CH_ESC :  '\\' . ;
STRING_LITERAL: 'L'? '"' (STR_ESC | ~["\r\n\\])*? '"'  ;
fragment STR_ESC:  '\\'  .  ;

ANY_ID: [_0-9a-zA-Z]+ ;

ALL_SYMBOL:
  '~' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '=' | '-' | '+' | '\\'| '|' | ':' | ';' | '"' | '\''|
  '<' | '>' | '.' | '?' | '/' | ',' | '[' | ']' | '(' | ')' | '{' | '}'

; //basically everything found in a keyboard

我打算通过PPHASH令牌告诉解析器一个预处理指令的开始 . 在一行开头是'#' .

我对#define行的解析器语法不正确:

define_line:
  PPHASH 'define'  (function_like_define | object_like_define)
;
//--- function like define ---
function_like_define:
  ANY_ID '(' parameter_seq? ')'  fl_replacement_string
;
parameter_seq:  ANY_ID ( ',' ANY_ID)* ;

//--- object like define ---
object_like_define:
  ANY_ID ol_replacement_string
;
//fl&ol different names, visitor no need to test parent. Separate rule to make it a single node supporting getText()
fl_replacement_string: any_non_crlf_token*;
ol_replacement_string: any_non_crlf_token*;
any_non_crlf_token:ANY_ID | .....;

该语法错误地将 #define abc (a,b,c) 视为像宏一样的函数 . 如何修复语法?

1 回答

  • 0

    解析具有所有铃声和口哨声的预处理器令牌(跳过禁用的任何内容,行拼接,宏处理,字符串化,charizing等等)对于一般解析器来说不是一项任务 . 您应该实现一个自己的输入流来处理预处理器宏(它涉及条件的表达式解析器) . 然后,此流将评估在读取输入时启用的内容并跳过它,直到找到 #else#endif . #if / #ifdef 是基于行的,因此您可以通过逐行阅读轻松完成此操作 .

    几年前我已经完成了这个过程,并在我的主页上免费提供结果:http://www.soft-gems.net/index.php/java/windows-resource-file-parser-and-converter . 这个项目是Windows .rc 文件的解析器,但由于其性质,完全实现了 .h 文件解析器表达式求值程序,宏扩展等 .

相关问题