QLEXpress语法分析和计算的入口类详细分析–Expressrunner(三)
1.执行一段文本(一)

2.执行一段文本(二)

3.执行一段文本(三)
public Object execute(String expressString, IExpressContext<String, Object> context, List<String> errorList,
boolean isCache, boolean isTrace, Log log) throws Exception {
InstructionSet parseResult;
if (isCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
synchronized (expressInstructionSetCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
parseResult = this.parseInstructionSet(expressString);
expressInstructionSetCache.put(expressString, parseResult);
}
}
}
} else {
parseResult = this.parseInstructionSet(expressString);
}
return executeReentrant(parseResult, context, errorList, isTrace, log);
}
private Object executeReentrant(InstructionSet sets, IExpressContext<String, Object> iExpressContext,
List<String> errorList, boolean isTrace, Log log) throws Exception {
try {
int reentrantCount = threadReentrantCount.get() + 1;
threadReentrantCount.set(reentrantCount);
return reentrantCount > 1 ?
InstructionSetRunner.execute(this, sets, this.loader, iExpressContext, errorList, isTrace, false, true,
log, false) :
InstructionSetRunner.executeOuter(this, sets, this.loader, iExpressContext, errorList, isTrace, false,
log, false);
} finally {
threadReentrantCount.set(threadReentrantCount.get() - 1);
}
}
4.解析一段文本,生成指令集合

5.输出全局定义信息

6.优先从本地指令集缓存获取指令集,没有的话生成并且缓存在本地
public InstructionSet getInstructionSetFromLocalCache(String expressString) throws Exception {
InstructionSet parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
synchronized (expressInstructionSetCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
parseResult = this.parseInstructionSet(expressString);
expressInstructionSetCache.put(expressString, parseResult);
}
}
}
return parseResult;
}
public InstructionSet createInstructionSet(ExpressNode root, String type) throws Exception {
InstructionSet result = new InstructionSet(type);
createInstructionSet(root, result);
return result;
}
public void createInstructionSet(ExpressNode root, InstructionSet result) throws Exception {
Stack<ForRelBreakContinue> forStack = new Stack<>();
createInstructionSetPrivate(result, forStack, root, true);
if (!forStack.isEmpty()) {
throw new QLCompileException("For处理错误");
}
}
public boolean createInstructionSetPrivate(InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
InstructionFactory factory = InstructionFactory.getInstructionFactory(node.getInstructionFactory());
return factory.createInstruction(this, result, forStack, node, isRoot);
}
7.获取一个表达式需要的外部变量名称列表

8.是否忽略charset类型的数据,而识别为string

9.提供简答的语法检查,保证可以在运行期本地环境编译成指令

10.提供复杂的语法检查,不保证可以在运行期本地环境编译成指令
public boolean checkSyntax(String text, boolean mockRemoteJavaClass, List<String> remoteJavaClassNames) {
try {
Map<String, String> selfDefineClass = new HashMap<>();
for (ExportItem item : this.loader.getExportInfo()) {
if (item.getType().equals(InstructionSet.TYPE_CLASS)) {
selfDefineClass.put(item.getName(), item.getName());
}
}
Word[] words = this.parse.splitWords(text, isTrace, selfDefineClass);
ExpressNode root = this.parse.parse(this.rootExpressPackage, words, text, isTrace, selfDefineClass,
mockRemoteJavaClass);
InstructionSet result = createInstructionSet(root, "main");
if (this.isTrace && log.isDebugEnabled()) {
log.debug(result);
}
if (mockRemoteJavaClass && remoteJavaClassNames != null) {
remoteJavaClassNames.addAll(Arrays.asList(result.getVirClasses()));
}
return true;
} catch (Exception e) {
log.error("checkSyntax has Exception", e);
return false;
}
}
}