proto_parser
a python compiler for protobuf
github: https://github.com/LiuRoy/proto_parser
安裝使用
下載代碼進(jìn)入目錄之后執(zhí)行:
pyton setup.py install
當(dāng)前支持直接讀取proto文件構(gòu)造客戶端,使用方法參考example/client.py
import grpc
from protoparser import make_client
client = make_client('./helloworld.proto')
channel = grpc.insecure_channel('localhost:50051')
stub = client.GreeterStub(channel)
response = stub.SayHello(client.HelloRequest(name='abc'))
print("Greeter client received: " + response.name)
代碼講解
本人接觸到的rpc通信協(xié)議有thrift和protobuf竞惋,兩者很類似。雖然原生的thrift和protobuf編譯器針對不同語言都只能將接口文件轉(zhuǎn)換為可以使用的中間文件漩勤,但不同于其他靜態(tài)語言膘融,python的動(dòng)態(tài)類型可以很方便的將接口文件直接加載使用粘室,例如thrift的python第三方庫thriftpy问词,使用起來比原生庫要方便很多瓤逼。但個(gè)人覺得thriftpy自己造輪子的成分過多踢关,client伞鲫、servier以及底層的通信實(shí)現(xiàn)全部重寫了一套,不是很確定能否和原生框架無縫對接签舞。參考thriftpy秕脓,自己也實(shí)現(xiàn)了一個(gè)簡單的protobuf編譯器,解析生成的結(jié)果也盡量用原生對象儒搭。
左邊是官方提供的protobuf使用流程吠架,具體參考鏈接http://www.grpc.io/docs/quickstart/python.html,可以看出每次修改完protobuf文件都需要用protobuf compiler重新生成中間文件搂鲫,使用上不是很友好傍药,期望的目標(biāo)是右邊那樣,只需要重啟一下進(jìn)程就可以了魂仍。
詞法分析
詳見文件lexer.py拐辽,直接使用第三方庫ply做的詞法解析。詞法分析算法上很復(fù)雜擦酌,但是使用起來卻很直觀俱诸,就是將輸入文本按照自定義的規(guī)則解析為一個(gè)一個(gè)的符號(hào)。詳細(xì)內(nèi)容可以參考lex文檔赊舶。
語法分析
詳見文件grammar.py睁搭,也是直接使用的第三方庫ply做的語法分析,具體的文法參考的thriftpy笼平,thriftpy的語法解析用到了很多全局變量园骆,雖然實(shí)現(xiàn)簡單而且好理解,最大的缺陷就是不是線程安全寓调,不能支持多線程锌唾,所以具體的實(shí)現(xiàn)上做了一些調(diào)整。調(diào)整內(nèi)容有一下:
- 語法上為proto3的子集夺英,protoparser解析沒有問題的接口文件原生編譯器一定能解析鸠珠,反之不一定
- enum packed singular import reserved option oneof等關(guān)鍵詞不支持,因?yàn)橛貌簧锨雉铮砸簿蛻械脤?shí)現(xiàn)
- 不支持在message仲嵌套定義message渐排,但是可以使用已經(jīng)定義的message類型
- 因?yàn)槭窃谧詈笞龅姆?hào)檢查,支持用到的符號(hào)在后面定義
沒有編譯基礎(chǔ)的童鞋閱讀ply的yacc文檔可能比較迷茫灸蟆,建議看一下編譯原理仲關(guān)于語法分析相關(guān)的概念和算法驯耻,在此推薦胡倫均的編譯原理,每一個(gè)概念都會(huì)給很多例子解釋炒考,很適合入門學(xué)習(xí)可缚。至于輪子哥推薦的parsing techniques以及龍虎鯨書,可以作為進(jìn)階學(xué)習(xí)使用斋枢。
ply的語法分析使用了LRLR算法帘靡,這是一種至下而上的分析法,也就是從給定的輸入串開始瓤帚,根據(jù)文法規(guī)則逐步進(jìn)行歸約描姚,直至歸約到文法開始的符號(hào)涩赢,或者說從語法樹的末端開始,步步向上歸約轩勘,直至根節(jié)點(diǎn)的分析方法筒扒。自定義的函數(shù)也是在對應(yīng)的文法歸約的時(shí)候執(zhí)行,理解了這一點(diǎn)對使用ply很重要绊寻,定義好文法之后花墩,按照文法一步一步實(shí)現(xiàn)歸約函數(shù),寫語法解析也是一件很有意思的事情澄步。
類型轉(zhuǎn)換
詳見objects.py和parser.py冰蘑,自己實(shí)現(xiàn)的語法解析直接解析為原生的對象,而是按照自己的文法邏輯先解析成objects.py仲定義的類型村缸,然后在parser.py仲做了一些轉(zhuǎn)換祠肥,由于沒有相關(guān)的文檔,實(shí)在是不清楚原生對象的使用方法王凑,所以盲人摸象般的寫了最簡單類型的轉(zhuǎn)關(guān)規(guī)則搪柑。本來以為python動(dòng)態(tài)類型用起來很美好,但是真的大量使用的時(shí)候索烹,不僅不好調(diào)試工碾,而且連自己也看不懂寫了啥玩意兒。歡迎有興趣的同伴提修改建議百姓。