您好,登錄后才能下訂單哦!
如何進行thriftpy+ply的源碼分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
thrift 使用ply做編譯和解析器,ply是編譯原理入門比較方便的源碼,代碼量少,且python文本就是代碼,解析方便
ex把每個掃面出來的單詞叫統統叫做token,token可以有很多類。對比自然語言的話,英語中的每個單詞都是token,token有很多類,比如non(名詞)就是一個類token,apple就是屬于這個類型的一個具體token。對于某個編程語言來說,token的個數是很有限的,不像英語這種自然語言中有幾十萬個單詞。
lex工具會幫我們生成一個yylex函數,yacc通過調用這個函數來得知拿到的token是什么類型的,但是token的類型是在yacc中定義的。
lex的輸入文件一般會被命名成 .l文件,通過lex XX.l 我們得到輸出的文件是lex.yy.c
yacc是什么呢?
剛才說完lex了,那么yacc呢,教科書上把yacc做的工作叫做syntactic analysis。這次我們翻譯沒有直譯做句法分析,而是叫語法分析,這個翻譯能好一點,意思也基本上比較清楚。
其實我們最開始學習英語的時候老師都會告訴我們英語其實就是“單詞+語法”,這個觀點放到編程語言中很合適,lex提取了單詞,那么是剩下的部分就是如何表達語法。那么yacc做的事情就是這一部分(實際應該說是BNF來做的)。
yacc會幫我們生成一個yyparse函數,這個函數會不斷調用上面的yylex函數來得到token的類型。
yacc的輸入文件一般會被命名成 .y文件,通過yacc -d XX.y我們得到的輸出文件是y.tab.h y.tab.c,前者包含了lex需要的token類型定義,需要被include進 .l文件中
lex和yacc的輸入文件格式
Definition section
%%
Rules section
%%
C code section
.l和.y的文件格式都是分成三段,用%%來分割,三個section的含義是:
Definition Section
這塊可以放C語言的各種各種include,define等聲明語句,但是要用%{ %}括起來。
如果是.l文件,可以放預定義的正則表達式:minus "-" 還要放token的定義,方法是:代號 正則表達式。然后到了,Rules Section就可以通過{符號} 來引用正則表達式
如果是.y文件,可以放token的定義,如:%token INTEGER PLUS ,這里的定一個的每個token都可以在y.tab.h中看到
Rules section
.l文件在這里放置的rules就是每個正則表達式要對應的動作,一般是返回一個token
.y文件在這里放置的rules就是滿足一個語法描述時要執行的動作
不論是.l文件還是.y文件這里的動作都是用{}擴起來的,用C語言來描述,這些代碼可以做你任何想要做的事情
C code Section
main函數,yyerror函數等的定義
lex和yacc能幫我們做什么?
一句話:解釋執行自定義語言。有幾點要注意:
自定義語言的要做的事情必須可以能通過C語言來實現。其實任何計算機能做的事情都可以用C語言來實現,lex和yacc存在的意義在于簡化語言,讓使用者能夠以一種用比較簡單的語言來實現復雜的操作。比如:對于數據庫的查詢肯定有現成的庫可以來完成,但是使用起來比較麻煩,要自己寫成語調用API,編譯才行。如果我們想實自定義一個簡單的語言(比如SQL)來實現操作,這個時候就可以用lex和yacc。
lex和yacc 做的事情只是:用C語言來實現另外一種語言。所以,他沒辦法實現C語言自己,但是可以實現java、python等。當然你可以通過Antlr來實現C語言的解析和執行,如果你這么做的話,C語言程序首先是通過java來執行,然后java又變成了本地語言(C語言)來執行,誰叫我們的操作系統都是C語言實現的呢。
使用lex和yacc我們要做那幾件事情?
定義各種token類型。他們在.y中定義,這些token既會被lex使用到,也會被.y文件中的BNF使用到。
寫詞匯分析代碼。這部分代碼在.l文件(就是lex的輸入文件)中。這塊的定義方式是:正則表達式-->對應操作。如果和yacc一起來使用的話,對應的操作通常是返回一個token類型,這個token的類型要在yacc中提前定義好。
寫BNF。這些東西定義了語言的規約方式。
關于BNF
是一種context-free grammars,請參考:http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form 摘錄:
<symbol> ::= __expression__
<symbol> is a nonterminal
__expression__ consists of one or more sequences of symbols
more sequences are separated by the vertical bar, '|'
Symbols that never appear on a left side are terminals. On the other hand
symbols that appear on a left side are non-terminals and are always enclosed between the pair <>.
在yacc中定義的方式其實是:
<symbol> : __expression__ {operation}
| __expression__ {operation}
operation 是 滿足語法時要執行的C語言代碼,這里的C語言代碼可以使用一些變量,他們是:$$ $1 $2等等。$$代表規約的結果,就是表達式__expression__的值,$1代表的是前面 __expression__ 中出現的各個word。舉個例子:
expr2:
expr3 { $$ == $1; }
| expr2 PLUS expr3 { $$ = plus($1, $3); }
| expr2 MINUS expr3 { $$ = minus($1, $3); }
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。