Atitit.注解and属性解析(2)---------语法分析 生成AST attilax总结 java .net
Atitit.注解and属性解析(2)---------语法分析 生成AST attilax总结 java .net
3. 识别TerminalExpression和NonterminalExpression 2
1.1. 单词流必须识别为保留字,标识符(变量),常量,操作符(运算符 )和界符五大类 2
1. 应用场景:::因为要使用ui化的注解
String s = "@QueryAdptr(sqlwhere=\" clo1='@p' \",prop2=\"v2\") @Nofilt";
网上马,,子能嘎自实现兰.
作者:: 老哇的爪子 Attilax 艾龙, EMAIL:1466519819@qq.com
转载请注明来源: http://blog.csdn.net/attilax
2. 使用解释器方式来实现生成AST
Context存储的全局上下文环境,AbstractExpression是所有表达式必须继承的接口,TerminalExpression和NonterminalExpression是两个实现。
3. 识别TerminalExpression和NonterminalExpression
1.1. 单词流必须识别为保留字,标识符(变量),常量,操作符(运算符 )和界符五大类
1.2. 操作符(运算符 ):::
() [] -> .
? : |
条件 |
由右向左 |
() [] -> . |
括号(函数等),数组,两种结构成员访问 |
由左向右 |
, |
逗号(顺序) |
||
+ - |
加,减 |
由左向右 |
括号,纺括号,等号
参考
编译器DIY——词法分析 - GodLike - 博客频道 - CSDN.NET.htm
操作符要使用一个状态来描述的...
4. 生成括号操作符表达式
// 构造函数传参,并解析
public Client(String expStr) throws CantFindRitBrack {
// 定义一个堆栈,安排运算的先后顺序
Stack<AbstractExpression> stack = ctx.stack;
// 表达式拆分为字符数组
List<Token> tokenList = (List<Token>) fsmx.getTokenList();
// 运算
//AbstractExpression left = null;
//AbstractExpression right = null;
for (int i =0; i < tokenList.size(); i++) {
Token tk = tokenList.get(i);
switch (tk.value) {
case "(": // comma exp
AbstractExpressionleft3 = stack.pop();
int nextRitBrackIdx=getnextRitBrackIdx(i,tokenList);
List sub=tokenList.subList(i+1, nextRitBrackIdx);
AbstractExpressioncenter = new BracktItemExpression(sub,ctx);
center=stack.pop();
stack.push(new BracktExpression(left3, center));
i=nextRitBrackIdx;
break;
case ",": // comma exp
AbstractExpressionleft = stack.pop();
AbstractExpressionright = new CommaItemExpression(new AttrNameExpression(
tokenList.get(++i).value), new EqxlExpression(
tokenList.get(++i).value), new AttValExpression(
tokenList.get(++i).value));
stack.push(new CommaExpression(left, right));
break;
default: // var in gonsi 公式中的变量
AbstractExpression left2 =new AnnoExpression(tokenList.get(i).value);
stack.push(left2);
}
}
// 把运算结果抛出来
this.expression = stack.pop();
}
private int getnextRitBrackIdx(int start, List<Token> tokenList) throws CantFindRitBrack {
for (int i=start;i<tokenList.size();i++) {
if(tokenList.get(i).value.equals(")"))
return i;
}
throw new CantFindRitBrack("");
}
// start calc开始运算
public Object run() {
System.out.println("--");
//CommaExpression ce=(CommaExpression) expression;
AbstractExpression AST=new ASTrootExpress(expression,new AnnoExpression("tt"));
System.out.println(JSONObject.fromObject(AST).toString(15));
//json
//System.out.println(JsonUtil4jackjson.buildNormalBinder().toJson(
//ce));
return this.expression.interpret(this.ctx);
}
5. 逗号操作符表达式
public class BracktItemExpression extends AbstractExpression {
public BracktItemExpression(List sub2, Context ctx) {
Stack<AbstractExpression> stack = ctx.stack;
List<Token> tokenList = sub2;
for (int i = 0; i < tokenList.size(); i++) {
Token tk = tokenList.get(i);
switch (tk.value) {
case ",": // comma exp
AbstractExpression left = stack.pop();
AbstractExpression right = new CommaItemExpression(
new AttrNameExpression(tokenList.get(++i).value),
new EqxlExpression(tokenList.get(++i).value),
new AttValExpression(tokenList.get(++i).value));
stack.push(new CommaExpression(left, right));
break;
default: // var in gonsi 公式中的变量
AbstractExpression left2 = new CommaItemExpression(
new AttrNameExpression(tokenList.get(i).value),
new EqxlExpression(tokenList.get(++i).value),
new AttValExpression(tokenList.get(++i).value));
stack.push(left2);
}
}
}
6. 等号表达式and 基本元素表达式
7. AST 可视化显示
使用json 缩进15来显示...马个好的tree型显示,都是树放的,马个亘放的...牙马个好的pic lib 输出层次...
{"rootExp": {
"centerExp": {
"leftComma": {
"leftComma": {
"attNameExp": {"attname": "at1"},
"attValExp": {"val": "v1"},
"eqExp": {}
},
"rightCommaExp": {
"attNameExp": {"attname": "at2"},
"attValExp": {"val": " v2 abc "},
"eqExp": {}
}
},
"rightCommaExp": {
"attNameExp": {"attname": "at3"},
"attValExp": {"val": "v3"},
"eqExp": {}
}
},
"nameExp": {"value": "@qu"}
}}