Python運(yùn)行的過程中不直接用到的相關(guān)函數(shù)的介紹
我們都知道在Python運(yùn)行的過程中是需要不直接的利用到Grammar文件的相關(guān)內(nèi)容進(jìn)而進(jìn)行相關(guān)的語法分析,那么如果你對Python運(yùn)行的實際操作感興趣的話,你就可以瀏覽我們的文章對其有一個更好的了解。過程中會依賴graminit.c/graminit.h中的數(shù)據(jù)結(jié)構(gòu)來進(jìn)行語法分析
前面提到了在Python的源代碼目錄下面有一個Grammar目錄,里面只有一個文件Grammar,以BNF的語法定義了Python的全部語法。拿if語句舉例來說:
- if_stmt: 'if' test ':' suite
('elif' test ':' suite)* ['else' ':' suite]
上面的語句可以這樣理解,if語句是if關(guān)鍵字+邏輯表達(dá)式+ ‘:’+語句塊(suite)后面跟上0至多個elif語句并以else語句結(jié)束。在最左邊的if_stmt表示這一句話定義了if_stmt(非終結(jié)符),’:’右邊則是if_stmt的具體對應(yīng)的內(nèi)容。
1. ‘’引號中的內(nèi)容是實際的字符串,’if’就代表if這兩個字符
2. 一般的標(biāo)示符代表著非終結(jié)符,也就是某個等式的左邊,if_stmt, test, suite都是非終結(jié)符,可以被擴(kuò)展為等式右邊的序列。
3. ()括號是原子操作符,被括號括起來的被作為單個表達(dá)式看待
4. *代表0或多個,比如在if_stmt中的(‘elif’ test ‘:’ suite)*代表一個if語句中可以有0或者多個elif子句
5. +代表1或者多個
但是,這個文件并不只是用來作為參考資料的。實際上,Python運(yùn)行的時候也需要間接利用到Grammar文件的內(nèi)容來進(jìn)行語法分析。
Python PGEN
在Makefile.pre.in和Parser/grammar.mak中均有類似如下的代碼:
- ###################################################
#######################- # Grammar
- GRAMMAR_H= $(srcdir)/Include/graminit.h
- GRAMMAR_C= $(srcdir)/Python/graminit.c
- GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar
- ###############################################
###########################- # Parser
- PGEN= Parser/pgen$(EXE)
- POBJS= \
- Parser/acceler.o \
- Parser/grammar1.o \
- Parser/listnode.o \
- Parser/node.o \
- Parser/parser.o \
- Parser/parsetok.o \
- Parser/bitset.o \
- Parser/metagrammar.o \
- Parser/firstsets.o \
- Parser/grammar.o \
- Parser/pgen.o
- PARSER_OBJS= $(POBJS) Parser/myreadline.o Parser/tokenizer.o
- PGOBJS= \
- Objects/obmalloc.o \
- Python/mysnprintf.o \
- Parser/tokenizer_pgen.o \
- Parser/printgrammar.o \
- Parser/pgenmain.o
- PGENOBJS= $(PGENMAIN) $(POBJS) $(PGOBJS)
- ###################################################
#########################- # Special rules for object files
- $(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
- -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
- $(PGEN): $(PGENOBJS)
- $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
這段代碼負(fù)責(zé)生成pgen,然后調(diào)用pgen以Grammar作為輸入,生成graminit.h/graminit.c。PGEN是Python自帶的語法分析數(shù)據(jù)生成的工具,負(fù)責(zé)分析Grammar然后生成對應(yīng)的graminit.c/graminit.h。然后,Python運(yùn)行過程中會依賴graminit.c/graminit.h中的數(shù)據(jù)結(jié)構(gòu)來進(jìn)行語法分析。PGEN的具體實現(xiàn)不在本文討論范圍中,從略。
【編輯推薦】