編譯的哪個階段是被識別的編程語言的關鍵字?編譯器的階段?
我
- 詞法分析之間的某種困惑。
- 該程序的解析。
我曾經寫過一個在C詞法分析器使用正則表達式,但它在int main(void)
承認main()
也作爲關鍵字。
在這些方面,我認爲我們必須構建一個分析樹來識別關鍵字。
編譯的哪個階段是被識別的編程語言的關鍵字?編譯器的階段?
我
我曾經寫過一個在C詞法分析器使用正則表達式,但它在int main(void)
承認main()
也作爲關鍵字。
在這些方面,我認爲我們必須構建一個分析樹來識別關鍵字。
今年我不得不建立一個簡單的編譯器作爲我使用Java的項目。關鍵詞的識別是在詞法分析上進行的。在那個階段,我會閱讀輸入語言,並創建一個類型的令牌(對於關鍵字類型是variable_declaration)及其值。對於每種情況,例如標識符,常量,乘法操作,添加操作等,我也有不同的類型。然後傳遞這些令牌到一個隊列,然後進入一個解析器,它將檢查語法並創建一個二叉樹,然後用它來創建輸出語言。
通常,彙編的詞法分析階段將輸入文本分解成詞彙序列,每個詞彙都屬於某個特定的記號類型,這在以後的分析中很有用。因此,關鍵詞通常在詞法分析過程中首先得到識別,以便更輕鬆地進行分析。由於解析器傾向於通過編寫上下文無關的標記語法而不是詞位來實現(即,詞位的類別而非內容),因此在關鍵字時構建解析器顯着更容易在練習中被標記。例如,如果我想有治療解析器「如果」作爲關鍵字,那麼我可能需要一個規則,看起來像這樣在我的CFG:
Statement ::= 'IF' Expr 'THEN' Expr
如果我不分類IF
和THEN
到他們自己的令牌類型中,那麼我的解析器就不能寫出類似上面的語句。
這將是詞法分析。
有些語言具有「特殊」標識符以及關鍵字。這些通常被添加到標識符表並在解析開始之前分配已知的常量ID值,以便它們可以很容易地被發現。這些通常對解析器沒有特別的意義 - 它們應該在解析後在抽象語法樹(AST)中檢測到。
例如,看一看的奧伯倫語言報表...
http://www-old.oberon.ethz.ch/oreport.html
不是一種語言建議 - 只是一個容易獲得和簡單的語言規範(非常Wirths風格)。
無論如何,「詞彙和表示」部分包含「運營商和分隔符」列表,其中包括大多數人會將其識別爲關鍵字的列表。這些將被詞法分析器識別。
在「聲明和範圍規則」部分,有一個預定義標識符列表,如「ABS」和「BOOLEAN」。我對Oberon的確定程度並不熟悉,但是如果我要編寫一個編譯器,那麼我很有可能只是預先初始化標準標識符表以包含這些預定義的標識符。
在C中,「main」在大多數方面只是另一個功能。編譯器可能會或可能不會將其視爲特殊的。關於它的唯一「特殊」事情可能是鏈接到最終可執行文件的啓動代碼調用該函數。
它很大程度上取決於定義,特別是您在掃描器,標記器,詞法分析器和分析器之間繪製線條的位置。既然這是作業,而且只有你的教授纔是正確的。說它是正確的:看看你的閱讀材料中提供的定義。
關於main():你可以肯定地說main()和其他函數不是關鍵字,而是一個標記。標記器識別子字符串「main」是一個標記,解析器將其設置爲與它的「(...)」和「{...}」部分有關。此外,對於main(),解析器將自動生成一個程序入口點。
傳統上,關鍵字是由詞法分析器識別的(使用固定關鍵字組成的語言)。但是當然你可以在解析過程中做到這一點。甚至可以使用衆多無詞法分析技術之一(例如PEGs)完全擺脫詞法分析器。它可以幫助你避免混淆。
只是一個說明:[正則表達式是可以嵌套的模式的不好選擇](http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems的.html)。 – Mehrdad 2011-03-05 08:52:49
@Mehrdad:絕對正確,但對於標記(它不涉及任何嵌套任何細節;一個詞法分析器只是返回一個扁平的標記流),它們很棒! – delnan 2011-03-05 08:53:17
@Mehrdad - 還有一些基於正則表達式的工具,這些工具添加了有限的嵌套處理能力 - 足以嵌套評論等.Ragel就是一個很好的例子。注意我說「基於」(我已經習慣了人們在這裏跳來跳去的東西;-)),我知道一旦你支持任意深度嵌套,整體語法就不再是常規的了。 – Steve314 2011-03-05 09:02:00