antlr lexer二次开发实例

使用antlr来进行词法分析,简单快速.本例子基于antlr3.

目标:

解析如下语句

load abc/abcd
  as  test1;
load abd as test2;
{[
begin:
select * from test1;
end;
]};

store to ddd;

其中分为三部分,

load子句,原来的sql子句,store 子句.

根据需求编写xxx.g文件,编写过程中需要注意:

1 可以使用@number来声明保存解析出来的字符串的内容.

2在定义语句时,可以使用var=LAB的方式,在接下来的大括号中,直接使用java代码方式将结果写入到第一步声明的变量中.

下面给出完成的代码:

lexer grammar ExtendSQL;
options{
filter=true;
}
@members{
    private java.util.Map<String,String> params;
    public ExtendSQL(CharStream input,java.util.Map<String,String> params){
        this(input);
        this.params=params;
    }
}
fragment
LoadSeg    :    'load' WS pi=PATH WS 'as' WS i=ID WS?';'{
    String inputs=null;
    if(!(null==params.get("inputs")||params.get("inputs").length()==0)){
        inputs=params.get("inputs")+";";
    }else{
        inputs="";
    }
    params.put("inputs",(inputs+pi.getText()+","+i.getText()));
};
fragment
SQLSeg    :    '{[' m=ANY ']};'{
    String str=m.getText();
    int start=str.indexOf("begin:");
    int end=str.indexOf("end;");
    if(start<end){
        params.put("sql",str.substring(start+6,end));
    }
};
fragment
ANY    :    WS? 'begin:'.*'end;'WS?;
fragment
SaveSeg    :    'store to' WS po=PATH WS?';'{
    params.put("output",po.getText());
};
fragment
WS    :    (' ' |'\t' |'\r' |'\n' )+;
fragment
ID     :     ('a'..'z' |'A'..'Z' |'_' ) ('a'..'z' |'A'..'Z' |'_' |'0'..'9' )*;
fragment
FILENAME:    ('.' | '..' |ID);
fragment
PATH    :    ('hdfs://' |'file://' |'/')?  (FILENAME '/'?)+;
fragment
CLASSNAME
    :    ID ('.' ID)*;
//fragment
Exit    :    (LoadSeg EOF)+ |SQLSeg EOF |(SaveSeg EOF);
fragment
EOL: '\n' | '\r' | '\r\n';

 

验证的java代码如下:

 public static void main(String[] args) {
        System.out.println("Hello world");

        try {
            String filename = "src/main/resources/errsql1.out";
            InputStream in = new FileInputStream(filename);
            ANTLRInputStream input = new ANTLRInputStream(in);
            Map<String, String> paras = new HashMap<String, String>();
            ExtendSQL lexer = new ExtendSQL(input, paras);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            tokens.fill();
            for (String key : paras.keySet()) {
                System.out.print(key+":");
                System.out.println(paras.get(key));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

 

转载于:https://my.oschina.net/u/937015/blog/757432

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值