用regex解析Java语法
我目前正在我的文本编辑器中为java开发一个校正器。为此,我认为最好的方法是使用模式来查找java语法的元素(导入或包声明、类或方法声明…)。我已经写了其中一些模式:用regex解析Java语法,java,Java,我目前正在我的文本编辑器中为java开发一个校正器。为此,我认为最好的方法是使用模式来查找java语法的元素(导入或包声明、类或方法声明…)。我已经写了其中一些模式: private String regimport = "^import(\\s+)(static |)(\\w+\\.)*(\\w+)(\\s*);(\\s*)$", regpackage="^package(\\s+)[\\w+\\.]*[\\w+](\\s*);(\\s*)$",
private String regimport = "^import(\\s+)(static |)(\\w+\\.)*(\\w+)(\\s*);(\\s*)$",
regpackage="^package(\\s+)[\\w+\\.]*[\\w+](\\s*);(\\s*)$",
regclass="^((public(\\s+)abstract)|(abstract)|(public)|(final)|(public(\\s+)final)|)(\\s+)class(\\s+)(\\w+)(((\\s+)(extends|implements)(\\s+)(\\w+))|)(\\s*)(\\{)?(\\s*)$";
现在还不是很难,但我恐怕要花很长时间才能做到。有人知道类似的东西是否已经存在吗
为此,我认为最好的方法是使用模式来查找java语法的元素
不对。正则表达式模式不能充分识别Java语法元素。这就是为什么存在更复杂的解析器。举个简单的例子,想象一下如何避免注释中保留字的错误匹配,例如
/* this is not importing anything
import java.util.*;
*/
但是,如果您非常热衷于使用正则表达式,并且愿意花费大量精力,那么可以看看Emacs
font-lock-mode
,它使用正则表达式来识别和设置语法元素的字体
注:我提到的“大量工作”指的是学习Emacs
如何工作,阅读elisp
code并将Emacs
regexp翻译成Java。如果你已经知道了所有这些,那么你将需要更少的努力
为此,我认为最好的方法是使用模式来查找java语法的元素
不对。正则表达式模式不能充分识别Java语法元素。这就是为什么存在更复杂的解析器。举个简单的例子,想象一下如何避免注释中保留字的错误匹配,例如
/* this is not importing anything
import java.util.*;
*/
但是,如果您非常热衷于使用正则表达式,并且愿意花费大量精力,那么可以看看Emacs
font-lock-mode
,它使用正则表达式来识别和设置语法元素的字体
注:我提到的“大量工作”指的是学习
Emacs
如何工作,阅读elisp
code并将Emacs
regexp翻译成Java。如果你已经知道了所有这些,那么你将需要更少的努力 正则表达式无法解析Java的完整语法。它们是不同的语言类别。Java至少是一种Chomsky类型2语言,而RegEx是类型3,类型2基本上比类型3更复杂。另请参阅关于使用正则表达式解析HTML的著名答案。。。这基本上是相同的问题。正则表达式无法解析Java的完整语法。它们是不同的语言类别。Java至少是一种Chomsky类型2语言,而RegEx是类型3,类型2基本上比类型3更复杂。另请参阅关于使用正则表达式解析HTML的著名答案。。。这基本上是同一个问题。谢谢大家的回答。我想我将使用javaparser AST,它将更容易:)
下面是检查AST错误的代码
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
public class Main {
public static void main(String[] args) {
ASTParser parser = ASTParser.newParser(AST.JLS2);
FileInputStream in=null;
try {
in = new FileInputStream("/root/java/Animbis.java"); //your personal java source file
int n;
String text="";
while( (n=in.read()) !=-1) {
text+=(char)n;
}
CompilationUnit cu;
// parse the file
parser.setSource(text.toCharArray());
in.close();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CompilationUnit unit = (CompilationUnit) parser.createAST(null);
//unit.recordModifications();
AST ast = unit.getAST();
IProblem[] problems = unit.getProblems();
boolean error = false;
for (IProblem problem : problems) {
StringBuffer buffer = new StringBuffer();
buffer.append(problem.getMessage());
buffer.append(" line: ");
buffer.append(problem.getSourceLineNumber());
String msg = buffer.toString();
if(problem.isError()) {
error = true;
msg = "Error:\n" + msg;
}
else
if(problem.isWarning())
msg = "Warning:\n" + msg;
System.out.println(msg);
}
}
}
要使用以下jar运行:
org.eclipse.core.contenttype.jar
org.eclipse.core.jobs.jar
org.eclipse.core.resources.jar
org.eclipse.core.runtime.jar
org.eclipse.equinox.common.jar
org.eclipse.equinox.preferences.jar
org.eclipse.jdt.core.jar
org.eclipse.osgi.jar
从中获得信息
谢谢大家的回答。我想我将使用javaparser AST,它将更容易:) 下面是检查AST错误的代码
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
public class Main {
public static void main(String[] args) {
ASTParser parser = ASTParser.newParser(AST.JLS2);
FileInputStream in=null;
try {
in = new FileInputStream("/root/java/Animbis.java"); //your personal java source file
int n;
String text="";
while( (n=in.read()) !=-1) {
text+=(char)n;
}
CompilationUnit cu;
// parse the file
parser.setSource(text.toCharArray());
in.close();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CompilationUnit unit = (CompilationUnit) parser.createAST(null);
//unit.recordModifications();
AST ast = unit.getAST();
IProblem[] problems = unit.getProblems();
boolean error = false;
for (IProblem problem : problems) {
StringBuffer buffer = new StringBuffer();
buffer.append(problem.getMessage());
buffer.append(" line: ");
buffer.append(problem.getSourceLineNumber());
String msg = buffer.toString();
if(problem.isError()) {
error = true;
msg = "Error:\n" + msg;
}
else
if(problem.isWarning())
msg = "Warning:\n" + msg;
System.out.println(msg);
}
}
}
要使用以下jar运行:
org.eclipse.core.contenttype.jar
org.eclipse.core.jobs.jar
org.eclipse.core.resources.jar
org.eclipse.core.runtime.jar
org.eclipse.equinox.common.jar
org.eclipse.equinox.preferences.jar
org.eclipse.jdt.core.jar
org.eclipse.osgi.jar
从中获得信息
而且我非常怀疑Java语法是否可以在正则表达式中完全表达。我觉得你构建Java校正器的方法是错误的,你不需要解析语言,你必须首先标记它并检查它的语法,这将使你的生活变得轻松Java不是一种常规语言(尽管Java正则表达式也不是常规语言),所以你现在正处于困境。但我相信有一些Java解析器是用Java编写的。我非常怀疑Java语法是否可以用正则表达式完全表达。我觉得你构建Java校正器的方法是错误的,你不需要解析语言,你必须首先对它进行标记并检查它的语法,这将使你的生活变得轻松Java不是一种常规语言(虽然Java正则表达式也不是常规的),所以你现在处于困境。但我相信有一些Java解析器是用Java编写的。Java不是类型2,因为它肯定不是上下文无关的。但是,现代正则表达式引擎(包括Java)也不是常规的。这就是“著名的答案”已经成为了一个令人厌倦的迷因…如果你知道你在做什么,你可以用正则表达式走得更远:真的-我将“可能”编辑为“至少”。不管怎样,正则表达式绝对不是做到这一点的方法。Java不是类型2,因为它绝对不是上下文无关的。但是,现代正则表达式引擎(包括Java)也不是常规的“著名答案”已经变成了一个令人厌倦的迷因…如果你知道你在做什么,你可以用正则表达式走得更远:是的-我将“可能”编辑为“至少”。无论如何,正则表达式绝对不是这样做的。