java 文件的语法检查

Syntax check on a java file

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

This other answer 很有前途,但它实际上是在进行语义检查而不是句法检查。它执行编译器会执行的操作 - 检查所有导入语句并验证代码中引用的外部 类。

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

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

例如Java 8 grammar for ANTLR(尽管不知道该语法的质量,您必须进行评估 - 但该语法是由 ANTLR 的作者编写的,所以我想应该没问题)。

按照 Jiri 的建议,使用 ANTLR 库来组装一个语法检查器。

  1. here

  2. 下载并提取 ANTLR 语法
  3. here

  4. 下载ANTLR4 jar
  5. 运行 以下命令从 Java 8 语法生成 类:

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

  6. 将创建的 .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");
    }
}

我正在研究如何做一个快速的 java 语法检查器以便在 vim 中使用。我受到 的回答的启发(感谢示例检查器!)但它还不够,因为我需要它以独立的方式工作。

这里是为了让 运行nable 命令必须完成的分步过程:

  • 运行:
# download and generate .java classes
wget https://repo1.maven.org/maven2/org/antlr/antlr4/4.5.3/antlr4-4.5.3.jar -O antlr4-4.5.3.jar
wget https://raw.githubusercontent.com/antlr/grammars-v4/master/java8/Java8.g4 -O Java8.g4
java -jar antlr4-4.5.3.jar ./Java8.g4
  • 然后写个语法检查器,可能和的差不多,放在package checker;下直接放在./checker目录下

  • 也将所有生成的.java类放在那个包下(即把package checker;放在所有文件的第一行)

  • 运行:

# prepare directory structure and compile
mkdir -p checker && mv *.java ./checker/
javac -cp antlr4-4.5.3.jar ./checker/*.java
  • 准备一个类似于以下内容的清单文件:
Class-Path: antlr4-4.5.3.jar
Main-Class: checker.<name-of-your-checker-class>
  • 运行:
# package into a jar file and run to test everything works
jar cfm checker.jar Manifest.txt checker/*.class
java -jar ./checker.jar <filename-you-want-to-run-syntax-check-against>

为了我在 vim 中的使用,我创建了一个简单的 shell 脚本来包装执行 运行ning java jar 的过程,如下所示:

#!/bin/bash

DIR=$(readlink -f [=14=])
DIR=${DIR:0:(-3)}            # put the length of the script name here instead of '3'

java -jar ${DIR}checker.jar $@

然后使其可执行并将其符号链接到 $PATH:

chmod a+x <file-name>
sudo ln -s /path/to/the/script /usr/bin/java-syntax

最后将这样的键绑定添加到 .vimrc 文件中(即映射 运行 按下 F10 键时的语法检查):

" java syntax validation                                                        
map <F10> :!java-syntax % <CR>

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