写点什么

案例研究之聊聊 QLExpress 源码 (六)

发布于: 2021 年 01 月 14 日
案例研究之聊聊 QLExpress 源码 (六)

六、解析模块(parse)

最近在回顾这些笔记的时候发现目前仅仅是将代码初步简单看了下,这个不是深度了解源码,那么如何能够将源码更好的理解,目前应该是只存在第一步骤,初步了解。第二步骤,原理了解。第三步骤,重点内容提炼,第四步骤,发现 bug 或者需要优化的内容。道阻且长,长途漫漫

6.1、AppendingClassFieldManager


package com.ql.util.express.parse;
import com.ql.util.express.*;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.op.OperatorBase;
import java.util.ArrayList;import java.util.List;
/** * 追加类属性管理器 * * @author tianqiao * @date 16/10/16 */public class AppendingClassFieldManager { /** * 追加属性 */ public class AppendingField { //名字 public String name; //绑定类 public Class<?> bindingClass; //操作 public Operator op; //返回类型 public Class<?> returnType; //构造函数 public AppendingField(String name, Class<?> bindingClass,Class<?> returnType, Operator op) { this.name = name; this.bindingClass = bindingClass; this.op = op; this.returnType = returnType; } }
/** * 追加的属性集合 */ private List<AppendingField> Fields = new ArrayList<AppendingField>();
/** * 添加追加属性 * @param name * @param bindingClass * @param returnType * @param op */ public void addAppendingField(String name,Class<?> bindingClass,Class<?> returnType, Operator op) { Fields.add(new AppendingField(name,bindingClass,returnType,op)); }
/** * 获取追加的类属性 * @param object * @param FieldName * @return */ public AppendingField getAppendingClassField(Object object, String FieldName) { for(AppendingField Field : Fields){ //object是定义类型的子类 if(FieldName.equals(Field.name) && (object.getClass()==Field.bindingClass || Field.bindingClass.isAssignableFrom(object.getClass()))){ return Field; } } return null;
}
/** * 运算执行并返回结果 * @param Field * @param context * @param aFieldObject * @param errorList * @return * @throws Exception */ public Object invoke(AppendingField Field, InstructionSetContext context, Object aFieldObject, List<String> errorList) throws Exception { Operator op = Field.op; Object result = op.executeInner(new Object[]{aFieldObject}); return result; }}
复制代码

6.2、AppendingClassMethodManager

package com.ql.util.express.parse;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.op.OperatorBase;
import java.util.ArrayList;import java.util.List;
/** * 追加类方法管理器 * * @author tianqiao * @date 16/10/16 */public class AppendingClassMethodManager { /** * 追加方法 */ public class AppendingMethod { //名字 public String name; //绑定的类 public Class<?> bindingClass; //运算 public OperatorBase op; //追加方法 public AppendingMethod(String name, Class<?> bindingClass, OperatorBase op) { this.name = name; this.bindingClass = bindingClass; this.op = op; } }
/** * 方法集合 */ private List<AppendingMethod> methods = new ArrayList<AppendingMethod>();
/** * 添加追加方法 * @param name * @param bindingClass * @param op */ public void addAppendingMethod(String name,Class<?> bindingClass,OperatorBase op) { methods.add(new AppendingMethod(name,bindingClass,op)); }
/** * 获取追加类方法 * @param object * @param methodName * @return */ public AppendingMethod getAppendingClassMethod(Object object, String methodName) { for(AppendingMethod method : methods){ //object是定义类型的子类 if(methodName.equals(method.name) && (object.getClass()==method.bindingClass || method.bindingClass.isAssignableFrom(object.getClass()))){ return method; } } return null;
}
/** * 方法的运算执行 * @param method * @param context * @param list * @param errorList * @return * @throws Exception */ public OperateData invoke(AppendingMethod method, InstructionSetContext context, ArraySwap list, List<String> errorList) throws Exception { OperatorBase op = method.op; return op.execute(context,list,errorList); }}
复制代码

6.3、ExpressNode(表达式节点)

package com.ql.util.express.parse;
import java.util.ArrayList;import java.util.List;
import com.ql.util.express.exception.QLCompileException;import com.ql.util.express.match.IDataNode;import com.ql.util.express.match.INodeType;
/** * 表达式节点 * @author xiaochengxinyizhan */public class ExpressNode implements IDataNode{ /** * 节点类型 */ private NodeType nodeType; /** * 树类型 */ private NodeType treeType; /** * 节点值 */ private String value; /** * 节点原始值 */ private String orgiValue; /** * 对象值 */ private Object objectValue; /** * 父节点 */ private ExpressNode parent; /** * 左节点 */ private List<ExpressNode> leftChildren; /** * 右节点 */ private List<ExpressNode> rightChildren; /** * 是否分割语法 */ private boolean isSplitStatement = false; /** * 行号 */ private int line; /** * 列号 */ private int col; /** * word的序号 */ private int wordIndex = -1;
/** * 获取词汇索引 * @return */ public int getWordIndex() { return wordIndex; }
/** * 表达式节点构造函数 * @param aType * @param aValue * @throws Exception */ public ExpressNode(NodeType aType, String aValue) throws Exception{ this(aType, aValue, null,null,null,-1,-1,-1); }
/** * 表达式节点构造函数 * @param aType * @param aValue * @param aOrgiValue * @param aObjectValue * @param aTreeType * @param aLine * @param aCol * @param wordIndex * @throws Exception */ public ExpressNode(NodeType aType,String aValue,String aOrgiValue,Object aObjectValue,NodeType aTreeType,int aLine,int aCol,int wordIndex) throws Exception{ if(aType == null){ throw new QLCompileException(aValue + " 没有找到对应的节点类型"); } this.nodeType = aType; this.treeType = aTreeType; if(aValue != null && aValue.length() >0){ this.value = aValue; } if(aOrgiValue != null && aOrgiValue.length() >0){ this.orgiValue = aOrgiValue; } if(aObjectValue != null){ this.objectValue = aObjectValue; } this.line = aLine; this.col =aCol; this.wordIndex = wordIndex; }
/** * 是否子节点类型 * @param parent * @return */ public boolean isTypeEqualsOrChild(String parent){ boolean result = this.getTreeType().isEqualsOrChild(parent); if(result == false && this.treeType != null){ result = this.getNodeType().isEqualsOrChild(parent); } return result; }
/** * 获取节点类型 * @return */ @Override public NodeType getNodeType() { return nodeType; }
/** * 设置节点类型 * @param type */ public void setNodeType(NodeType type) { this.nodeType = type; }
/** * 获取值 * @return */ @Override public String getValue() { if(value == null){ return this.nodeType.getName(); }else{ return value; } }
/** * 设置值 * @param value */ public void setValue(String value) { this.value = value; }
/** * 是否切割语法规范 * @return */ public boolean isSplitStatement() { return isSplitStatement; }
/** * 设置切割语法规范 * @param isSplitStatement */ public void setSplitStatement(boolean isSplitStatement) { this.isSplitStatement = isSplitStatement; }
/** * 获取指令工厂 * @return */ public String getInstructionFactory(){ if(this.nodeType.getInstructionFactory() != null){ return this.nodeType.getInstructionFactory(); } if(this.treeType != null && this.treeType.getInstructionFactory() != null){ return this.treeType.getInstructionFactory(); } throw new RuntimeException("没有定义节点的指令InstructionFactory信息:" + this.nodeType.getName()+ (this.treeType == null?"":" 或者 " +this.treeType.getName()) ); }
/** * 获取原值 * @return */ public String getOrgiValue() { return orgiValue; }
/** * 设置原值 * @param orgiValue */ public void setOrgiValue(String orgiValue) { this.orgiValue = orgiValue; }
/** * 获取对象值 * @return */ public Object getObjectValue() { return objectValue; }
/** * 设置对象值 * @param objectValue */ @Override public void setObjectValue(Object objectValue) { this.objectValue = objectValue; }
/** * 获取父节点 * @return */ public ExpressNode getParent() { return parent; }
/** * 设置父节点 * @param parent */ public void setParent(ExpressNode parent) { this.parent = parent; }
/** * 获取行 * @return */ public int getLine() { return line; }
/** * 设置行 * @param line */ public void setLine(int line) { this.line = line; }
/** * 获取列 * @return */ public int getCol() { return col; }
/** * 设置列 * @param col */ public void setCol(int col) { this.col = col; }
/** * 获取真树类型 --无调用,感觉是废弃的原代码 * @return */ public NodeType getRealTreeType(){ return this.treeType; }
/** * 获取树类型 * @return */ @Override public NodeType getTreeType() { if(this.treeType == null){ return this.nodeType; }else{ return treeType; } }
/** * 设置树类型 * @param treeType */ public void setTreeType(NodeType treeType) { this.treeType = treeType; }
/** * 获取左孩子 * @return */ public List<ExpressNode> getLeftChildren() { return leftChildren; }
/** * 设置左孩子 * @param leftChildren */ public void setLeftChildren(List<ExpressNode> leftChildren) { this.leftChildren = leftChildren; }
/** * 获取右孩子 * @return */ public List<ExpressNode> getRightChildren() { return rightChildren; }
/** * 设置右孩子 * @param rightChildren */ public void setRightChildren(List<ExpressNode> rightChildren) { this.rightChildren = rightChildren; }
/** * 添加左孩子 * @param leftChild */ public void addLeftChild(ExpressNode leftChild){ if(leftChild == null){ return ; } if(this.leftChildren ==null){ this.leftChildren = new ArrayList<ExpressNode>(); } this.leftChildren.add(leftChild); }
/** * 添加右孩子 * @param rightChild */ public void addRightChild(ExpressNode rightChild){ if(rightChild == null){ return ; } if(this.leftChildren ==null){ this.leftChildren = new ArrayList<ExpressNode>(); } this.leftChildren.add(rightChild); }
/** * 获取孩子 * @return */ public ExpressNode[] getChildren(){ List<ExpressNode> result = new ArrayList<ExpressNode>(); if(this.leftChildren != null && this.leftChildren.size() >0){ result.addAll(this.leftChildren); } if(this.rightChildren != null && this.rightChildren.size() >0){ result.addAll(this.rightChildren); } return result.toArray(new ExpressNode[0]); } @Override public String toString(){ String str = (this.orgiValue == null ? this.getValue():this.orgiValue) + (this.nodeType.getName() == null?"":(":" + this.nodeType.getName())); // return str + "[" + this.line +"," + this.col +"]"; return str; }
/** * 创建表达式节点 * @param aType * @param aValue * @return * @throws Exception */ @Override public IDataNode createExpressNode(INodeType aType, String aValue) throws Exception { return new ExpressNode((NodeType)aType,aValue); }
/** * 设置节点类型 * @param type */ @Override public void setNodeType(INodeType type) { this.setNodeType((NodeType)type); }
/** * 添加左子树 * @param ref */ @Override public void addLeftChild(IDataNode ref) { this.addLeftChild((ExpressNode)ref); }
/** * 设置树类型 * @param aTreeType */ @Override public void setTreeType(INodeType aTreeType) { this.setTreeType((NodeType)aTreeType); }}

复制代码

6.4、ExpressPackage(表达式包)


package com.ql.util.express.parse;
import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;
/** * 表达式包 */public class ExpressPackage { /** * 包集合 */ private List<String> m_packages; /** * 根据名字查询缓存 */ private Map<String,Class<?>> name2CallCache = null; /** * 空指针类 */ private Class<?> S_NULL = NullClass.class; /** * 表达式包 */ private ExpressPackage parent;
/** * 表达式包构造函数 * @param aParent */ public ExpressPackage(ExpressPackage aParent) { this.parent = aParent; }
/** * 添加包 * @param aPackageName */ public void addPackage(String aPackageName) { if(this.m_packages == null){ this.m_packages = new ArrayList<String>(); } int point = aPackageName.indexOf(".*"); if(point >=0){ aPackageName = aPackageName.substring(0, point); } this.m_packages.add(aPackageName); }
/** * 移除包 * @param aPackageName */ public void removePackage(String aPackageName) { if(this.m_packages != null){ this.m_packages.remove(aPackageName); } }
/** * 获取类 * @param name * @return */ public Class<?> getClass(String name) { Class<?> tempClass = null; if (this.parent != null){ tempClass = this.parent.getClass(name); } if(tempClass == null){ if(this.m_packages == null && this.parent != null){ return null; } if (this.name2CallCache == null) { this.name2CallCache = new ConcurrentHashMap<String, Class<?>>(); }else{ tempClass = this.name2CallCache.get(name); } if(tempClass == null){ tempClass = this.getClassInner(name,this.parent == null); if(tempClass == null){ tempClass = S_NULL ; } } this.name2CallCache.put(name, tempClass); } if(tempClass == S_NULL){ return null; }else{ return tempClass; } }
/** * 获取类内部 * @param name * @param isRootCall * @return */ private Class<?> getClassInner(String name,boolean isRootCall) { Class<?> result = null; if (isRootCall == true) { // 如果本身具有包名,这直接定位 if (name.indexOf(".") >= 0) { try { result = Class.forName(name); } catch (Throwable ex) { } return result; } if (Integer.TYPE.getName().equals(name) == true) return Integer.TYPE; if (Short.TYPE.getName().equals(name) == true) return Short.TYPE; if (Long.TYPE.getName().equals(name) == true) return Long.TYPE; if (Double.TYPE.getName().equals(name) == true) return Double.TYPE; if (Float.TYPE.getName().equals(name) == true) return Float.TYPE; if (Byte.TYPE.getName().equals(name) == true) return Byte.TYPE; if (Character.TYPE.getName().equals(name) == true) return Character.TYPE; if (Boolean.TYPE.getName().equals(name) == true) return Boolean.TYPE; } if (this.m_packages != null) { for (int i = 0; i < m_packages.size(); i++) { String tmp = ""; if (m_packages.get(i).endsWith("." + name) == true) { tmp = m_packages.get(i); } else { tmp = m_packages.get(i) + "." + name; } try { result = Class.forName(tmp); } catch (ClassNotFoundException ex) { // 不做任何操作 } if (result != null) { return result; } } } return null; }}
/** * 空指针类 */class NullClass{ }

复制代码

6.5、ExpressParse(表达式解析)


package com.ql.util.express.parse;
import java.math.BigDecimal;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;
import com.ql.util.express.exception.QLCompileException;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;
import com.ql.util.express.ExpressUtil;import com.ql.util.express.IExpressResourceLoader;import com.ql.util.express.match.QLMatchResult;import com.ql.util.express.match.QLPattern;
/** * 表达式解析 */public class ExpressParse {
private static final Log log = LogFactory.getLog(ExpressParse.class); NodeTypeManager nodeTypeManager; IExpressResourceLoader expressResourceLoader; /** * 是否忽略charset类型的数据,而识别为string,比如'a' -> "a" * 在计算比如 '1'+'2'=='12' */ private boolean ignoreConstChar = false; /** * 是否需要高精度计算 */ private boolean isPrecise = false;
/** * 是否忽略常量字符 * @return */ public boolean isIgnoreConstChar() { return ignoreConstChar; }
/** * 设置忽略的常量字符 * @param ignoreConstChar */ public void setIgnoreConstChar(boolean ignoreConstChar) { this.ignoreConstChar = ignoreConstChar; }
/** * 表达式解析构造函数 * @param aNodeTypeManager * @param aLoader * @param aIsPrecise */ public ExpressParse(NodeTypeManager aNodeTypeManager, IExpressResourceLoader aLoader, boolean aIsPrecise){ this.nodeTypeManager = aNodeTypeManager; this.expressResourceLoader = aLoader; this.isPrecise = aIsPrecise; }
/** * 根据名字获取表达式 * @param expressFileName * @return * @throws Exception */ protected Word[] getExpressByName(String expressFileName) throws Exception{ String express = this.expressResourceLoader.loadExpress(expressFileName); return WordSplit.parse(nodeTypeManager.splitWord, express); }
/** * 处理包含的分词 * @param wordObjects * @return * @throws Exception */ protected Word[] dealInclude(Word[] wordObjects) throws Exception{ boolean isInclude = false; StringBuffer includeFileName = new StringBuffer(); int point = 0; List<Word> result = new ArrayList<Word>(); while(point <wordObjects.length ){ if(wordObjects[point].word.equals("include") ==true){ isInclude = true; includeFileName.setLength(0); }else if(isInclude == true && wordObjects[point].word.equals(";") ==true) { isInclude = false; Word[] childExpressWord = this.getExpressByName(includeFileName.toString()); childExpressWord = this.dealInclude(childExpressWord); for(int i=0;i< childExpressWord.length;i++){ result.add(childExpressWord[i]); } }else if(isInclude == true){ includeFileName.append(wordObjects[point].word); }else{ result.add(wordObjects[point]); } point = point + 1; } return result.toArray(new Word[0]); } /** * 进行单词类型分析 * @param aRootExpressPackage * @param wordObjects * @param selfClassDefine * @param dealJavaClass * @return * @throws Exception */ public List<ExpressNode> transferWord2ExpressNode(ExpressPackage aRootExpressPackage,Word[] wordObjects,Map<String,String> selfClassDefine,boolean dealJavaClass) throws Exception{ List<ExpressNode> result = new ArrayList<ExpressNode>(); String tempWord; NodeType tempType; int point = 0; ExpressPackage tmpImportPackage = null; if(dealJavaClass==true){ tmpImportPackage = new ExpressPackage(aRootExpressPackage); //先处理import,import必须放在文件的最开始,必须以;结束 boolean isImport = false; StringBuffer importName = new StringBuffer(); while(point <wordObjects.length ){ if(wordObjects[point].word.equals("import") ==true){ isImport = true; importName.setLength(0); }else if(wordObjects[point].word.equals(";") ==true) { isImport = false; tmpImportPackage.addPackage(importName.toString()); }else if(isImport == true){ importName.append(wordObjects[point].word); }else{ break; } point = point + 1; } }
String orgiValue = null; Object objectValue = null; NodeType treeNodeType = null; Word tmpWordObject = null; while(point <wordObjects.length){ tmpWordObject = wordObjects[point]; tempWord = wordObjects[point].word; char firstChar = tempWord.charAt(0); char lastChar = tempWord.substring(tempWord.length() - 1).toLowerCase().charAt(0); if(firstChar >='0' && firstChar<='9'){ if(result.size() >0){//对 负号进行特殊处理 if(result.get(result.size() -1).getValue().equals("-")){ if(result.size() == 1 || result.size() >=2 && ( result.get(result.size() - 2).isTypeEqualsOrChild("OP_LIST") || result.get(result.size() - 2).isTypeEqualsOrChild(",") || result.get(result.size() - 2).isTypeEqualsOrChild("return") || result.get(result.size() - 2).isTypeEqualsOrChild("?") || result.get(result.size() - 2).isTypeEqualsOrChild(":") ) && result.get(result.size() - 2).isTypeEqualsOrChild(")")==false && result.get(result.size() - 2).isTypeEqualsOrChild("]")==false ){ result.remove(result.size() -1); tempWord = "-" + tempWord; } } } if(lastChar =='d'){ tempType = nodeTypeManager.findNodeType("CONST_DOUBLE"); tempWord = tempWord.substring(0,tempWord.length() -1); if(this.isPrecise == true){ objectValue = new BigDecimal(tempWord); }else{ objectValue = Double.valueOf(tempWord); } }else if(lastChar =='f'){ tempType = nodeTypeManager.findNodeType("CONST_FLOAT"); tempWord = tempWord.substring(0,tempWord.length() -1); if(this.isPrecise == true){ objectValue = new BigDecimal(tempWord); }else{ objectValue = Float.valueOf(tempWord); } }else if(tempWord.indexOf(".") >=0){ tempType = nodeTypeManager.findNodeType("CONST_DOUBLE"); if(this.isPrecise == true){ objectValue = new BigDecimal(tempWord); }else{ objectValue = Double.valueOf(tempWord); } }else if(lastChar =='l'){ tempType = nodeTypeManager.findNodeType("CONST_LONG"); tempWord = tempWord.substring(0,tempWord.length() -1); objectValue = Long.valueOf(tempWord); }else{ long tempLong = Long.parseLong(tempWord); if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){ tempType = nodeTypeManager.findNodeType("CONST_INTEGER"); objectValue = Integer.valueOf((int)tempLong); }else{ tempType = nodeTypeManager.findNodeType("CONST_LONG"); objectValue = Long.valueOf(tempLong); } } treeNodeType = nodeTypeManager.findNodeType("CONST"); point = point + 1; }else if(firstChar =='"'){ if(lastChar !='"' || tempWord.length() <2){ throw new QLCompileException("没有关闭的字符串:" + tempWord); } tempWord = tempWord.substring(1,tempWord.length() -1); tempType =nodeTypeManager.findNodeType("CONST_STRING"); objectValue = tempWord; treeNodeType = nodeTypeManager.findNodeType("CONST"); point = point + 1; }else if(firstChar =='\''){ if(lastChar !='\'' || tempWord.length() <2){ throw new QLCompileException("没有关闭的字符:" + tempWord); } tempWord = tempWord.substring(1,tempWord.length() -1); treeNodeType = nodeTypeManager.findNodeType("CONST"); if(tempWord.length() == 1 && !ignoreConstChar){ //转换为字符串 tempType =nodeTypeManager.findNodeType("CONST_CHAR"); objectValue = tempWord.charAt(0); }else{ tempType =nodeTypeManager.findNodeType("CONST_STRING"); objectValue = tempWord; } point = point + 1; }else if(tempWord.equals("true") || tempWord.equals("false")){ tempType = nodeTypeManager.findNodeType("CONST_BOOLEAN"); treeNodeType = nodeTypeManager.findNodeType("CONST"); objectValue = Boolean.valueOf(tempWord); point = point + 1; }else { tempType = nodeTypeManager.isExistNodeTypeDefine(tempWord); if(tempType != null && tempType.getKind() != NodeTypeKind.KEYWORD){ //不是关键字 tempType = null; } if (tempType == null) { boolean isClass = false; String tmpStr = ""; Class<?> tmpClass = null; if (dealJavaClass == true) { int j = point; while (j < wordObjects.length) { tmpStr = tmpStr + wordObjects[j].word; tmpClass = tmpImportPackage.getClass(tmpStr); if (tmpClass != null) { point = j + 1; isClass = true; break; } if (j < wordObjects.length - 1 && wordObjects[j + 1].word.equals(".") == true) { tmpStr = tmpStr + wordObjects[j + 1].word; j = j + 2; continue; } else { break; } } } if (isClass == true){ tempWord = ExpressUtil.getClassName(tmpClass); orgiValue = tmpStr; tempType = nodeTypeManager.findNodeType("CONST_CLASS"); objectValue = tmpClass; }else if(this.nodeTypeManager.isFunction(tempWord)){ tempType = nodeTypeManager.findNodeType("FUNCTION_NAME"); point = point + 1; }else if(selfClassDefine != null && selfClassDefine.containsKey(tempWord)){ tempType = nodeTypeManager.findNodeType("VClass"); point = point + 1; }else{ tempType = nodeTypeManager.findNodeType("ID"); point = point + 1; } }else{ point = point + 1; } } result.add(new ExpressNode(tempType,tempWord,orgiValue,objectValue,treeNodeType,tmpWordObject.line,tmpWordObject.col,tmpWordObject.index)); treeNodeType = null; objectValue = null; orgiValue = null; } return result; }
/** * 打印树节点 * @param builder * @param node * @param level */ public static void printTreeNode(StringBuilder builder,ExpressNode node, int level){ builder.append(level+":" ); for (int i = 0; i < level; i++) { builder.append(" "); } builder.append(node); if(builder.length() <100){ for (int i = 0; i <100 - builder.length(); i++) { builder.append(" "); } } builder.append("\t"+ node.getTreeType().getName()).append("\n"); List<ExpressNode> leftChildren = node.getLeftChildren(); if (leftChildren != null && leftChildren.size() > 0) { for (ExpressNode item : leftChildren) { printTreeNode(builder,item, level + 1); } } List<ExpressNode> rightChildren = node.getRightChildren(); if (rightChildren != null && rightChildren.size() > 0) { for (ExpressNode item : rightChildren) { printTreeNode(builder,item, level + 1); } } }
/** * 打印树节点 * @param node * @param level */ public static void printTreeNode(ExpressNode node, int level) { StringBuilder builder = new StringBuilder(); printTreeNode(builder,node,level); System.out.println(builder.toString()); }
/** * 重制父节点 * @param node * @param parent */ public static void resetParent(ExpressNode node,ExpressNode parent){ node.setParent(parent); List<ExpressNode> leftChildren = node.getLeftChildren(); if (leftChildren != null && leftChildren.size() > 0) { for (ExpressNode item : leftChildren) { resetParent(item,node); } } List<ExpressNode> rightChildren = node.getRightChildren(); if (rightChildren != null && rightChildren.size() > 0) { for (ExpressNode item : rightChildren) { resetParent(item,node); } } } /** * 提取自定义的Class * @param words */ public static void fetchSelfDefineClass(Word[] words,Map<String,String> selfDefineClass){ for(int i=0;i<words.length -1;i++){ if("class".equals(words[i].word)){ selfDefineClass.put(words[i+1].word, words[i+1].word); } } }
/** * 解析表达式包 * @param rootExpressPackage * @param express * @param isTrace * @param selfDefineClass * @return * @throws Exception */ public ExpressNode parse(ExpressPackage rootExpressPackage,String express,boolean isTrace,Map<String,String> selfDefineClass) throws Exception{ Word[] words = splitWords(rootExpressPackage,express,isTrace,selfDefineClass); return parse(rootExpressPackage,words,express,isTrace,selfDefineClass); }
/** * 解析分词 * @param rootExpressPackage * @param express * @param isTrace * @param selfDefineClass * @return * @throws Exception */ public Word[] splitWords(ExpressPackage rootExpressPackage,String express,boolean isTrace,Map<String,String> selfDefineClass) throws Exception{ Word[] words = WordSplit.parse(this.nodeTypeManager.splitWord,express); if(isTrace == true && log.isDebugEnabled()){ log.debug("执行的表达式:" + express); log.debug("单词分解结果:" + WordSplit.getPrintInfo(words,",")); } words = this.dealInclude(words); if(isTrace == true && log.isDebugEnabled()){ log.debug("预处理后结果:" + WordSplit.getPrintInfo(words,",")); } //提取自定义Class if(selfDefineClass == null){ selfDefineClass = new HashMap<String,String>(); } fetchSelfDefineClass(words,selfDefineClass); for(int i=0;i<words.length;i++){ words[i].index=i; } return words; }
/** * 解析 * @param rootExpressPackage * @param words * @param express * @param isTrace * @param selfDefineClass * @return * @throws Exception */ public ExpressNode parse(ExpressPackage rootExpressPackage,Word[] words ,String express,boolean isTrace,Map<String,String> selfDefineClass) throws Exception{ return parse(rootExpressPackage,words,express,isTrace,selfDefineClass,false); }
/** * 解析 * @param rootExpressPackage * @param words * @param express * @param isTrace * @param selfDefineClass * @param mockRemoteJavaClass * @return * @throws Exception */ public ExpressNode parse(ExpressPackage rootExpressPackage,Word[] words ,String express,boolean isTrace,Map<String,String> selfDefineClass,boolean mockRemoteJavaClass) throws Exception{
List<ExpressNode> tempList = this.transferWord2ExpressNode(rootExpressPackage,words,selfDefineClass,true); if(isTrace == true && log.isDebugEnabled()){ log.debug("单词分析结果:" + printInfo(tempList,",")); } //比如用在远程配置脚本,本地jvm并不包含这个java类,可以 if(mockRemoteJavaClass){ List<ExpressNode> tempList2 = new ArrayList<ExpressNode>(); for(int i=0;i<tempList.size();i++){ ExpressNode node = tempList.get(i); if(node.getValue().equals("new") && node.getNodeType().getKind() == NodeTypeKind.KEYWORD && i+1<tempList.size() && !"CONST_CLASS".equals(tempList.get(i+1).getNodeType().getName())){ tempList2.add(node); //取出 ( 前面的类路径作为configClass名称 int end = i+1; String configClass = tempList.get(end).getValue(); end++; while (!tempList.get(end).getValue().equals("(")) { configClass = configClass+tempList.get(end).getValue(); end++; } NodeType nodeType = nodeTypeManager.findNodeType("VClass"); ExpressNode vClassNode = new ExpressNode(nodeType,configClass); tempList2.add(vClassNode); i = end-1;//因为循环之后,i++,所以i=end-1 }else { tempList2.add(node); } } tempList = tempList2; if(isTrace == true && log.isDebugEnabled()){ log.debug("修正后单词分析结果:" + printInfo(tempList,",")); } }
QLMatchResult result = QLPattern.findMatchStatement(this.nodeTypeManager, this.nodeTypeManager .findNodeType("PROGRAM").getPatternNode(), tempList,0); if(result == null){ throw new QLCompileException("语法匹配失败"); } if(result.getMatchLastIndex() < tempList.size()){ int maxPoint = result.getMatchLastIndex(); ExpressNode tempNode = tempList.get(maxPoint); throw new QLCompileException("还有单词没有完成语法匹配:" + result.getMatchLastIndex() +"["+ tempNode.getValue() + ":line=" + tempNode.getLine() + ",col=" + tempNode.getCol() +"] 之后的单词 \n" + express); } result.getMatchs().get(0).buildExpressNodeTree(); ExpressNode root =(ExpressNode)result.getMatchs().get(0).getRef(); //为了生成代码时候进行判断,需要设置每个节点的父亲 resetParent(root,null); if(isTrace == true && log.isDebugEnabled()){ log.debug("最后的语法树:" ); printTreeNode(root,1); } return root; }
/** * 打印信息 * @param list * @param splitOp * @return */ public static String printInfo(List<ExpressNode> list,String splitOp){ StringBuffer buffer = new StringBuffer(); for(int i=0;i<list.size();i++){ if(i > 0){buffer.append(splitOp);} buffer.append(list.get(i)); } return buffer.toString(); }}


复制代码

6.6、KeyWordDefine4Java

package com.ql.util.express.parse;
/** * 为Java专门定义的关键字 */public class KeyWordDefine4Java { /** * 拆分关键字数组 */ public String[] splitWord={ // 位操作 "^","~","&","|","<<", ">>", "+", "-","*", "/", "%","++", "--", //四则运算: ".",",",":",";","(", ")", "{", "}", "[", "]","?", //分隔符号 "!","<", ">", "<=", ">=", "==","!=","&&","||", //Boolean运算符号 "=","/**","**/" }; /** * 关键字数组 */ public String[] keyWords = new String[] { "mod","nor","in", "for", "if","when", "then", "else", "exportAlias", "alias", "break", "continue", "return", "macro", "function" , "def","exportDef", "new","array","anonymousNewArray", "like","class","VClass", "cast" }; /** * 节点类型定义数组 */ public String[] nodeTypeDefines = new String[] { "ID:TYPE=WORDDEF", "EOF:TYPE=WORDDEF", "FUNCTION_NAME:TYPE=WORDDEF", "FUNCTION_DEFINE:TYPE=WORDDEF", "LEFT_BRACKET:TYPE=WORDDEF,DEFINE=(", "RIGHT_BRACKET:TYPE=WORDDEF,DEFINE=)",
"XOR:TYPE=WORDDEF,DEFINE=^", "MAYBE:TYPE=WORDDEF,DEFINE=|", "OR:TYPE=WORDDEF,DEFINE=||", "LEFT_COMMENT:TYPE=WORDDEF,DEFINE=/**", "RIGHT_COMMENT:TYPE=WORDDEF,DEFINE=**/", "MULTI:TYPE=WORDDEF,DEFINE=*", "CONST_BYTE:TYPE=WORDDEF", "CONST_SHORT:TYPE=WORDDEF", "CONST_INTEGER:TYPE=WORDDEF", "CONST_LONG:TYPE=WORDDEF", "CONST_FLOAT:TYPE=WORDDEF", "CONST_DOUBLE:TYPE=WORDDEF", "CONST_NUMBER:TYPE=WORDDEF,DEFINE=CONST_BYTE|CONST_SHORT|CONST_INTEGER|CONST_LONG|CONST_FLOAT|CONST_DOUBLE", "CONST_CHAR:TYPE=WORDDEF", "CONST_STRING:TYPE=WORDDEF", "CONST_BOOLEAN:TYPE=WORDDEF", "CONST_CLASS:TYPE=WORDDEF", "CONST:TYPE=WORDDEF,DEFINE=CONST_NUMBER|CONST_CHAR|CONST_STRING|CONST_BOOLEAN|CONST_CLASS",
"CHILD_EXPRESS:TYPE=EXPRESS,DEFINE=LEFT_BRACKET->CHILD_EXPRESS^$(RIGHT_BRACKET~|(EXPRESS$(,~$EXPRESS)*$RIGHT_BRACKET~))", "[]:TYPE=EXPRESS,DEFINE=[~$EXPRESS*$]~#[]", "OP_LEVEL1:TYPE=OPERATOR,DEFINE=~|!", "OP_LEVEL2:TYPE=OPERATOR,DEFINE=++|--", "OP_LEVEL3:TYPE=OPERATOR,DEFINE=&|MAYBE|XOR|<<|>>", "OP_LEVEL4:TYPE=OPERATOR,DEFINE=*|/|mod|%", "OP_LEVEL5:TYPE=OPERATOR,DEFINE=+|-", "OP_LEVEL6:TYPE=OPERATOR,DEFINE=in|like", "OP_LEVEL7:TYPE=OPERATOR,DEFINE=>|>=|<|<=|==|!=", "OP_LEVEL8:TYPE=OPERATOR,DEFINE=&&", "OP_LEVEL9:TYPE=OPERATOR,DEFINE=OR|nor", "OP_LIST:TYPE=GROUP,DEFINE=OP_LEVEL1|OP_LEVEL2|OP_LEVEL3|OP_LEVEL4|OP_LEVEL5|OP_LEVEL6|OP_LEVEL7|OP_LEVEL8|OP_LEVEL9|=|LEFT_BRACKET|RIGHT_BRACKET|[|]|{|}", "PARAMETER_LIST:TYPE=STATEMENT,DEFINE=LEFT_BRACKET~$(RIGHT_BRACKET~|(EXPRESS$(,~$EXPRESS)*$RIGHT_BRACKET~))", "VAR_DEFINE:TYPE=EXPRESS,DEFINE=(CONST_CLASS|VClass->CONST_STRING)$(([$])#[])*$ID->CONST_STRING#def", "EXPORT_VAR_DEFINE:TYPE=EXPRESS,DEFINE=exportDef^$CONST_CLASS$ID->CONST_STRING", "NEW_OBJECT:TYPE=EXPRESS,DEFINE=new->NEW_OBJECT^$CONST_CLASS$PARAMETER_LIST", "NEW_ARRAY:TYPE=EXPRESS,DEFINE=new->NEW_ARRAY^$CONST_CLASS$([]*)", "ANONY_NEW_ARRAY:TYPE=EXPRESS,DEFINE=[->anonymousNewArray^$(]~|(EXPRESS$(,~$EXPRESS)*$]~))",
"NEW_VIR_OBJECT:TYPE=EXPRESS,DEFINE=new->NEW_VIR_OBJECT^$VClass->CONST_STRING$PARAMETER_LIST", "OPDATA:TYPE=EXPRESS,DEFINE=ANONY_NEW_ARRAY|VAR_DEFINE|EXPORT_VAR_DEFINE|NEW_OBJECT|NEW_ARRAY|NEW_VIR_OBJECT|CHILD_EXPRESS|CONST|ID", "FIELD_CALL:TYPE=EXPRESS,DEFINE= .->FIELD_CALL^$(ID->CONST_STRING|class->CONST_STRING)", "METHOD_CALL:TYPE=EXPRESS,DEFINE=.->METHOD_CALL^$(ID->CONST_STRING|FUNCTION_NAME->CONST_STRING)$PARAMETER_LIST", "OBJECT_CALL:TYPE=EXPRESS,DEFINE=((COMMENT~)*$OPDATA$(COMMENT~)*)$(METHOD_CALL|FIELD_CALL)^*", "FUNCTION_CALL:TYPE=EXPRESS,DEFINE=(ID->CONST_STRING|FUNCTION_NAME->CONST_STRING)$PARAMETER_LIST#FUNCTION_CALL", "ARRAY_CALL:TYPE=EXPRESS,DEFINE=(FUNCTION_CALL|OBJECT_CALL)$([->ARRAY_CALL^$EXPRESS$]~)^*$(METHOD_CALL|FIELD_CALL)^*",
"CAST_CALL:TYPE=EXPRESS,DEFINE=(LEFT_BRACKET~$CONST_CLASS$RIGHT_BRACKET~#cast)^*$ARRAY_CALL", "EXPRESS_OP_L1:TYPE=EXPRESS,DEFINE=OP_LEVEL1^*$CAST_CALL", "EXPRESS_OP_L2:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L1$OP_LEVEL2^*", "EXPRESS_OP_L3:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L2$(OP_LEVEL3^$EXPRESS_OP_L2)^*", "EXPRESS_OP_L4:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L3$(OP_LEVEL4^$EXPRESS_OP_L3)^*", "EXPRESS_OP_L5:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L4$(OP_LEVEL5^$EXPRESS_OP_L4)^*", "EXPRESS_OP_L6:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L5$(OP_LEVEL6^$EXPRESS_OP_L5)^*", "EXPRESS_OP_L7:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L6$(OP_LEVEL7^$EXPRESS_OP_L6)^*", "EXPRESS_OP_L8:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L7$(OP_LEVEL8^$EXPRESS_OP_L7)^*", "EXPRESS_OP_L9:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L8$(OP_LEVEL9^$EXPRESS_OP_L8)^*", "EXPRESS_COMPUTER:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L9",
"EXPRESS_JUDGEANDSET:TYPE=EXPRESS,DEFINE=EXPRESS_COMPUTER$(?->EXPRESS_JUDGEANDSET^$EXPRESS_COMPUTER$:~$EXPRESS_COMPUTER)^{0:1}", "EXPRESS_KEY_VALUE:TYPE=EXPRESS,DEFINE=EXPRESS_JUDGEANDSET$(:->EXPRESS_KEY_VALUE^$(EXPRESS_JUDGEANDSET|STAT_BLOCK))^{0:1}", "EXPRESS_ASSIGN:TYPE=EXPRESS,DEFINE=EXPRESS_KEY_VALUE$(=^$EXPRESS_KEY_VALUE)^*", "EXPRESS_RETURN:TYPE=EXPRESS,DEFINE=return^$EXPRESS_ASSIGN", "BREAK_CALL:TYPE=EXPRESS,DEFINE=break^", "CONTINUE_CALL:TYPE=EXPRESS,DEFINE=continue^", "ALIAS_CALL:TYPE=EXPRESS,DEFINE=alias^$ID->CONST_STRING$EXPRESS_ASSIGN", "EXPORT_ALIAS_CALL:TYPE=EXPRESS,DEFINE=exportAlias^$ID->CONST_STRING$EXPRESS_ASSIGN", "OP_CALL:TYPE=EXPRESS,DEFINE=(ID->CONST_STRING|FUNCTION_NAME->CONST_STRING)$(EXPRESS$(,~$EXPRESS)*)#FUNCTION_CALL", "EXPRESS:TYPE=EXPRESS,DEFINE=BREAK_CALL|CONTINUE_CALL|EXPRESS_RETURN|ALIAS_CALL|EXPORT_ALIAS_CALL|EXPRESS_ASSIGN|OP_CALL", "STAT_SEMICOLON:TYPE=STATEMENT,DEFINE=;~|(EXPRESS$(EOF|;)~#STAT_SEMICOLON)", "STAT_IFELSE:TYPE=STATEMENT,DEFINE=(if|when->if)^$EXPRESS$then$(STAT_BLOCK|STATEMENT|EXPRESS)$else$(STAT_BLOCK|STATEMENT)", "STAT_IF:TYPE=STATEMENT, DEFINE=(if|when->if)^$EXPRESS$then$(STAT_BLOCK|STATEMENT)", "STAT_IFELSE_JAVA:TYPE=STATEMENT,DEFINE=(if|when->if)^$CHILD_EXPRESS$(STAT_BLOCK|STATEMENT|EXPRESS)$else$(STAT_BLOCK|STATEMENT)", "STAT_IF_JAVA:TYPE=STATEMENT, DEFINE=(if|when->if)^$CHILD_EXPRESS$(STAT_BLOCK|STATEMENT)", "PARAMETER_DEFINE:TYPE=STATEMENT,DEFINE=LEFT_BRACKET->CHILD_EXPRESS^$(RIGHT_BRACKET~|(VAR_DEFINE$(,~$VAR_DEFINE)*$RIGHT_BRACKET~))", "STAT_FOR:TYPE=STATEMENT,DEFINE=for^$(LEFT_BRACKET~$STATEMENT{0:2}$EXPRESS$RIGHT_BRACKET~#CHILD_EXPRESS)$STAT_BLOCK$;~*", "STAT_MACRO:TYPE=STATEMENT,DEFINE=macro^$ID->CONST_STRING$STAT_BLOCK$;~*", "STAT_FUNCTION:TYPE=STATEMENT,DEFINE=function^$ID->CONST_STRING$PARAMETER_DEFINE$STAT_BLOCK$;~*", "STAT_CLASS:TYPE=STATEMENT,DEFINE=class^$VClass->CONST_STRING$PARAMETER_DEFINE$STAT_BLOCK$;~*", "COMMENT:TYPE=BLOCK,DEFINE=LEFT_COMMENT$(RIGHT_COMMENT@)*$RIGHT_COMMENT#COMMENT", "STATEMENT:TYPE=STATEMENT,DEFINE=COMMENT|STAT_IFELSE|STAT_IF|STAT_IFELSE_JAVA|STAT_IF_JAVA|STAT_FOR|STAT_MACRO|STAT_FUNCTION|STAT_CLASS|STAT_SEMICOLON", "STAT_BLOCK:TYPE=BLOCK,DEFINE={->STAT_BLOCK^$STAT_LIST$}~", "STAT_LIST:TYPE=BLOCK,DEFINE=(STAT_BLOCK|STATEMENT)*", "PROGRAM:TYPE=BLOCK,DEFINE=STAT_LIST#STAT_BLOCK", }; /** * 指令工厂映射 */ public String[][] instructionFacotryMapping = { {"^,~,!,++,--,&,|,<<,>>,*,/,mod,%,+,-,like,>,>=,<,<=,==,!=,&&,||,nor,=,return,alias,exportAlias,ARRAY_CALL","com.ql.util.express.instruction.OperatorInstructionFactory"}, {"in","com.ql.util.express.instruction.InInstructionFactory"}, {"exportDef","com.ql.util.express.instruction.OperatorInstructionFactory"}, {"ID","com.ql.util.express.instruction.LoadAttrInstructionFactory"}, {"CONST,CONST_CLASS","com.ql.util.express.instruction.ConstDataInstructionFactory"}, {"[],STAT_SEMICOLON,STAT_BLOCK,FUNCTION_DEFINE,CHILD_EXPRESS","com.ql.util.express.instruction.BlockInstructionFactory"}, {"def","com.ql.util.express.instruction.DefineInstructionFactory"}, {"NEW_OBJECT,NEW_ARRAY,anonymousNewArray","com.ql.util.express.instruction.NewInstructionFactory"}, {"FIELD_CALL","com.ql.util.express.instruction.FieldCallInstructionFactory"}, {"METHOD_CALL","com.ql.util.express.instruction.MethodCallInstructionFactory"}, {"cast","com.ql.util.express.instruction.CastInstructionFactory"}, {"break","com.ql.util.express.instruction.BreakInstructionFactory"}, {"continue","com.ql.util.express.instruction.ContinueInstructionFactory"}, {"FUNCTION_CALL","com.ql.util.express.instruction.CallFunctionInstructionFactory"}, {"if,EXPRESS_JUDGEANDSET","com.ql.util.express.instruction.IfInstructionFactory"}, {"for","com.ql.util.express.instruction.ForInstructionFactory"}, {"function,class","com.ql.util.express.instruction.FunctionInstructionFactory"}, {"macro","com.ql.util.express.instruction.MacroInstructionFactory"}, {"NEW_VIR_OBJECT","com.ql.util.express.instruction.NewVClassInstructionFactory"}, {"COMMENT","com.ql.util.express.instruction.NullInstructionFactory"}, {"EXPRESS_KEY_VALUE","com.ql.util.express.instruction.KeyValueInstructionFactory"}, };}

复制代码

6.7、NodeType(节点类型)


package com.ql.util.express.parse;
import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;
import com.ql.util.express.match.INodeType;import com.ql.util.express.match.QLPattern;import com.ql.util.express.match.QLPatternNode;
/** * 节点类型种类 */enum NodeTypeKind { KEYWORD, BLOCK, EXPRESS, OPERATOR, WORDDEF, GROUP, STATEMENT}
/** * 节点类型 */public class NodeType implements INodeType { /** * 节点类型管理器 */ NodeTypeManager manager; /** * 名字 */ private String name; /** * 定义str */ private String defineStr; /** * 节点类型种类 */ private NodeTypeKind kind; /** * 真实节点类型 */ private NodeType realNodeType; /** * 指令工厂 */ private String instructionFactory; /** * 模式匹配 */ private QLPatternNode qlPatternNode;
/** * 节点类型构造器 * @param aManager * @param aName * @param aDefineStr */ protected NodeType(NodeTypeManager aManager, String aName, String aDefineStr) { this.manager = aManager; this.defineStr = aDefineStr; this.name = aName; }
/** * 分词属性 * @param str * @return */ public static String[][] splitProperties(String str) { Pattern p = Pattern.compile("(,|:)\\s*(([A-Z]|-|_)*)\\s*="); Matcher matcher = p.matcher(str); List<String[]> list = new ArrayList<String[]>(); int endIndex = 0; while (matcher.find()) { if (list.size() > 0) { list.get(list.size() - 1)[1] = str.substring(endIndex, matcher.start()).trim(); } list.add(new String[2]); list.get(list.size() - 1)[0] = str.substring(matcher.start() + 1, matcher.end() - 1).trim(); endIndex = matcher.end(); } if (list.size() > 0) { list.get(list.size() - 1)[1] = str.substring(endIndex).trim(); } return (String[][]) list.toArray(new String[0][2]); }
/** * 初始化 */ public void initial() { try { int index = this.defineStr.indexOf(":", 1); String[][] properties = splitProperties(this.defineStr.substring(index)); for (String[] tempList : properties) { if (tempList[0].equalsIgnoreCase("type")) { this.setKind(NodeTypeKind.valueOf(tempList[1])); } else if (tempList[0].equalsIgnoreCase("real")) { this.realNodeType = manager.findNodeType(tempList[1]); } else if (tempList[0].equalsIgnoreCase("factory")) { this.instructionFactory = tempList[1]; } else if (tempList[0].equalsIgnoreCase("define")) { this.qlPatternNode = QLPattern.createPattern(this.manager, this.name, tempList[1]); } else { throw new RuntimeException("不能识别\"" + this.name + "\"的属性类型:" + tempList[0] + " 定义:" + this.defineStr); } } } catch (Exception e) { throw new RuntimeException("节点类型\"" + this.name + "\"初始化失败,定义:" + this.defineStr, e); } }
/** * 是否是子节点 * @param parent * @return */ public boolean isEqualsOrChild(String parent) { return this.manager.findNodeType(parent).isContainerChild(this); }
/** * 是否包含子节点 * @param child * @return */ public boolean isContainerChild(NodeType child) { if (this.equals(child)) { return true; } if (this.qlPatternNode == null) { return false; } if (this.qlPatternNode.isDetailMode()) { return ((NodeType) this.qlPatternNode.getNodeType()) .isContainerChild(child); } // 是and类型,不能增加子节点或进行判断 if (this.qlPatternNode.isAndMode() && this.qlPatternNode.getChildren().size() > 0) { return false; } for (QLPatternNode node : this.qlPatternNode.getChildren()) { if (node.getNodeType() != null && ((NodeType) node.getNodeType()).isContainerChild(child)) { return true; } } return false; }
/** * 添加子节点 * @param child * @throws Exception */ public void addChild(NodeType child) throws Exception { String str = child.name; if (this.qlPatternNode != null) { str = this.qlPatternNode.toString() + "|" + str; } this.qlPatternNode = QLPattern.createPattern(this.manager, this.name,str); }
public String toString() { StringBuilder result = new StringBuilder(); result.append(name + ":TYPE=" + this.kind); if (this.instructionFactory != null) { result.append(",FACTORY=" + this.instructionFactory); } if (this.qlPatternNode != null) { result.append(",DEFINE=").append(this.qlPatternNode); } return result.toString(); }
/** * 获取真实节点类型 * @return */ public NodeType getRealNodeType() { return realNodeType; }
/** * 获取种类 * @return */ public NodeTypeKind getKind() { return kind; }
/** * 获取指令工厂 * @return */ public String getInstructionFactory() { return instructionFactory; }
/** * 设置指令工厂 * @param instructionFactory */ public void setInstructionFactory(String instructionFactory) { this.instructionFactory = instructionFactory; }
/** * 获取管理器 * @return */ @Override public NodeTypeManager getManager() { return manager; }
/** * 获取定义str * @return */ public String getDefineStr() { return defineStr; }
/** * 设置种类 * @param kind */ public void setKind(NodeTypeKind kind) { this.kind = kind; }
/** * 获取名字 * @return */ @Override public String getName() { return name; }
/** * 获取父节点 * @return */ @Override public QLPatternNode getPatternNode() { return this.qlPatternNode; }
}
复制代码


6.8、NodeTypeManager(节点类型管理器)


package com.ql.util.express.parse;
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;
import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;
import com.ql.util.express.match.INodeTypeManager;
/** * 节点类型管理器 */public class NodeTypeManager implements INodeTypeManager { private static final Log log = LogFactory.getLog(NodeTypeManager.class); /** * 分割词 */ public String[] splitWord; /** * 关键词 */ private String[] keyWords; /** * 节点类型定义 */ private String[] nodeTypeDefines; /** * 指令工厂映射 */ protected String[][] instructionFacotryMapping; /** * 节点类型 */ protected Map<String, NodeType> nodeTypes = new HashMap<String, NodeType>();
//所有的函数定义 protected Map<String, String> functions = new HashMap<String, String>();
/** * 构造器 */ public NodeTypeManager() { this(new KeyWordDefine4Java()); }
/** * 节点类型管理器的构造器 * @param keyWorkdDefine */ public NodeTypeManager(KeyWordDefine4Java keyWorkdDefine) { this.splitWord = keyWorkdDefine.splitWord; com.ql.util.express.parse.WordSplit.sortSplitWord(this.splitWord); this.keyWords = keyWorkdDefine.keyWords; this.nodeTypeDefines = keyWorkdDefine.nodeTypeDefines; this.instructionFacotryMapping = keyWorkdDefine.instructionFacotryMapping; this.initial(); this.addOperatorWithRealNodeType("and", "&&"); this.addOperatorWithRealNodeType("or", "||");
}
/** * 初始化 */ public void initial() { //创建所有的关键字 NodeType[] tempKeyWordNodeTypes = new NodeType[splitWord.length + keyWords.length]; for (int i = 0; i < splitWord.length; i++) { tempKeyWordNodeTypes[i] = this.createNodeType(splitWord[i] + ":TYPE=KEYWORD"); } for (int i = 0; i < keyWords.length; i++) { tempKeyWordNodeTypes[i + splitWord.length] = this.createNodeType(keyWords[i] + ":TYPE=KEYWORD"); } // 初始化所有的类型信息, for (int i = 0; i < tempKeyWordNodeTypes.length; i++) { tempKeyWordNodeTypes[i].initial(); }
// 创建所有的类型信息,但不能初始化 NodeType[] nodeTypes = new NodeType[nodeTypeDefines.length]; for (int i = 0; i < nodeTypeDefines.length; i++) { nodeTypes[i] = this.createNodeType(nodeTypeDefines[i]); } // 初始化所有的类型信息, for (int i = 0; i < nodeTypes.length; i++) { nodeTypes[i].initial(); }
//初始化指令Facotry if (this.instructionFacotryMapping != null) { for (String[] list : this.instructionFacotryMapping) { for (String s : list[0].split(",")) { this.findNodeType(s).setInstructionFactory(list[1]); } } } }
/** * 创建节点类型,需要注意的是不能初始化,必须所有的类型都创建完成后才能调用初始化方法 * * @param aDefineStr * @return */ public NodeType createNodeType(String aDefineStr) { int index = aDefineStr.indexOf(":", 1);//避免对操作符号":"的错误处理 String name = aDefineStr.substring(0, index).trim(); NodeType define = nodeTypes.get(name); if (define != null) { log.warn("节点类型定义重复:" + name + " 定义1=" + define.getDefineStr() + " 定义2=" + aDefineStr); throw new RuntimeException("节点类型定义重复:" + name + " 定义1=" + define.getDefineStr() + " 定义2=" + aDefineStr); } define = new NodeType(this, name, aDefineStr); nodeTypes.put(name, define); return define; }
/** * 根据类型名称查找节点类型 * * @param name * @return */ @Override public NodeType findNodeType(String name) { NodeType result = nodeTypes.get(name); if (result == null) { throw new RuntimeException("没有定义的节点类型:" + name); } while (result.getRealNodeType() != null) { result = result.getRealNodeType(); } return result; }
/** * 增加关键字,但是用实际的类型代替,例如 :"如果" -》"if" * * @param keyWordName * @param realName */ public void addOperatorWithRealNodeType(String keyWordName, String realName) { NodeType target = this.createNodeType(keyWordName + ":TYPE=KEYWORD,REAL=" + realName); target.initial(); }
/** * 增加新的操作符号,其优先级别,以及语法关系与参照的操作符号一致 * * @param operName * @param refOperName * @throws Exception */ public void addOperatorWithLevelOfReference(String operName, String refOperName) throws Exception { NodeType target = this.createNodeType(operName + ":TYPE=KEYWORD"); target.initial(); NodeType[] list = this.getNodeTypesByKind(NodeTypeKind.OPERATOR); NodeType refNodeType = this.findNodeType(refOperName); target.setInstructionFactory(refNodeType.getInstructionFactory()); for (NodeType item : list) { if (item.isContainerChild(refNodeType)) { item.addChild(target); return; } } }
/** * 判断是否存在节点类型定义 * * @param name * @return */ public NodeType isExistNodeTypeDefine(String name) { NodeType result = nodeTypes.get(name); if (result != null && result.getRealNodeType() != null) { result = result.getRealNodeType(); } return result; }
/** * 根据种类获取节点类型集合 * @param aKind * @return */ public NodeType[] getNodeTypesByKind(NodeTypeKind aKind) { List<NodeType> result = new ArrayList<NodeType>(); for (NodeType item : this.nodeTypes.values()) { if (item.getKind() == aKind) { result.add(item); } } return result.toArray(new NodeType[0]); }
/** * 是否是函数 * @param name * @return */ public boolean isFunction(String name) { return this.functions.containsKey(name); }
/** * 添加函数名字 * @param name */ public void addFunctionName(String name) { this.functions.put(name, name); }}

复制代码

6.9、word(分词)


package com.ql.util.express.parse;
/** * 分词 */public class Word { /** * 分词 */ public String word; /** * 行 */ public int line; /** * 列 */ public int col; /** * 索引 */ public int index;
/** * 构造函数 * @param aWord * @param aLine * @param aCol */ public Word(String aWord,int aLine,int aCol){ this.word = aWord; this.line = aLine; this.col = aCol; }
@Override public String toString(){ // + "[" + this.line + "," + this.col + "]"; return this.word; }}

复制代码

6.10、WordSplit(语法解析类)


package com.ql.util.express.parse;
import com.ql.util.express.exception.QLCompileException;
import java.util.ArrayList;import java.util.Arrays;import java.util.Comparator;import java.util.List;

/** * 语法解析类 * 1、单词分解 * @author xuannan * */
public class WordSplit{ /** * 文本分析函数,“.”作为操作符号处理 * @param str String * @throws Exception * @return String[] */ public static Word[] parse(String[] splitWord,String str) throws Exception{ if (str == null){ return new Word[0]; } char c; int line =1; List<Word> list = new ArrayList<Word>(); int i= 0; int point = 0; // 当前行第一个字符相对脚本起点的偏移量offset int currentLineOffset = 0; while(i<str.length()){ c = str.charAt(i); if (c=='"' || c=='\''){//字符串处理 int index = str.indexOf(c,i + 1); //处理字符串中的”问题 while(index >0 && str.charAt(index - 1) =='\\'){ index = str.indexOf(c,index + 1); } if (index < 0) throw new QLCompileException("字符串没有关闭"); String tempDealStr = str.substring(i,index + 1); //处理 \\,\"的情况 String tmpResult = ""; int tmpPoint = tempDealStr.indexOf("\\"); while(tmpPoint >=0 ){ tmpResult = tmpResult + tempDealStr.substring(0,tmpPoint); if(tmpPoint == tempDealStr.length() -1){ throw new QLCompileException("字符串中的" + "\\错误:" + tempDealStr); } tmpResult = tmpResult + tempDealStr.substring(tmpPoint + 1 ,tmpPoint + 2); tempDealStr = tempDealStr.substring(tmpPoint + 2); tmpPoint = tempDealStr.indexOf("\\"); } tmpResult = tmpResult + tempDealStr; list.add(new Word(tmpResult,line,i - currentLineOffset + 1));
if (point < i ){ list.add(new Word(str.substring(point,i),line,point - currentLineOffset + 1)); } i = index + 1; point = i; }else if(c=='.' && point < i && isNumber(str.substring(point,i))){ i = i + 1; //小数点的特殊处理 }else if(c == ' ' ||c =='\r'|| c =='\n'||c=='\t'||c=='\u000C'){ if (point < i ){ list.add(new Word(str.substring(point,i),line,point - currentLineOffset + 1)); } if(c =='\n'){ line = line + 1; currentLineOffset = i + 1; } i = i + 1; point = i; }else{ boolean isFind = false; for(String s:splitWord){ int length = s.length(); if(i + length <= str.length() && str.substring(i, i+length).equals(s)){ if (point < i ){ list.add(new Word(str.substring(point,i),line,point - currentLineOffset + 1)); } list.add(new Word(str.substring(i, i+length),line,i - currentLineOffset + 1)); i = i + length; point = i; isFind = true; break; } } if(isFind == false){ i = i+1; } } } if (point < i) { list.add(new Word(str.substring(point, i), line, point - currentLineOffset + 1)); }
Word result[] = new Word[list.size()]; list.toArray(result); return result; }
/** * 排序分解单词 * @param splitWord * @return */ public static String[] sortSplitWord(String[] splitWord) { Arrays.sort(splitWord, new Comparator<String>() { public int compare(String o1, String o2) { if (o1.length() == o2.length()) { return 0; } else if (o1.length() > o2.length()) { return -1; } else { return 1; }
} }); return splitWord; }
/** * 判断是否是数字 * @param str * @return */ protected static boolean isNumber(String str) { if (str == null || str.equals("")) return false; char c = str.charAt(0); // 数字 if (c >= '0' && c <= '9') { return true; } else { return false; } }
/** * 获取打印信息 * @param list * @param splitOp * @return */ public static String getPrintInfo(Object[] list,String splitOp){ StringBuffer buffer = new StringBuffer(); for(int i=0;i<list.length;i++){ if(i > 0){buffer.append(splitOp);} buffer.append("{" + list[i] +"}"); } return buffer.toString(); }
}

复制代码


发布于: 2021 年 01 月 14 日阅读数: 21
用户头像

小胜靠智,大胜靠德 2019.06.27 加入

历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666

评论

发布
暂无评论
案例研究之聊聊 QLExpress 源码 (六)