0

我正在學習編譯器,並對有關語言/編譯器的所有術語/區域感到困惑。語言,編譯器,正則表達式,詞法分析和解析之間的關係

所以我在這裏分享我對他們之間關係的理解,並希望有人能夠批准或糾正我的想法。


這是相當困難的開發者通過直接寫入機器代碼使應用程序,所以我們需要一個高水平language。我們通常編寫的程序因此成爲一組texts

語言使用regular expressions來定義語法,即文本程序中的所有文本是否良好。

compiler的任務是將這些texts翻譯成遵循語言定義規則的機器代碼。

一個compiler的前兩步是詞法分析解析

lexical分析會將正則表達式轉換爲NFA/DFA,並處理程序文本,並驗證它們並將它們轉換爲令牌。

parsing處理這些令牌並檢查它們的語義


我說得對嗎?

另一個問題是,一種語言的定義是正則表達式,我們使用parsing部分來驗證程序的語法?

回答

3

而我們通常編寫的程序因此成爲一組文本。

「文本」這個詞在編譯器構造中並不是真正的常用術語(或者至少不是我以前聽說過的)。通常程序首先被翻譯成標記(它們基本上是該語言的「詞」¹),然後該序列被翻譯成語法樹。那棵樹可能會被進一步轉換,並最終被轉換成機器指令序列,這些指令組成編譯好的程序。

語言使用正則表達式來定義語法,即文本程序中的所有文本是否良好。

一種語言的語法描述了方案在結構上是有效還是無效(不考慮類型的錯誤和運行時錯誤,其被單獨處理)。你不能用正則表達式來做到這一點,因爲絕大多數語言都是不規則的,也就是說它們比正則表達式可以描述的要複雜得多。例如,你不能說使用正則表達式來表示「每個左括號都必須有一個右括號」。

正則表達式通常用於描述語言的標記。這就是說你可以說「語言中的標識符與正則表達式[a-zA-Z_][a-zA-Z0-9_]*匹配,並且數字匹配正則表達式[0-9]+」。

然後用語法描述這些令牌如何組合在一起形成一個完整的程序。

編譯器的前兩個步驟是詞法分析和解析。

通常,是的。

詞法分析將正則表達式轉換爲NFA/DFA,並處理程序文本,並驗證它們並將它們轉換爲令牌。

如果您使用詞法分析器生成器,那麼生成器會接收一大堆您給它的正則表達式並將它們轉換爲自動機,然後根據這些生成器生成代碼。生成的代碼是詞法分析器,它將獲取程序源並生成一系列令牌。

請注意,正則表達式和自動機之間的轉換髮生在生成器運行時,而不是作爲編譯器的一部分。如果你手動編寫詞法分析器,正則表達式和自動機之間不會發生任何轉換(除非可能在你的頭上)。

解析處理這些標記並檢查它們的語義。

號解析階段需要的令牌,並確保它們符合語言的語法。如果他們這樣做,它會根據語言的句法結構執行操作。通常這意味着構建一個語法樹。對於簡單的語言,也可以在解析器中直接進行語義分析(如類型檢查)和代碼生成。

如果你確實構建了一個語法樹,那麼隨後的階段就會遍歷那棵樹,這就是語言的語義發揮作用的地方。

另一個問題是,一個語言的定義是正則表達式,我們使用解析部分來驗證程序的語法?

語言的語法的定義一般是給出一個語法,而不是一個正則表達式。正如我所說,正則表達式對此沒有足夠的表現力。我們使用解析來驗證給定的程序是否符合語言的語法(以及確定程序的語法結構)。

語言的定義由語言的語法定義和語義的定義組成。後者通常以文本形式提供。

¹在這裏我使用單詞「單詞」的口語意義,而不是它的語言理論意義。

+0

真的有幫助的答案。謝謝。通過'正則表達式經常被用來描述一種語言的標記,你的意思是每個標記可以是一個正則表達式?這也是爲什麼在像ocamllex這樣的'lex'工具中,我們使用正則表達式來定義標記類型和每個構造函數? –

+0

@JacksonTale我的意思是每個標記都有一個正則表達式,是的。我不會說令牌*是正則表達式。令牌是由詞法分析器生成的。如果你有'[0-9] + {IntegerLiteral(int_of_string(lexeme lexbuf)}'並且在輸入'42'上運行它,那麼令牌就是'IntegerLiteral 42'。 – sepp2k

+0

現在明白了,謝謝。 –

2

開發人員很難直接編寫機器代碼來編寫應用程序,所以我們需要高級語言。我們通常編寫的程序因此成爲一組文本。

好的。

語言使用正則表達式來定義語法,即文本程序中的所有文本是否良好。

不。一種語言使用上下文無關語法來定義語法,也可能使用正則表達式來定義詞典。正則表達式不能表示遞歸,所以它們不能用於定義具有遞歸語法的編程語言,實際上它們都是這些語法。

編譯器的任務是根據語言定義的規則將這些文本轉換爲機器碼。

好的。

編譯器的前兩個步驟是詞法分析和解析。

好的。

詞法分析轉換的正則表達式到NFA/DFA

號的程序生成詞法分析器這樣做,如果有一個。生成的分析器只是直接使用NFA或DFA。

並通過程序文本工作,並驗證它們並將它們轉換爲令牌。

不,只有後者。解析器執行大部分驗證,以及被稱爲「靜態語義」階段的階段。

解析處理這些令牌

是。

並檢查它們的語義。

否解析與語義無關。這是編譯器的其餘部分。

另一個問題是,這麼一個語言的定義是正則表達式

沒有見上。

我們使用解析部分來驗證程序的語法嗎?

不,驗證程序的語法。

+0

「正則表達式不能表示遞歸,所以它們不能是用於定義具有它的編程語言「語言理論意義上的遞歸語言不是具有遞歸的語言,語言是否支持遞歸函數定義與它是否可以被解析無關一個正則表達式。 – sepp2k

+0

@ sepp2k我不知道'遞歸函數定義'可能意味着什麼,但我沒有對它們或關於遞歸函數調用說一句話。我正在談論遞歸語法,就像你一樣。 – EJP

+0

哦,我明白了。我誤解了這一點。通過遞歸函數定義,我指的是遞歸函數的定義。就像在一些舊的語言中一樣,你不能定義一個遞歸的函數(因爲那些語言沒有調用堆棧的概念),所以這就是我通常所說的沒有遞歸的編程語言。 – sepp2k