使用antlr4获取预处理器行并解析C代码

时间:2017-10-16 09:19:52

标签: java antlr4

我使用Antlr4来解析C代码,我使用以下语法来解析:

Link to C.g4

默认情况下,上述语法不提供任何解析规则来获取预处理程序语句。

我稍微改变了语法,通过添加以下行来获得预处理器行

externalDeclaration
:   functionDefinition
|   declaration
|   ';' // stray ;
|   preprocessorDeclaration
;

preprocessorDeclaration
:   PreprocessorBlock
;

PreprocessorBlock
:   '#' ~[\r\n]*
    -> channel(HIDDEN)
;

在Java中,我使用以下监听器来获取预处理器行

@Override
public void enterPreprocessorDeclaration(PreprocessorDeclarationContext ctx) {
    System.out.println("Preprocessor Directive found");
    System.out.println("Preprocessor: " + parser.getTokenStream().getText(ctx));
}

永远不会触发该方法。有人可以建议一种获取预处理器线的方法吗?

输入:

#include <stdio.h>

int k = 10;
int f(int a, int b){
int i;
for(i = 0; i < 5; i++){
    printf("%d", i);
}

}

1 个答案:

答案 0 :(得分:3)

实际上,对于channel(HIDDEN),规则preprocessorDeclaration不会产生任何输出。

如果我删除-> channel(HIDDEN),则有效:

preprocessorDeclaration
@after {System.out.println("Preprocessor found : " + $text);}
    :   PreprocessorBlock
    ;

PreprocessorBlock
    :   '#' ~[\r\n]*
//        -> channel(HIDDEN)
    ;

执行:

$ grun C compilationUnit -tokens -diagnostics t2.text
[@0,0:17='#include <stdio.h>',<PreprocessorBlock>,1:0]
[@1,18:18='\n',<Newline>,channel=1,1:18]
[@2,19:19='\n',<Newline>,channel=1,2:0]
[@3,20:22='int',<'int'>,3:0]
...
[@72,115:114='<EOF>',<EOF>,10:0]
C last update 1159
Preprocessor found : #include <stdio.h>
line 4:11 reportAttemptingFullContext d=83 (parameterDeclaration), input='int a,'
line 4:11 reportAmbiguity d=83 (parameterDeclaration): ambigAlts={1, 2}, input='int a,'
...
#include <stdio.h>

int k = 10;
int f(int a, int b) {
    int i;
    for(i = 0; i < 5; i++) {
        printf("%d", i);
    }
}

在档案CMyListener.java(来自我之前的回答)我添加了:

public void enterPreprocessorDeclaration(CParser.PreprocessorDeclarationContext ctx) {
    System.out.println("Preprocessor Directive found");
    System.out.println("Preprocessor: " + parser.getTokenStream().getText(ctx));
}

执行:

$ java test_c t2.text 
...
parsing ended
>>>> about to walk
Preprocessor Directive found
Preprocessor: #include <stdio.h>
>>> in CMyListener
#include <stdio.h>

int k = 10;
...
}