【问题标题】:Syntax check on a java filejava文件的语法检查
【发布时间】:2016-07-29 11:00:42
【问题描述】:

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

This other answer 很有希望,但它实际上是在进行语义检查而不是语法检查。它做了编译器会做的事情 - 检查所有导入语句以及验证代码中引用的外部类。

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

【问题讨论】:

  • 是的,我们确实使用了 IDE。我需要分析大量遗留文件,其中许多没有它们所依赖的库
  • 尝试使用javac编译
  • 您链接到的答案建议使用 Eclipse 的 JDT 解析器模块,该模块返回一个抽象语法树。我猜应该这样做。
  • 谢谢 Jens,javac 会做比我需要的更深入的分析
  • 您是在寻找工具还是代码?

标签: java syntax grammar


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    1. here下载并提取ANTLR语法

    2. here下载ANTLR4 jar

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

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

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

    【讨论】:

      【解决方案3】:

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

      以下是为了获得可运行命令而必须完成的操作的分步过程:

      • 运行:
      # 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
      
      • 然后写一个语法检查器,可能类似于@Fidel的那个,放在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 脚本来包装运行 java jar 的过程的执行,如下所示:

      #!/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 $@
      

      然后使其可执行并在$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 就足够了,以便构建和打包检查器。随意将其用作灵感。

      【讨论】:

        猜你喜欢
        • 2016-08-17
        • 1970-01-01
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多