使用antlr來進行詞法分析,簡單快速.本例子基於antlr3.java
目標:sql
解析以下語句this
load abc/abcd
as test1;
load abd as test2;
{[
begin:
select * from test1;
end;
]};token
store to ddd;字符串
其中分爲三部分,get
load子句,原來的sql子句,store 子句.input
根據需求編寫xxx.g文件,編寫過程當中須要注意:string
1 可使用@number來聲明保存解析出來的字符串的內容.it
2在定義語句時,可使用var=LAB的方式,在接下來的大括號中,直接使用java代碼方式將結果寫入到第一步聲明的變量中.io
下面給出完成的代碼:
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(); } }