書看了大半,天馬行空似懂非懂。返回頭看看感覺沒學到什麼東西,所以還是動手嘗試下。實際這個解析器只是sqlite語法的乙個create table語法,而且也沒完全實現(不支援check約束和指定資料庫)。
為了定乙個模子我先寫了乙個create table 的antlr文法(如下)照著做的。
grammar sqlitcreatetable;
@members
}createtablestatment
: 'create' (temp='temp'|temp='temporary')? 'table' ('if' 'not' 'exists')?
name
columnlist ';'?
;columnlist
: '(' column (',' column)* ')' ;
column :
name
type typelimit?
constainst* ;
typelimit
: '(' a=int ( ',' b=int)? ')'
else if($a.text!=null )
} ;type : ?id
;constainst
: 'primary' 'key'
| 'unique'
| 'default' '(' (v=int|v=float|v=string) ')'
| 'not' 'null'
| 'autoincrement'
;name : '[' id ']'
| id
;id : ('a'..'z'|'a'..'z'|'_') ('a'..'z'|'a'..'z'|'0'..'9'|'_')*
;int : '0'..'9'+
;float
: ('0'..'9')+ '.' ('0'..'9')* exponent?
| '.' ('0'..'9')+ exponent?
| ('0'..'9')+ exponent
;comment
: '--' ~('\n'|'\r')* '\r'? '\n'
| '/*' ( options : . )* '*/'
;string
: '\'' ( esc_seq | ~('\\'|'\'') )* '\''
;fragment
exponent : ('e'|'e') ('+'|'-')? ('0'..'9')+ ;
fragment
hex_digit : ('0'..'9'|'a'..'f'|'a'..'f') ;
fragment
esc_seq
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| unicode_esc
| octal_esc
;fragment
octal_esc
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;fragment
unicode_esc
: '\\' 'u' hex_digit hex_digit hex_digit hex_digit
;ws : ( ' '
| '\t'
| '\r'
| '\n'
) ;
生成這個文法的**除錯輸入create table 語句則會輸出表、列、列型別和約束資訊。
sqlite的create table 語法還是比較簡單的,用ll(1)即可以實現了。比較麻煩的還是詞法分析部分,由於 terence parr講解的例子裡面未涉及到關鍵字的識別,所以對於關鍵字的識別我採用了向前看(n+1)來判斷是否為某關鍵字。這個演算法(iskw函式)或許是錯誤的方法請各位有經驗的朋友指教。
" create temporary table\n/*mlcomment*/ if not exists [table_name] (\n[a1] int unique not null,b1 double(22) primary key,c1 string(1,2) autoincrement,e1 float not null,ff char default(0.123) )--slcomment";
在節點的儲存上我採用了簡單的收集需要的節點,而不是異形樹或同型樹之類,遍歷的結果將輸出這樣的
mlcomment
slcomment
tbl--temporaray table_name
column--a1 int unique not null
column--b1 double(22) primary key
column--c1 string(1,2) autoincrement
column--e1 float not null
column--ff string default(0.123)
Atiit 如何手寫詞法解析器
atiit 如何手寫詞法解析器 1.1.通過程式設計直接從正則 nfa dfa 表驅動詞法解析一條龍自動生成。那是用程式自動生成是需要這樣的,自己手寫完全不必要這麼複雜 11.2.狀態轉移表。使用狀態表比較簡單,dfa比較麻煩。dfa其實就是比較高階的狀態表。11.3.然後給了你 框架 這裡以nes...
Sqlite3之Lemon語法解析器初探(1)
看sqlite3原始碼發現用到了lemon語法解析器 然後發現一本好的lemon教程 然後參考裡面的例子 做了一些例子。lemon語法分析器 非常小巧 只依賴於兩個檔案 以下的 實現乙個計算器程式。初步的沒有加入詞法生成器,直接呼叫了parse函式來做運算。中包含注釋,以下並解釋具體點。在生成的檔案...
乙個簡單的表示式解析器
package lipeng.stringdemo 乙個簡單的表示式解析器,這個解析器可以計算由數字 運算子和括號組成的表示式的值,並能處理變數,為了處理簡單,本解析器只支援乙個字母的變數,不區分變數字母的大小寫。因此,最多只能儲存26個變數。如果使用者的變數名長度大於乙個字母,則只取第乙個字母當作...