摘要:而,稱(chēng)之為非終結(jié)符。而這個(gè)展開(kāi)方案中對(duì)各個(gè)非終結(jié)符產(chǎn)生式的選擇過(guò)程,即是對(duì)源代碼中每一個(gè)部分的定性過(guò)程。這個(gè)過(guò)程讓能夠理解源代碼各個(gè)部分表示的含義,并以此生成對(duì)應(yīng)的語(yǔ)法樹(shù)。
我需要定義出 tao 語(yǔ)言的細(xì)節(jié),在此,需要引出文法這一概念。所謂文法,即是用于描述語(yǔ)言的一種工具。
例如,一個(gè)賦值語(yǔ)句可能寫(xiě)成如下形式:
variable = 1 + 3
如何充分定義這個(gè)賦值語(yǔ)句的形式呢?若用自然語(yǔ)言描述,我可以說(shuō),賦值語(yǔ)句最左邊是一個(gè)標(biāo)示符,然后緊接一個(gè)“=”符號(hào),然后再接一個(gè)表達(dá)式。滿(mǎn)足這個(gè)條件的,即是賦值語(yǔ)句啦。
S → abE
用符號(hào)來(lái)描述的話(huà),就是如上形式,這種形式稱(chēng)之為 S 的產(chǎn)生式。其中 S 表示賦值語(yǔ)句,a 表示一個(gè)標(biāo)示符,b 是“=”符號(hào),E 表示表達(dá)式。這里用到了S、a、b、E 四個(gè)不同的字母。
等等,似乎還有什么沒(méi)說(shuō)完,因?yàn)闃?biāo)示符(字母a表示)與“=”符號(hào)(字母b表示)都與 Tokenizer 生成的 Token 對(duì)應(yīng),但是表達(dá)式(字母E表示)卻沒(méi)有對(duì)應(yīng)的 Token 呀。
于是,我還要進(jìn)一步描述表達(dá)式。這里為了不讓問(wèn)題變得過(guò)于繁瑣,我先假定表達(dá)式只出現(xiàn)加減號(hào)和數(shù)字。那么表達(dá)式的定義如下。
E → d | E+d | E-d
這里出現(xiàn)的“|”表示“或”,這表明表達(dá)式(字母E)可以展開(kāi)成三種不同的式子。同時(shí),E 展開(kāi)后的式子中可能再次出現(xiàn) E 本身,這種遞歸形式足以涵蓋任意長(zhǎng)度的表達(dá)式形式。
于是,我們又得到字母 d,d 表示一個(gè)數(shù)字(也與某種 Token 對(duì)應(yīng))。
至此,我們一共得到了 S、a、b、E、d 五個(gè)不同的字母,其中 a、b、d 都與 Token 對(duì)應(yīng)。然而,雖然 S、E 卻沒(méi)有對(duì)應(yīng)的 Token,但它們都有至少有一個(gè)屬于自己的產(chǎn)生式。
對(duì)于 a、b、d,稱(chēng)之為終結(jié)符。即它們不會(huì)再有自己的產(chǎn)生式了。而 S、E,稱(chēng)之為非終結(jié)符。
當(dāng)我們?yōu)槭阶又心硞€(gè)非終結(jié)符挑選一個(gè)特定的產(chǎn)生式,并用產(chǎn)生式的右邊部分代替這個(gè)非終結(jié)符在式子中的位置,那么我們將這個(gè)過(guò)程稱(chēng)之為非終結(jié)符的展開(kāi)。
考慮下面這行代碼:
index = 15 + 7 - 3
其形如 abd+d-d(a 為 "index"、b 為"="、d 為"15", "7", "3")
對(duì)于 S 有如下展開(kāi)方式:
S → abE
→ abE-d(展開(kāi) E → E-d)
→ abE+d-d(展開(kāi) E → E+d)
→ abd+d-d(展開(kāi) E → d)
其中 S 表示一個(gè)賦值語(yǔ)句。既然 S 存在某種展開(kāi)方式,其形式與這行代碼完全相同,我們說(shuō),這行代碼與 S 是匹配的。對(duì)于 Parser 而言,即可斷定這行語(yǔ)句是一個(gè)賦值語(yǔ)句。
因此,Parser 讀取語(yǔ)言的文法定義。然后,通過(guò)找到一個(gè)展開(kāi)方案以匹配源代碼。而這個(gè)展開(kāi)方案中對(duì)各個(gè)非終結(jié)符產(chǎn)生式的選擇過(guò)程,即是對(duì)源代碼中每一個(gè)部分的定性過(guò)程。這個(gè)過(guò)程讓 Parser 能夠理解源代碼各個(gè)部分表示的含義,并以此生成對(duì)應(yīng)的語(yǔ)法樹(shù)(Syntax Tree)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/64262.html
摘要:是的,這個(gè)系列將呈現(xiàn)一個(gè)完整的編譯器從無(wú)到有的過(guò)程。但在寫(xiě)這個(gè)編譯器的過(guò)程中,我可不會(huì)偷工減料,該有的一定會(huì)寫(xiě)上的。該語(yǔ)言的虛擬機(jī)將運(yùn)行于之上,同時(shí)編譯器將使用實(shí)現(xiàn)。我早有寫(xiě)編譯器的想法之前沒(méi)寫(xiě)過(guò),故希望一邊寫(xiě)編譯器一邊完成這個(gè)系列。 是的,這個(gè)系列將呈現(xiàn)一個(gè)完整的編譯器從無(wú)到有的過(guò)程。當(dāng)然,為了保證該系列內(nèi)容的簡(jiǎn)潔(也為了降低難度),僅僅保證編譯器的最低要求,即僅能用。但在寫(xiě)這個(gè)編譯...
摘要:希臘字母表示空,這個(gè)產(chǎn)生式表明非終結(jié)符可以產(chǎn)生一個(gè)空。此外,對(duì)于一個(gè)文法之中的非終結(jié)符,還有集集的概念。對(duì)于一個(gè)非終結(jié)符而言,它的集指可能展開(kāi)的各種形式中,位于第一的所有終結(jié)符所組成的集合。 上一章中,我說(shuō) Parser 的工作就是依據(jù)文法定義,找到一個(gè)與源代碼匹配的展開(kāi)方案就可以了。聽(tīng)起來(lái)我們只要先給出一個(gè) tao 語(yǔ)言的文法定義,然后寫(xiě)一個(gè)找匹配方案的的程序就可以了。 然而事情情況...
摘要:目前為止我們創(chuàng)建的文件列表新上一章中我們提到了個(gè)方法它們可以用來(lái)描述非終結(jié)符和展開(kāi)式的形式,那么它們又是如何工作的呢文件中定義了一些方法。特別的,注意如下代碼這個(gè)方法可以紀(jì)錄被掉的一組非終結(jié)符,紀(jì)錄這些東西有什么用,將在隨后的章節(jié)介紹。 目前為止我們創(chuàng)建的文件列表: |- com.taozeyu.taolan.analysis |- FirstSetConstructor ...
摘要:一個(gè)非終結(jié)符可以被展開(kāi)稱(chēng)為一個(gè)串,如上定義便是將這個(gè)非終結(jié)符展開(kāi)稱(chēng)為一個(gè)又終結(jié)符和非終結(jié)符混合而成的串。特別注意我定義的方法僅僅用于修飾非終結(jié)符,而非展開(kāi)式,雖然這個(gè)例子中我的方法更靠近方法,但并意味著用于修飾展開(kāi)式。 各位久等了,本系列在新一年的連載中,形式會(huì)加入少許變化。首先,我會(huì)將 tao 語(yǔ)言編譯器(以及運(yùn)行環(huán)境)的全部?jī)?nèi)容貼在 GitHub 上,在閱讀本系列的時(shí)候,需要對(duì)照 ...
摘要:從展開(kāi)式中,可以看出,除了這個(gè)非終結(jié)符,還有其他一些非終結(jié)符。是可能展開(kāi)的形式之一,在語(yǔ)言中,如下代碼就是一行典型的從表達(dá)式來(lái)看,它是由一個(gè)級(jí)表達(dá)式和一個(gè)類(lèi)型的非終結(jié)符組成。但特別注意結(jié)尾的數(shù)量詞表明,整個(gè)非終結(jié)符都是可選的。 目前為止我們創(chuàng)建的文件列表: |- com.taozeyu.taolan.analysis |- FirstSetConstructor |- ...
閱讀 3402·2023-04-25 17:19
閱讀 701·2021-11-23 09:51
閱讀 1410·2021-11-08 13:19
閱讀 857·2021-09-29 09:34
閱讀 1755·2021-09-28 09:36
閱讀 1553·2021-09-22 14:59
閱讀 2777·2019-08-29 16:38
閱讀 2110·2019-08-26 13:40