【ali SimpleEL】day1
4054 ワード
式(例えば@a-@b+@c)の各部分をtokenとしてリストに格納し、アルゴリズムは以下の通りである.
ExpressUtils.java
public static List parse(String expr) {
List tokenList = new ArrayList();
TokenType type = TokenType.Text;
StringBuffer buf = new StringBuffer();
char[] charArray = expr.toCharArray();
for (int i = 0; i < charArray.length; ++i) {
char ch = charArray[i];
if (ch == '@') {
if (buf.length() > 0) {
tokenList.add(new Token(type, buf.toString()));
}
type = TokenType.Variant;
buf = new StringBuffer();
continue;
}
if (ch == '/' && i < charArray.length - 1 && charArray[i + 1] == '*') {
if (buf.length() > 0) {
tokenList.add(new Token(type, buf.toString()));
}
buf.append("/*");
++i;
type = TokenType.MultiLineComment;
continue;
}
if (ch == '/' && i < charArray.length - 1 && charArray[i + 1] == '/') {
if (buf.length() > 0) {
tokenList.add(new Token(type, buf.toString()));
}
buf.append("//");
++i;
type = TokenType.LineComment;
continue;
}
if (type == TokenType.Variant) {
if (Character.isLetter(ch) || Character.isDigit(ch)) {
buf.append(ch);
} else if (ch == '_') {
buf.append(ch);
} else {
tokenList.add(new Token(type, buf.toString()));
type = TokenType.Text;
buf = new StringBuffer();
--i;
}
continue;
}
if (type == TokenType.Text) {
buf.append(ch);
continue;
}
if (type == TokenType.MultiLineComment) {
if (ch == '*' && i < charArray.length - 1 && charArray[i + 1] == '/') {
buf.append("*/");
++i;
tokenList.add(new Token(type, buf.toString()));
type = TokenType.Text;
buf = new StringBuffer();
continue;
} else {
buf.append(ch);
}
}
if (type == TokenType.LineComment) {
if (ch == '
') {
buf.append(ch);
tokenList.add(new Token(type, buf.toString()));
type = TokenType.Text;
buf = new StringBuffer();
} else if (ch == '\r') {
buf.append(ch);
if (i < charArray.length - 1 && charArray[i + 1] == '
') {
buf.append(charArray[i + 1]);
++i;
}
tokenList.add(new Token(type, buf.toString()));
type = TokenType.Text;
buf = new StringBuffer();
} else {
buf.append(ch);
}
continue;
}
}
if (buf.length() > 0) {
tokenList.add(new Token(type, buf.toString()));
}
return tokenList;
}
JavaソースファイルをクラスにコンパイルするClass型インスタンス:JdkCompiler.java/JdkCompileTask.java
public synchronized Class extends Expr> compile(JavaSource javaSource) {
compileCount.incrementAndGet();
long startTimeMillis = System.nanoTime();
try {
final DiagnosticCollector errs = new DiagnosticCollector();
JdkCompileTask compileTask = new JdkCompileTask(classLoader, options);
String fullName = javaSource.getPackageName() + "." + javaSource.getClassName();
return (Class extends Expr>) compileTask.compile(fullName, javaSource.getSource(), errs);
} catch (JdkCompileException ex) {
DiagnosticCollector diagnostics = ex.getDiagnostics();
throw new CompileExprException("compile error, source :
" + javaSource + ", " + diagnostics.getDiagnostics(), ex);
} catch (Exception ex) {
throw new CompileExprException("compile error, source :
" + javaSource, ex);
} finally {
//
compileTimeNano.addAndGet(System.nanoTime() - startTimeMillis);
}
}
検討対象:
javax.tools.JavaCompiler.JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler().