zoukankan      html  css  js  c++  java
  • atitit..sql update语法的词法分析,与语法ast构建

    atitit..sql update语法的词法分析,与语法ast构建

    1. 要使用sql udpate语法的dsl ,需要写个解释器。。 1

    2. 词法分析的实现 1

    2.1. 扫描器的实现 SqlUpExpTokener 1

    2.2. 等号操作符的转态 EqxState 2

    2.3. 单引号的转态 SingleQuoeState 3

    2.4. 逗号操作的转态 CommaState 5

    3. 构建语法树ast 6

    4. 最终输出ast结构 8

    1. 要使用sql udpate语法的dsl ,需要写个解释器。。

    主要应用在orm框架上,使得update 跟个insert的语法统一

    注意的要点::

    单引号的转义实现

    单引号内的逗号,等号的实现。

    作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:1466519819@qq.com

    转载请注明来源: http://blog.csdn.net/attilax

    2. 词法分析的实现

    2.1. 扫描器的实现 SqlUpExpTokener

    s = "fld1=1,fld2='at''t,lax',fld3='val3'";

     

    public List getTokenList(String s) {

    // DslPaserContext context = new DslPaserContext();

    Context4sqlUpExp context = new Context4sqlUpExp();

    context.setState(new iniState());

    int n = 0;

    while (!(context.state instanceof FinishState)) {

    // System.out.println(n);

    // ����

    context.request(s);

    n++;

    if (n > 200)

    break;

    }

    for (Token tk : context.tokenList) {

    // if(tk.value.trim().length()>0)

    System.out.println(tk.value + "===");

    }

    return (Listcontext.tokenList;

    }

     

    2.2. 等号操作符的转态 EqxState 

     

    public class EqxState implements State {

    @Override

    public void handle(String sampleParameterContext context) {

    Context4sqlUpExp ctt = (Context4sqlUpExpcontext;

    char curchar = ctt.curchar;

    if (ctt.lastKeystate instanceof CommaState || ctt.lastKeystate instanceof CommaState || ctt.lastKeystate instanceof com.attilax.dsm.state.iniState) {

    Token tk = new Token();

    tk.value = ctt.curToken.value.trim();

    ctt.tokenList.add(tk);

    ctt.tokenList.add(new Token() {

    {

    this.value = "=";

    }

    });

    ctt.curToken = new Token();

    ctt.lastKeystate=new EqxState();

    else

    ctt.curToken.value += curchar;

    ctt.curcharIndex++;

    }

     

    2.3. 单引号的转态 SingleQuoeState 

    public class SingleQuoeState implements State {

    /* (non-Javadoc)

     * @see com.attilax.designpatter.statepatter.State#handle(java.lang.String)

     */

    @Override

    public void handle(String sampleParameter) {

    // TODO Auto-generated method stub

    }

    /* (non-Javadoc)

     * @see com.attilax.designpatter.statepatter.State#handle(java.lang.String, com.attilax.designpatter.statepatter.Context)

     */

    @Override

    public void handle(String sampleParameterContext context) {

    Context4sqlUpExp ctt = (Context4sqlUpExpcontext;

        char curchar=ctt.curchar

       

       cttSingleQuoeCount++;

     //   ctt.curToken.value+=curchar;

        

        

        //sec queot 

        ifnextAlsoSq(ctt) &&  cttSingleQuoeCount%2==0 )

        {

        ctt.curToken.value=ctt.curToken.value+new StringBuffer().append(curchar).toString();

        ctt.curcharIndex++;

        return;

        

        }

        else   ifpreAlsoSq(ctt) &&  cttSingleQuoeCount%2==1 )

        {

        ctt.curToken.value=ctt.curToken.value+new StringBuffer().append(curchar).toString();

        ctt.curcharIndex++;

        return;

        }

        

        else if(ctt.lastKeystate instanceof EqxState)

        {

        

          ctt.curToken=new Token();

          ctt.lastKeystate=new SingleQuoetStartState();

      

        }

        else if (ctt.lastKeystate instanceof SingleQuoetStartState )//first queot

        {

          Token tk=new Token();

        tk.value=ctt.curToken.value;

        ctt.tokenList.add(tk);

    //    ctt.tokenList.add(new Token(){{ this.value="," ; }});

        ctt.curToken=new Token();

        ctt.lastKeystate=new SingleQuoeEndState();

        }

        

        

        ctt.curcharIndex++;

        

    }

    /**

    @author attilax 老哇的爪子

    @since   p2g m_n_5

     

     */

    private boolean preAlsoSq(Context4sqlUpExp ctt) {

    if( ctt.charArr[ctt.curcharIndex-1]=='\'')

    return true;

    else

    return false;

    }

    /**

    @author attilax 老哇的爪子

     * @param ctt 

    @since   p2g m_c_s

     

     */

    private boolean nextAlsoSq(Context4sqlUpExp ctt) {

    try {

    if( ctt.charArr[ctt.curcharIndex+1]=='\'')

    return true;

    else

    return false;

     

    catch (ArrayIndexOutOfBoundsException e) {

    return false;

    }

    }

    }

     

    2.4. 逗号操作的转态 CommaState

    public void handle(String sampleParameterContext context) {

    Context4sqlUpExp ctt = (Context4sqlUpExpcontext;

    char curchar = ctt.curchar;

      if(ctt.lastKeystate instanceof EqxState  )

    {

      //

      Token tk=new Token();

      tk.value=ctt.curToken.value.trim();

      ctt.tokenList.add(tk);

      

    ctt.tokenList.add(new Token() {

    {

    this.value = ",";

    }

    });

    ctt.curToken = new Token();

    ctt.lastKeystate = new CommaState();

    }

      else if(  ctt.lastKeystate instanceof SingleQuoeEndState)

      {

    ctt.tokenList.add(new Token() {

    {

    this.value = ",";

    }

    });

    ctt.curToken = new Token();

    ctt.lastKeystate = new CommaState(); 

     cttSingleQuoeCount=0;

      }

      else

    {

     ctt.curToken.value+=curchar;

    }

    // ctt.curToken.value+=curchar;

    ctt.curcharIndex++;

    }

     

    3. 构建语法树ast 

    这里使用map作为Ast的存储格式。。最终序列化为json

    public class AstBuilder {

    public Context ctx = new Context();

    // ����ı��ʽ

    public AbstractExpression expression;

    public Map astRoot = new HashMap();

    private String expStr;

    @SuppressWarnings("all")

    public static void main(String[] argsthrows CantFindRitBrack {

    String expStr2 = " method1( param1;\r\n method2(param2);";

    expStr2 = "fld1=1,fld2='at''t,lax',fld3='val3'";

    AstBuilder clt = new AstBuilder(expStr2);

    clt.tkr = new SqlUpExpTokener();

    Object rzt = clt.build();// AST

    System.out.println(JSONObject.fromObject(clt.astRoot).toString(10));

    //System.out.println(JsonUtil4jackjson.buildNormalBinder().toJson(rzt));

    }

    // ���캯������,������

    public AstBuilder(String expStrthrows CantFindRitBrack {

    this.expStr = expStr;

    }

    Tokener tkr;

    List<TokentokenList;

    private Object build() throws CantFindRitBrack {

    tokenList = tkr.getTokenList(this.expStr);

    // ����һ����ջ������������Ⱥ�˳��

    // Stack<AbstractExpression> stack = ctx.stack;

    // ����

    for (int i = 0i < tokenList.size(); i++) {

    Token tk = tokenList.get(i);

    if (tk.value.equals(",")   ) {

    Token key = tokenList.get(i - 3);

    this.astRoot.put(key.valuetokenList.get(i - 1).value);

    }

    ifi==tokenList.size()-1  )

    {

    this.astRoot.put(tokenList.get(i - 2).valuetokenList.get(i).value);

    }

    }

    return this.astRoot;

    // ���������׳���

    // this.expression = stack.pop();

    }

     

     

    4. 最终输出ast结构

    {

              "fld1": "1",

              "fld3": "val3",

              "fld2": "at''t,lax"

    }

     

     

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    控件动态产生器(使用RegisterClasses提前进行注册)
    Delphi编写自定义控件以及接口的使用(做了一个TpgDbEdit)
    Log4delphi使用心得
  • 原文地址:https://www.cnblogs.com/attilax/p/15198981.html
Copyright © 2011-2022 走看看