案例研究之聊聊 QLExpress 源码 (六)
发布于: 2021 年 01 月 14 日
六、解析模块(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
版权声明: 本文为 InfoQ 作者【小诚信驿站】的原创文章。
原文链接:【http://xie.infoq.cn/article/62cce55dfbfcc630e343a5c7e】。文章转载请联系作者。
小诚信驿站
关注
小胜靠智,大胜靠德 2019.06.27 加入
历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666
评论