atitit.java解析sql語言解析器解譯器的實現,atitit.javasql
atitit.java解析sql語言解析器解譯器的實現
1. 解析sql的本質:實現一個4gl dsl程式設計語言的編譯器 1
2. 解析sql的主要的流程,詞法分析,而後進行文法分析,語義分析,構建sql的AST 1
3. 詞法分析器 2
4. 文法分析器--ANTLR 2
5. Eclipse外掛程式,,ANTLR Studio 3
6. 一個基於javacc實現的解析器JSqlParser0.7(yr2011), 3
7. 例子代碼-----解析sql表格列的名稱and類型 3
8. }Sql的曆史 4
9. 解析select語句 4
10. zql,JSqlParser,General sql parser. 5
11. ANTLR實現的SQL解析器 - OQL 5
12. Javacc/AST簡單的介紹 5
13. SQLJEP http://sqljep.sourceforge.net/ 5
14. Sql產生SqlBuilder ,Querydsl ,hb 6
15. 俄的總結: 還湊火JSqlParser0.7走行蘭. 6
16. 參考 6
1. 解析sql的本質:實現一個4gl dsl程式設計語言的編譯器
Sql走十一個4gl dsl,..SQL解析器基本上走十一個編譯器實現
2. 解析sql的主要的流程,詞法分析,而後進行文法分析,語義分析,構建sql的AST
首先要進行詞法分析,而後進行文法分析,語義分析
詞法分析,and 文法分析>>>.
詞法分析即將輸入的語句進行分詞(token),解析出每個token的意義。分詞的本質便是Regex的匹配過程,比較流行的分詞工具應該是lex,通 過簡單的規則制定,來實現分詞。Lex一般和yacc結合使用。關於lex和yacc的基礎知識請參考Yacc 與Lex 快速入門- IBM。如果想深入學習的話,可以看下《LEX與YACC》。
然而Mysql並沒有使用lex來實現詞法分析,但是文法分析卻用了yacc,而yacc需要詞法分析函數yylex,
不過ANTLR更多簡化...
作者:: 老哇的爪子 Attilax 艾龍, EMAIL:1466519819@qq.com
轉載請註明來源: http://blog.csdn.net/attilax
3. 詞法分析器
MySQL的詞法分析器是手工打造的。
文法分析器的入口函數是MYSQLparse,詞法分析器的入口函數是MYSQLlex。
2. 詞法分析中會檢查token是否為關鍵字。
最直接的做法是弄個大的關鍵字數組,進行折半尋找
1.1 詞法分析器(Lexer)
詞法分析器又稱為 Scanner,Lexical analyser和Tokenizer。程式設計語言通常由關鍵字和嚴格定義的文法結構組成。編譯的最終目的是將程式設計語言的高層指令翻譯成物力機器或 虛擬機器可以執行的指令。此法分析器的工作是分析量化那些本來毫無意義的字元流,將他們翻譯成離散的字元組(也就是一個一個的Token)括關鍵字,標識 符,符號(symbols)和操作符供文法分析器使用。
,Lexer不關心所產生的單個Token的文法意義及其與上下文之間的關係
ANTLR將上述兩者結合起來,它允許我們定義識別字元流的詞法規則和用於解釋Token流的詞法分析規則。然後,ANTLR將根據使用者提供的文法檔案自 動產生相應的詞法/文法分析器。
4. 文法分析器--ANTLR
也因為不想和以下推自動機為原理的YACC/LEX產生的一大堆整數表打交道,我選擇了另一個開源的LL(K)文法/詞法分析器—ANTLR。
之前YACC/LEX顯得過於學院派,而以LL(k)為基礎的ANTLR雖然在效率上還略有不足
Lexer不關心所產生的單個Token的文法意義及其與上下文之間的關係,而這就是Parser的工作。文法分析器將收到的Tokens組織起來,並轉換成為目標語言文法定義所允許的序列。
無論是Lexer還是Parser都是一種辨識器,Lexer是字元序列辨識器而Parser是Token序列辨識器。他們在本質上是類似的東西,而只是在分工上有所不同而已。
ANTLR將上述兩者結合起來,它允許我們定義識別字元流的詞法規則和用於解釋Token流的詞法分析規則。然後,ANTLR將根據使用者提供的文法檔案自 動產生相應的詞法/文法分析器。使用者可以利用他們將輸入的文本進行編譯,並轉換成其他形式(如AST—Abstract Syntax Tree,抽象的文法樹)。構建sql的AST
5. Eclipse外掛程式,,ANTLR Studio
為了更好的使用ANTLR,你還可以下載ANTLR的Eclipse外掛程式來協助你完成工作。ANTLR Studio
6. 一個基於javacc實現的解析器JSqlParser0.7(yr2011),
它可以把SQL語句轉換為Java對象,由於JsqlParser是使用JavaCC做文法分析的,而本身JavaCC就支援JJTree...如是就寫了個小工具SQLParser,將產生的對象以樹的形式呈現出來^
JSqlParser存在的問題及解決
JSqlParser是一個SQL語句的解析器,包括常用的一些SQL語句,insert,update,select,delete等,但相容的文法有限,比如括弧,或者一些複雜的結構等。 對於逸出字元的處理
7. 例子代碼-----解析sql表格列的名稱and類型
final String sql = filex.read("c:\\pojo.sql", "gbk");
new SqlParseO7(sql)
this.sqlParseO7.parse(new Closure()
public void parse(Closure c) throws JSQLParserException {
CCJSqlParserManager parserManager = new CCJSqlParserManager();
// String statement =
// "CREATE TABLE mytab (mycol a (10, 20) c nm g, mycol2 mypar1 mypar2 (23,323,3) asdf ('23','123') dasd, "
// + "PRIMARY KEY (mycol2, mycol)) type = myisam";
CreateTable createTable = (CreateTable) parserManager
.parse(new StringReader(this.sql));
List columnDefinitions = createTable.getColumnDefinitions();
String tabName = createTable.getTable().getName();
// System.out.println(columnDefinitions.size());// 獲得欄位總數.
for (Object object : columnDefinitions) {
ColumnDefinition col = (ColumnDefinition) object;
Object[] oa = { col.getColumnName(),
col.getColDataType().getDataType(), tabName };
c.execute(oa);
}
8. }Sql的曆史9. 解析select語句
Statement stat = new CCJSqlParserManager().parse(new StringReader(
"select * from a where 姓名='崔永遠'"));
Select select = (Select) stat;
Expression where = ((PlainSelect) select.getSelectBody()).getWhere();
WhereExpressionVisitor visitor = new WhereExpressionVisitor(rowMeta, where);
for (int i = 0; i < data.length; i++) {
Object result = visitor.eval(data[i]);
if (result instanceof Boolean && ((Boolean) result).booleanValue()) {
System.out.print("通過=====>");
} else {
System.out.print("不通過=====>");
}
System.out.println(StringUtils.join(data[i], ","));
}
10. zql,JSqlParser,General sql parser. 11. ANTLR實現的SQL解析器 - OQL12. Javacc/AST簡單的介紹
JavaCC 是一個代碼產生器,可以根據輸入的語言定義輸出一個詞法分析器和解析器,JavaCC 輸出的代碼是合法的可編譯Java代碼.解析器和詞法分析器本身就是一個冗長而複雜的組件,手工編寫一個這樣的程式需要仔細考慮各條件的相互作用,總的來說,通過javacc完成一些字串的分析,還是比較方便,現在普遍使用AST了。
13. SQLJEP http://sqljep.sourceforge.net/
SQLJEP 是一個用來解析和模擬執行SQL語句的Java類庫。支援幾乎所有 Oracle 和 MaxDB 的函數。SQLJEP 使用 JavaCC 來做詞法分析。
14. Sql產生SqlBuilder ,Querydsl ,hb
3.SqlBuilder http://openhms.sourceforge.net/sqlbuilder/
SqlBuilder 是一個Java的類庫,它試圖幫你避免在Java程式內直接書寫SQL查詢的痛苦。你只需要使用 SqlBuilder 的方法,它就可以幫你產生對應的 SQL 資料庫查詢語句,例如下面一個SQL語句:
15. 俄的總結: 還湊火JSqlParser0.7走行蘭.16. 參考
Java 實現對Sql語句解析 - 翠竹林 - 部落格園.htm
SQL 文法解譯器jsqlparser - serv - ITeye技術網站.htm
Hibernate原始碼分析 - 青火的筆記 - 記筆記 - 私塾線上 - 只做精品視頻課程服務.htm
開源文法分析器--ANTLR - 薛笛的專欄 - 部落格頻道 - CSDN.NET.htm
高分助:Java自訂指令碼語言解譯器的設計實現思路
這個你有編譯原理基礎的話,就在找本編譯原理的書看,會想起來怎麼做的。這個解析過程並不太難。
如果你沒學過編譯原理,那就別看了,短時間內掌握不了的。可以參考這個思路:
建立一個替換表:
{”如果“ : "if", "並且" : "&&", "則" : "{", "如果結束" : "}"},可能還有很多別的什麼的吧
然後對程式進行替換
替換後為:
C = A + B
if(C > 0 && A > 5){
D=100
if(C > 5 && B > 10){
D=200
}
}
然後進行一些文法補全的操作什麼的,爭取轉換為javascript之類的指令碼語言。這樣就能執行了
對於變數那個判斷,可以對於變數進行遍曆,尋找全部賦值操作左邊的變數,就是被賦值變數了,其他的就是可變的
什命令是java語言的解譯器?
Java解譯器可用來直接解釋執行Java位元組代碼,具體命令列格式如下:
C:\>java options className
argumentsclassName必須包括所有軟體包資訊。不僅有類名本身,還有Java 解譯器所期望的類名(不是Java位元組代碼的檔案名稱),所有在解譯器環境下啟動並執行類都必須包括解譯器第一次調用時所需的main成員函數,用以傳遞命令所帶的變數。public static void main(string args[]){ ......}
下面Java解譯器的所有選項。-cs -checksource 此選項讓解譯器重編譯Java源檔案已更新的類--重編譯已改變過了的類。-classpath path 此選項重寫CLASSPATH環境變數,告訴Java在哪裡能找到類庫。如果其中用冒號分開,則可能包含多個目錄。 -mx x 此選項設定記憶體配置池的最大值。所指定的池必須大於1,000位元組。
另外“K”,“M”可附加在數字上指定是KB還是MB。預設值是16MB。 -ms x 此選項設定記憶體配置池的最小值。所指寂的池必須大於1,000位元組。
另外,“K”,“M”可加在數字上指定的是KB還是MB。預設值是1MB。-noasyncgc 此選項關閉非同步無用單元收集功能,只有在程式中調用它或記憶體溢出的時候,無用單元收集才會被啟用。
-ss x 此選項將C線程棧的最大值設定為x , x 必須大於1KB,其設定方式同 -ms。 -oss x 此選項設定Java堆棧最大值為x。
-v,-verbose 此選項告知Java每當類被調用之時, 向標準輸出裝置輸出資訊。 -verify 此選項告知Java在所有代碼上使用校正。-verifyremote 此選項告知Java 僅僅對類載入器所載入的類進行校正。-noverify 此選項告知Java不進行校正。 -verbosegc 此選項告知Java讓無用單元收集器在它釋放記憶體時顯示一條資訊。 -t 此選項在Java-g解譯器中是可用的,並把執行的情況逐條列印出來。 -debug 此選項允許Java調試器與本次Java 解譯器會話相聯結。它運行時,Java會顯示一個密碼,用於啟動這次偵錯工作階段
-D propName=newVal 此選項允許使用者在運行時改變屬性值