如何在Java中安全验证Python文件语法有效性(纯Java方案)
问题
在Java中自动修改Python文件的注释后,我需要验证该文件仍具备有效的Python语法。要求不使用Python解释器运行代码,且必须是纯Java方案(不能在Java中调用外部代码来判断语法有效性)。
我尝试过用ANTLR构建文件的抽象语法树(AST),但这对任意Python文件来说实现难度很高。另外两种思路都不符合要求:直接运行文件验证安全性无法保证;在Java中调用Python代码验证则依赖外部环境,我不想采用这种方式。
最小可复现示例(MWE)
以下是一段代码,但它仍存在依赖系统安装Python的问题:
package com.something.is_valid_python_syntax; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.TokenSource; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; import com.doctestbot.is_valid_python_syntax.generated.PythonParser; import com.doctestbot.is_valid_python_syntax.generated.PythonLexer; public class IsValidPythonSyntax { public static PythonParser getPythonParser(String pythonCode) { // Create a CharStream from the Python code CharStream charStream = CharStreams.fromString(pythonCode); // Create the lexer PythonLexer lexer = new PythonLexer(charStream); // Create a token stream from the lexer CommonTokenStream tokenStream = new CommonTokenStream((TokenSource) lexer); // Create the parser return new PythonParser(tokenStream); } public static boolean isValidPythonSyntax(String pythonCode) { PythonParser parser = getPythonParser(pythonCode); // Parse the input and get the tree // Redirect standard error stream PrintStream originalErr = System.err; ByteArrayOutputStream errStream = new ByteArrayOutputStream(); System.setErr(new PrintStream(errStream)); try { ParseTree tree = parser.file_input(); } finally { // Restore the original standard error stream System.setErr(originalErr); } // Check if there were any errors in the error stream String errorOutput = errStream.toString(); if (!errorOutput.isEmpty()) { System.out.println("Invalid Python syntax:"); System.out.println(errorOutput); return false; } else { System.out.println("Valid Python syntax"); return true; } } }
然而这段代码会误判以下合法Python代码存在语法错误:
def foo(): print("hello world.") foo()
对应的ANTLR错误信息如下:
Invalid Python syntax: line 1:3 extraneous input ' ' expecting {'match', '_', NAME}
我搜索后发现需要调整语法规则,但该语法是从官方Python 3.12的ANTLR语法自动生成的。
问题点
ANTLR的错误消息系统无法区分警告和实际语法错误。比如对于以下缺少右括号的错误Python代码:
def foo(): print("hello world." foo()
它会输出:
Invalid Python syntax: line 1:3 extraneous input ' ' expecting {'match', '_', NAME} line 2:9 no viable alternative at input '(' line 3:0 no viable alternative at input 'foo'
我不清楚ANTLR解析Python代码会产生多少种不同的错误消息,也不确定哪些错误属于真正的语法错误,更不知道基于ANTLR的解析错误判断Python语法有效性是否存在上下文依赖的问题。
内容的提问来源于stack exchange,提问作者a.t.
相关产品推荐
相关产品推荐

