Antlr4预处理器语法与C语法集成

时间:2019-02-22 08:24:34

标签: c parsing antlr4

我是Antlr4的新手。我正在使用Antlr4和antlr4 adaptor来解析C文件并生成PSI树。

我知道C预处理程序应该处理#include和#define部分,并将结果传递给C lexer和C解析器。但是我需要为C.g4解析#include和#define,以便我的插件无需预处理程序即可处理C文件。

我调查了此link并尝试了解决方案,但是当遇到除预处理程序语句之外的其他内容时,它将无法解决。

示例C代码

#include <stdio.h>

int main()
{
  int i,j;
  for(i=1;i<=9;)
     {
      for(j=1;j<=9;j)
         {
           if(i>=j)
            {
              printf("%d*%d=%d    ",j,i,j*i);
            }
            j++;
         }
          printf("\n");
          i++;
     }
    return 0;
}

结果树就是这样

enter image description here

您可以在图像中看到,在包含块之后,所有元素都不是一棵树。

我删除了示例C代码中的#include行,并使用了原始的C.g4语法,它可以像下面这样解析一个好的PSI树:

enter image description here

有人会帮助我改善语法打击吗?这样我的语法就可以在不使用任何预处理器的情况下将#include和#define解析为PSI树中的预处理器块。

谢谢

Whitespace
:   [ \t]+
    -> channel(HIDDEN)
;
Newline
:   (   '\r' '\n'?
    |   '\n'
    )
    -> channel(HIDDEN)
;

BlockComment
:   '/*' .*? '*/'
;

LineComment
:   '//' ~[\r\n]*
;


IncludeBlock
 :   '#' Whitespace? 'include' ~[\r\n]*
 ;

DefineStart
:     '#' Whitespace? 'define'
;

DefineBlock
 :   DefineStart (~[\\\r\n] | '\\\\' '\r'? '\n' | '\\'. )*
 ;

MultiDefine
:   DefineStart MultiDefineBody
;

MultiDefineBody
:   [\\] [\r\n]+ MultiDefineBody
|   ~[\r\n]
;

preprocessorDeclaration
:   includeDeclaration
|   defineDeclaration
;

includeDeclaration
:   IncludeBlock
;

defineDeclaration
:   DefineBlock | MultiDefine
;

comment
:   BlockComment
|   LineComment
;

declaration
:   declarationSpecifiers initDeclaratorList ';'
|   declarationSpecifiers ';'
|   staticAssertDeclaration
|   preprocessorDeclaration
|   comment
;

1 个答案:

答案 0 :(得分:0)

我尝试并解决了自己的问题。

窍门是换行符应像下面的语法一样跳过,它不应该使用channel(HIDDEN)。

close()

应更改为

Newline
:   (   '\r' '\n'?
|   '\n'
)
-> channel(HIDDEN)
;

好的PSI树如下所示

good PSI tree with #include and #define

无论如何,我不完全了解channel(HIDDEN)和skip之间的区别。