使用ANTLR4获取C语言空间的全部功能内容

时间:2017-10-14 20:13:13

标签: java antlr4

我正在使用ANTLR 4使用以下链接中提供的语法来解析C代码

Grammer for C.g4

我想要功能的全部内容,包括所有空格

以下是我用来遍历解析树的Listener类

public class CListnerImpl extends CBaseListener{

@Override
public void enterFunctionDefinition(FunctionDefinitionContext ctx) {
    System.out.println("Function name: " + ctx.declarator().directDeclarator().directDeclarator().getText());;
    System.out.println(ctx.compoundStatement().blockItemList().getText());
}

但是对于这段代码,我得到的函数内容没有任何像

这样的空格
  

函数名称:sumOfCubes   INTD,总和= 0;而(N!= 0){d = N%10 N / = 10;和+ = d d d;} returnsum;

我希望输出像

  

函数名称:sumOfCubes   int d,sum = 0; while(n!= 0){d = n%10; n / = 10; sum + = d d d;} return sum;

如果我得到包含所有缩进的代码也可以

1 个答案:

答案 0 :(得分:3)

保留空格和换行符取决于您如何定义相应的词法分析器规则。有了这条规则:

WS : [ \r\n\t]+ -> skip ;

空白被扔掉了,而这个规则:

WS : [ \t\r\n]+ -> channel(HIDDEN) ;

它会在getText()中保留并可用。

对C.g4的这些修改:

compilationUnit
@init {System.out.println("C last update 0531");}
@after {System.out.println($text);}
    :   translationUnit? EOF
    ;

Whitespace
    :   [ \t]+
//        -> skip
        -> channel(HIDDEN)
    ;

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

和文件t.text中的输入:

int sumOfCubes() {
    int d, sum = 0;
    while (n != 0)
        { d = n % 10;
          n /= 10;
          sum += d;
        }
    return sum;
}

我获得了以下结果:

$ grun C compilationUnit -diagnostics t.text
C last update 0531
int sumOfCubes() {
    int d, sum = 0;
    while (n != 0)
        { d = n % 10;
          n /= 10;
          sum += d;
        }
    return sum;
}

Java侦听器

档案CMyListener.java

public class CMyListener extends CBaseListener {
    CParser parser;
    public CMyListener(CParser parser) { this.parser = parser; }

    public void exitCompilationUnit(CParser.CompilationUnitContext ctx) {
        System.out.println(parser.getTokenStream().getText(ctx));
    }
}

测试程序,文件test_c.java

import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.*;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

public class test_c {
    public static void main(String[] args) throws IOException {
        ANTLRInputStream input = new ANTLRFileStream(args[0]);
        CLexer lexer = new CLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        CParser parser = new CParser(tokens);
        ParseTree tree = parser.compilationUnit();
        System.out.println("parsing ended");
        ParseTreeWalker walker = new ParseTreeWalker();
        CMyListener my_listener = new CMyListener(parser);
        System.out.println(">>>> about to walk");
        walker.walk(my_listener, tree);
    }
}

执行:

$ javac CMyListener.java
$ javac test_c.java 
$ java test_c t.text 
C last update 0531
int sumOfCubes() {
    int d, sum = 0;
    while (n != 0)
        { d = n % 10;
          n /= 10;
          sum += d;
        }
    return sum;
}
parsing ended
>>>> about to walk
int sumOfCubes() {
    int d, sum = 0;
    while (n != 0)
        { d = n % 10;
          n /= 10;
          sum += d;
        }
    return sum;
}