|
@@ -47,7 +47,7 @@ public class XbcExpParser {
|
|
|
public Set<String> getParamSet() {
|
|
|
return paramSet;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public List<XbcExpDrawnInfoVo> getDrawnInfoVos() {
|
|
|
if(es == null) {
|
|
|
return null;
|
|
@@ -57,50 +57,81 @@ public class XbcExpParser {
|
|
|
|
|
|
public XbcExpExpTree parse() {
|
|
|
es = new XbcExpScanner(expStr, mkDiv);
|
|
|
- XbcExpExpTree firstExp = null;
|
|
|
- XbcExpExpTree exp = null;
|
|
|
- XbcExpExpTree lastExp = null;
|
|
|
token = es.readToken();
|
|
|
- while(token != XbcExpToken.EOF_TT) {
|
|
|
- switch(token) {
|
|
|
- case XbcExpToken.EXPNAME_TT: // variable-name
|
|
|
- case XbcExpToken.INT_TT: // integer
|
|
|
- case XbcExpToken.DBL_TT: // double
|
|
|
- case XbcExpToken.STR_TT: // string
|
|
|
- case XbcExpToken.LPRN_TT: // (
|
|
|
- case XbcExpToken.SELFMNS_TT: // --
|
|
|
- case XbcExpToken.SELFPLS_TT: // ++
|
|
|
- case XbcExpToken.PLS_TT: // +
|
|
|
- case XbcExpToken.MNS_TT: // -
|
|
|
- case XbcExpToken.BNOT_TT: // ~
|
|
|
- case XbcExpToken.NOT_TT: // !
|
|
|
- exp = readExpTree();
|
|
|
- break;
|
|
|
- case XbcExpToken.DIV0_TT: // div0
|
|
|
- exp = readDiv0Exp();
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new XbcExpParseException("未知的符号: " + XbcExpToken.getTokenName(token) + ", 公式: " + expStr);
|
|
|
- }
|
|
|
- if(firstExp == null) {
|
|
|
- firstExp = exp;
|
|
|
- }
|
|
|
- if(lastExp != null) {
|
|
|
- lastExp.next = exp;
|
|
|
- }
|
|
|
- lastExp = exp;
|
|
|
- //token = es.readToken();
|
|
|
- if(token == XbcExpToken.EOF_TT) {
|
|
|
+ XbcExpExpTree exp = readExpSequence();
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readExpSequence() {
|
|
|
+ XbcExpExpTree exp = readNextExp();
|
|
|
+ XbcExpExpTree next = exp;
|
|
|
+ while(next != null && next.next != null) {
|
|
|
+ next = next.next;
|
|
|
+ }
|
|
|
+ while(next != null) {
|
|
|
+ next.next = readNextExp();
|
|
|
+ if(next.next == null) {
|
|
|
break;
|
|
|
}
|
|
|
- if(token != XbcExpToken.SEMI_TT) { // 用分号来分隔多个表达式
|
|
|
- throw new XbcExpParseException("多余的符号: " + XbcExpToken.getTokenName(token) + ", 公式: " + expStr);
|
|
|
- }
|
|
|
- while(token == XbcExpToken.SEMI_TT) {
|
|
|
- match(XbcExpToken.SEMI_TT);
|
|
|
+ while(next.next != null) {
|
|
|
+ next = next.next;
|
|
|
}
|
|
|
}
|
|
|
- return firstExp;
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readNextExp() {
|
|
|
+ XbcExpExpTree exp = null;
|
|
|
+ switch(token) {
|
|
|
+ case XbcExpToken.EXPNAME_TT: // variable-name
|
|
|
+ case XbcExpToken.INT_TT: // integer
|
|
|
+ case XbcExpToken.DBL_TT: // double
|
|
|
+ case XbcExpToken.STR_TT: // string
|
|
|
+ case XbcExpToken.LPRN_TT: // (
|
|
|
+ case XbcExpToken.SELFMNS_TT: // --
|
|
|
+ case XbcExpToken.SELFPLS_TT: // ++
|
|
|
+ case XbcExpToken.PLS_TT: // +
|
|
|
+ case XbcExpToken.MNS_TT: // -
|
|
|
+ case XbcExpToken.BNOT_TT: // ~
|
|
|
+ case XbcExpToken.NOT_TT: // !
|
|
|
+ case XbcExpToken.NEW_TT: // new
|
|
|
+ case XbcExpToken.INVOKE_TT:
|
|
|
+ exp = readAsnExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.FOR_TT: // for
|
|
|
+ exp = readForExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.BREAK_TT: // break;
|
|
|
+ exp = readBreakExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.CONTINUE_TT: // continue
|
|
|
+ exp = readContinueExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.WHILE_TT: // while
|
|
|
+ exp = readWhileExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.IF_TT: // if
|
|
|
+ exp = readIfExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.LSQB_TT: // {
|
|
|
+ exp = readBlockExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.DIV0_TT: // div0
|
|
|
+ exp = readDiv0Exp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.EXIT_TT: // exit
|
|
|
+ exp = readExitExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.SEMI_TT:
|
|
|
+ match(XbcExpToken.SEMI_TT);
|
|
|
+ exp = new XbcExpExpTree(XbcExpExpOpKind.NULL_OK);
|
|
|
+ break;
|
|
|
+ case XbcExpToken.EOF_TT:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new XbcExpParseException("未知的符号: " + XbcExpToken.getTokenName(token) + ", 公式: " + expStr);
|
|
|
+ }
|
|
|
+ return exp;
|
|
|
}
|
|
|
|
|
|
private void match(int expectedToken) {
|
|
@@ -109,7 +140,64 @@ public class XbcExpParser {
|
|
|
}
|
|
|
token = es.readToken();
|
|
|
}
|
|
|
+
|
|
|
+ private XbcExpExpTree readExitExp() {
|
|
|
+ match(XbcExpToken.EXIT_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.EXIT_OK);
|
|
|
+ exp.lchild = readAsnExp();
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readInvokeExp() {
|
|
|
+ String tokenContent = es.getTokenContent();
|
|
|
+ match(XbcExpToken.INVOKE_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.INVOKE_OK);
|
|
|
+ exp.value = tokenContent;
|
|
|
+ exp.params = new ArrayList<>();
|
|
|
+
|
|
|
+ match(XbcExpToken.LPRN_TT);
|
|
|
+ while(token != XbcExpToken.RPRN_TT) {
|
|
|
+ XbcExpExpTree pexp = readAsnExp();
|
|
|
+ exp.params.add(pexp);
|
|
|
+ if(token == XbcExpToken.CMM_TT) {
|
|
|
+ match(token);
|
|
|
+ if(token == XbcExpToken.RPRN_TT) {
|
|
|
+ throw new XbcExpParseException("解析函数【" + tokenContent + "】的参数时出错。" + " 公式: " + expStr);
|
|
|
+ }
|
|
|
+ } else if(token != XbcExpToken.RPRN_TT) {
|
|
|
+ throw new XbcExpParseException("解析函数【" + tokenContent + "】的参数时出错。" + " 公式: " + expStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ match(XbcExpToken.RPRN_TT);
|
|
|
+
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
|
|
|
+ private XbcExpExpTree readNewExp() {
|
|
|
+ String tokenContent = es.getTokenContent();
|
|
|
+ match(XbcExpToken.NEW_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.NEW_OK);
|
|
|
+ exp.value = tokenContent;
|
|
|
+ exp.params = new ArrayList<>();
|
|
|
+
|
|
|
+ match(XbcExpToken.LPRN_TT);
|
|
|
+ while(token != XbcExpToken.RPRN_TT) {
|
|
|
+ XbcExpExpTree pexp = readAsnExp();
|
|
|
+ exp.params.add(pexp);
|
|
|
+ if(token == XbcExpToken.CMM_TT) {
|
|
|
+ match(token);
|
|
|
+ if(token == XbcExpToken.RPRN_TT) {
|
|
|
+ throw new XbcExpParseException("解析函数【" + tokenContent + "】的参数时出错。" + " 公式: " + expStr);
|
|
|
+ }
|
|
|
+ } else if(token != XbcExpToken.RPRN_TT) {
|
|
|
+ throw new XbcExpParseException("解析函数【" + tokenContent + "】的参数时出错。" + " 公式: " + expStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ match(XbcExpToken.RPRN_TT);
|
|
|
+
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
private XbcExpExpTree readDiv0Exp() {
|
|
|
match(XbcExpToken.DIV0_TT);
|
|
|
XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.DIV0_OK);
|
|
@@ -119,9 +207,97 @@ public class XbcExpParser {
|
|
|
exp.lchild = texp;
|
|
|
return exp;
|
|
|
}
|
|
|
+
|
|
|
+ private XbcExpExpTree readBlockExp() {
|
|
|
+ match(XbcExpToken.LSQB_TT);
|
|
|
+ XbcExpExpTree exp = null;
|
|
|
+ if(token == XbcExpToken.RSQB_TT) {
|
|
|
+ match(XbcExpToken.RSQB_TT);
|
|
|
+ exp = new XbcExpExpTree(XbcExpExpOpKind.NULL_OK);
|
|
|
+ } else {
|
|
|
+ exp = readNextExp();
|
|
|
+ XbcExpExpTree tail = exp;
|
|
|
+ XbcExpExpTree next = exp;
|
|
|
+ while(tail.next != null) {
|
|
|
+ tail = tail.next;
|
|
|
+ }
|
|
|
+ while(token != XbcExpToken.RSQB_TT) {
|
|
|
+ if(next == null) {
|
|
|
+ throw new XbcExpParseException("没有结束的\"}\"。 公式: " + expStr);
|
|
|
+ }
|
|
|
+ next = readNextExp();
|
|
|
+ tail.next = next;
|
|
|
+ tail = next;
|
|
|
+ if(next != null) {
|
|
|
+ while(tail.next != null) {
|
|
|
+ tail = tail.next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ match(XbcExpToken.RSQB_TT);
|
|
|
+ }
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readIfExp() {
|
|
|
+ match(XbcExpToken.IF_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.IF_OK);
|
|
|
+ match(XbcExpToken.LPRN_TT);
|
|
|
+ exp.lchild = readAsnExp();
|
|
|
+ match(XbcExpToken.RPRN_TT);
|
|
|
+ exp.mchild = readNextExp();
|
|
|
+ if(token == XbcExpToken.ELSE_TT) {
|
|
|
+ match(XbcExpToken.ELSE_TT);
|
|
|
+ exp.rchild = readNextExp();
|
|
|
+ }
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readBreakExp() {
|
|
|
+ match(XbcExpToken.BREAK_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.BREAK_OK);
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readContinueExp() {
|
|
|
+ match(XbcExpToken.CONTINUE_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.CONTINUE_OK);
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
|
|
|
- private XbcExpExpTree readExpTree() {
|
|
|
- XbcExpExpTree exp = readAsnExp();
|
|
|
+ private XbcExpExpTree readWhileExp() {
|
|
|
+ match(XbcExpToken.WHILE_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.WHILE_OK);
|
|
|
+ match(XbcExpToken.LPRN_TT);
|
|
|
+ exp.lchild = readAsnExp();
|
|
|
+ match(XbcExpToken.RPRN_TT);
|
|
|
+ exp.body = readNextExp();
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private XbcExpExpTree readForExp() {
|
|
|
+ match(XbcExpToken.FOR_TT);
|
|
|
+ XbcExpExpTree exp = new XbcExpExpTree(XbcExpExpOpKind.FOR_OK);
|
|
|
+ match(XbcExpToken.LPRN_TT);
|
|
|
+ if(token != XbcExpToken.SEMI_TT) {
|
|
|
+ exp.lchild = readAsnExp();
|
|
|
+ } else {
|
|
|
+ exp.lchild = null;
|
|
|
+ }
|
|
|
+ match(XbcExpToken.SEMI_TT);
|
|
|
+ if(token != XbcExpToken.SEMI_TT) {
|
|
|
+ exp.mchild = readAsnExp();
|
|
|
+ } else {
|
|
|
+ exp.mchild = null;
|
|
|
+ }
|
|
|
+ match(XbcExpToken.SEMI_TT);
|
|
|
+ if(token != XbcExpToken.SEMI_TT) {
|
|
|
+ exp.rchild = readAsnExp();
|
|
|
+ } else {
|
|
|
+ exp.rchild = null;
|
|
|
+ }
|
|
|
+ match(XbcExpToken.RPRN_TT);
|
|
|
+ exp.body = readNextExp();
|
|
|
return exp;
|
|
|
}
|
|
|
|
|
@@ -503,6 +679,7 @@ public class XbcExpParser {
|
|
|
|
|
|
private boolean isPfEt(int t) {
|
|
|
switch(t) {
|
|
|
+ case XbcExpToken.PRD_TT:
|
|
|
case XbcExpToken.LPRN_TT:
|
|
|
return true;
|
|
|
}
|
|
@@ -535,6 +712,17 @@ public class XbcExpParser {
|
|
|
}
|
|
|
while(isPfEt(token)) {
|
|
|
switch(token) {
|
|
|
+ case XbcExpToken.PRD_TT:
|
|
|
+ match(token);
|
|
|
+ if(token != XbcExpToken.EXPNAME_TT) {
|
|
|
+ throw new XbcExpParseException("点号后面应该接一个成员变量名或方法名。" + " 公式: " + expStr);
|
|
|
+ }
|
|
|
+ XbcExpExpTree exp2 = new XbcExpExpTree(XbcExpExpOpKind.PRD_OK);
|
|
|
+ exp2.lchild = exp;
|
|
|
+ exp2.value = es.getTokenContent();
|
|
|
+ match(token);
|
|
|
+ exp = exp2;
|
|
|
+ break;
|
|
|
case XbcExpToken.LPRN_TT:
|
|
|
match(token);
|
|
|
XbcExpExpTree exp1 = new XbcExpExpTree(XbcExpExpOpKind.FUNC_OK);
|
|
@@ -566,9 +754,17 @@ public class XbcExpParser {
|
|
|
switch(token) {
|
|
|
case XbcExpToken.EXPNAME_TT:
|
|
|
String tokenContent = es.getTokenContent();
|
|
|
- exp = XbcExpExpTree.newIdExptree(tokenContent);
|
|
|
- if(!removedParamSet.contains(tokenContent)) {
|
|
|
- paramSet.add(tokenContent);
|
|
|
+ if(tokenContent.equals("true")) {
|
|
|
+ exp = XbcExpExpTree.newConstBoolExptree(true);
|
|
|
+ } else if(tokenContent.equals("false")) {
|
|
|
+ exp = XbcExpExpTree.newConstBoolExptree(false);
|
|
|
+ } else if(tokenContent.equals("null")) {
|
|
|
+ exp = XbcExpExpTree.newConstNullExptree();
|
|
|
+ } else {
|
|
|
+ exp = XbcExpExpTree.newIdExptree(tokenContent);
|
|
|
+ if(!removedParamSet.contains(tokenContent)) {
|
|
|
+ paramSet.add(tokenContent);
|
|
|
+ }
|
|
|
}
|
|
|
match(token);
|
|
|
break;
|
|
@@ -586,9 +782,15 @@ public class XbcExpParser {
|
|
|
break;
|
|
|
case XbcExpToken.LPRN_TT:
|
|
|
match(token);
|
|
|
- exp = readExpTree();
|
|
|
+ exp = readAsnExp();
|
|
|
match(XbcExpToken.RPRN_TT);
|
|
|
break;
|
|
|
+ case XbcExpToken.NEW_TT: // new
|
|
|
+ exp = readNewExp();
|
|
|
+ break;
|
|
|
+ case XbcExpToken.INVOKE_TT:
|
|
|
+ exp = readInvokeExp();
|
|
|
+ break;
|
|
|
default:
|
|
|
throw new XbcExpParseException("读取表达式出错: " + es.getTokenContent() + ", 公式: " + expStr);
|
|
|
}
|