練手寫了個SQLite解析器

2021-08-27 09:49:48 字數 2575 閱讀 8501

書看了大半,天馬行空似懂非懂。返回頭看看感覺沒學到什麼東西,所以還是動手嘗試下。實際這個解析器只是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個變數。如果使用者的變數名長度大於乙個字母,則只取第乙個字母當作...