java文件的语法检查

java文件的语法检查,java,syntax,grammar,Java,Syntax,Grammar,对于给定的java文件,我想检查它的语法是否正确。例如,如果它在正确的位置有分号,匹配的括号等。重要的是,我需要检查文件与它的所有依赖项隔离 很有希望,但是它实际上是在做语义检查,而不是语法检查。它执行编译器将执行的操作—检查所有导入语句以及验证代码中引用的外部类 有没有办法进行真正的语法检查?(只根据Java的形式语法检查原始文本的检查)创建或使用Java源代码解析器。对于某些解析器生成器,有可用的公共Java语法—您可以使用它来生成解析器 例如,for(虽然不知道语法的质量,但你必须进行评估

对于给定的java文件,我想检查它的语法是否正确。例如,如果它在正确的位置有分号,匹配的括号等。重要的是,我需要检查文件与它的所有依赖项隔离

很有希望,但是它实际上是在做语义检查,而不是语法检查。它执行编译器将执行的操作—检查所有导入语句以及验证代码中引用的外部类


有没有办法进行真正的语法检查?(只根据Java的形式语法检查原始文本的检查)

创建或使用Java源代码解析器。对于某些解析器生成器,有可用的公共Java语法—您可以使用它来生成解析器


例如,for(虽然不知道语法的质量,但你必须进行评估——但语法是由ANTLR的作者编写的,所以我想应该可以)。

正如Jiri所建议的,使用ANTLR库组合语法检查器

  • 从下载并提取ANTLR语法

  • 从下载ANTLR4 jar

  • 运行以下命令从Java 8语法生成类:

    java-jar-antlr-4.5.3-complete.jar ~/Downloads/grammars-v4-master/java8/java8.g4

  • 将创建的.java文件复制到项目中

  • 然后,您可以编写语法检查器:

    public static void main(String[] args) throws SAXException, IOException {
    
        ANTLRInputStream input = new ANTLRFileStream(args[0]);
        Java8Lexer lexer = new Java8Lexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        Java8Parser parser = new Java8Parser(tokens);
    
        final StringBuilder errorMessages = new StringBuilder();
        parser.addErrorListener(new BaseErrorListener() {
            @Override
            public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
                String err = String.format("Failed to parse at line %d:%d due to %s", line, charPositionInLine + 1, msg);
                errorMessages.append(err);
                errorMessages.append(System.lineSeparator());
            }
        });
    
        parser.compilationUnit();
        int syntaxErrors = parser.getNumberOfSyntaxErrors();
    
        if (syntaxErrors == 0) {
            System.out.println(args[0] + ": PASS");
        } else {
            System.out.println(args[0] + ": FAILED (" + syntaxErrors + " syntax errors");
        }
    }
    
    publicstaticvoidmain(字符串[]args)抛出SAXException、IOException{
    AntlInputStream输入=新的ANTLRFileStream(args[0]);
    Java8Lexer lexer=新的Java8Lexer(输入);
    CommonTokenStream令牌=新的CommonTokenStream(lexer);
    Java8Parser=新的Java8Parser(令牌);
    最终StringBuilder errorMessages=新StringBuilder();
    addErrorListener(新的BaseErrorListener(){
    @凌驾
    public void syntaxError(识别器识别器、对象违规符号、int行、int charPositionInLine、字符串消息、识别异常e){
    String err=String.format(“由于%s,在第%d行:%d处分析失败”,第行,charPositionInLine+1,msg);
    errorMessages.append(err);
    errorMessages.append(System.lineSeparator());
    }
    });
    parser.compilationUnit();
    int syntaxErrors=parser.getNumberOfSyntaxErrors();
    如果(语法错误==0){
    System.out.println(args[0]+“:PASS”);
    }否则{
    System.out.println(args[0]+“:失败(“+syntaxErrors+”语法错误”);
    }
    }
    
    我正在研究如何在vim中使用java语法快速检查工具。我的灵感来自于的答案(感谢示例检查工具!),但这还不够,因为我需要它以独立的方式工作

    下面是一个循序渐进的过程,说明了为了获得runnable命令必须做些什么:

    • 运行:
    #下载并生成.java类
    wgethttps://repo1.maven.org/maven2/org/antlr/antlr4/4.5.3/antlr4-4.5.3.jar -O antlr4-4.5.3.jar
    wgethttps://raw.githubusercontent.com/antlr/grammars-v4/master/java8/Java8.g4 -O Java8.g4
    java-jar antlr4-4.5.3.jar./Java8.g4
    
    • 然后编写一个语法检查器,可能与的类似,并将其放在
      包检查器下;
      将其直接放在
      /checker
      目录下

    • 同时将所有生成的
      .java
      类放在该包下(即将
      包检查器;
      放在所有文件的第一行)

    • 运行:

    #准备目录结构并编译
    mkdir-p checker&&mv*.java./checker/
    javac-cp antlr4-4.5.3.jar./checker/*.java
    
    • 准备一个清单文件,其外观类似于:
    然后使其可执行并在
    $PATH
    下对其进行符号链接:

    chmoda+x
    sudo ln-s/path/to/the/script/usr/bin/java语法
    
    最后在
    .vimrc
    文件中添加了这样的键绑定(即,按下F10键时运行语法检查的映射):

    “java语法验证
    映射:!java语法%
    

    我还将该过程存储到了中,其中所有命令都准备在一个makefile中,运行
    make
    就足以构建和打包检查器。请随意使用它作为灵感。

    是的,我们确实使用了一个IDE。我需要分析大量的遗留文件,其中许多文件没有它们所依赖的库使用javac编译您链接到的答案建议使用Eclipse的JDT解析器模块,该模块返回一个抽象语法树。我想应该可以。谢谢Jens,javac将进行比我需要的更深入的分析。您是否在寻找工具或代码?
    Class-Path: antlr4-4.5.3.jar
    Main-Class: checker.<name-of-your-checker-class>
    
    #!/bin/bash
    
    DIR=$(readlink -f $0)
    DIR=${DIR:0:(-3)}            # put the length of the script name here instead of '3'
    
    java -jar ${DIR}checker.jar $@