且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-27 14:21:11

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

如果我删除 ->通道(隐藏),它有效:

preprocessorDeclaration@after {System.out.println("找到预处理器:" + $text);}: 预处理器块;预处理块: '#' ~[\r\n]*//->频道(隐藏);

执行:

$ grun C compilerUnit -tokens -diagnostics t2.text[@0,0:17='#include ',,1:0][@1,18:18='\n',,channel=1,1:18][@2,19:19='\n',,channel=1,2:0][@3,20:22='int',,3:0]...[@72,115:114='<EOF>',<EOF>,10:0]C 最后更新 1159发现预处理器:#include 第 4:11 行 reportAttemptingFullContext d=83 (parameterDeclaration), input='int a,'line 4:11 reportAmbiguity d=83 (parameterDeclaration): ambigAlts={1, 2}, input='int a,'...#include 整数 k = 10;int f(int a, int b) {国际我;for(i = 0; i 

在文件 CMyListener.java(来自我之前的回答)中,我添加了:

public void enterPreprocessorDeclaration(CParser.PreprocessorDeclarationContext ctx) {System.out.println("找到预处理指令");System.out.println("预处理器:" + parser.getTokenStream().getText(ctx));}

执行:

$ java test_c t2.text...解析结束>>>>即将走路找到预处理器指令预处理器:#include >>>在 CMyListener 中#include 整数 k = 10;...}

I am using Antlr4 to parse C code and I am using the following grammar to parse:

Link to C.g4

The above grammar by default does not provide any parsing rules to get preprocessor statements.

I changed the grammar slightly to get the preprocessor lines by adding the following lines

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

preprocessorDeclaration
:   PreprocessorBlock
;

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

And in Java I am using the following listener to get the preprocessor lines

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

The method is never triggered. Can someone suggest a method to get the preprocessor lines?

Input:

#include <stdio.h>

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

}

Actually, with channel(HIDDEN), the rule preprocessorDeclaration produces no output.

If I remove -> channel(HIDDEN), it works :

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

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

Execution :

$ 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);
    }
}

In file CMyListener.java (from my previous answer) I have added :

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

Execution :

$ 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;
...
}