剖析與文法的應用
掃描器(詞法分析器,lexer)
/ LEK-ser /
要看懂一個句子,你得先把它看成一個個詞,而不是一團字母。讀 thecatsat 很難,直到你把它切成 the cat sat。掃描器,又稱詞法分析器(lexer),正是為編譯器做這種切塊:它讀入原始字元串流,把它們組成詞符(token),也就是語言中有意義的「單字」,並順手丟掉空白與註解。
掃描器建立在正規語言的機制之上,那是文法之下的一層。每一種詞符,識別字、整數、關鍵字、運算子,都用一個正規表示式描述,而掃描器實際上是一台跑過字元、回報所辨識每個詞符的有限自動機(DFA)。標準規則是最長匹配(maximal munch,longest match):在每一點抓住能構成有效詞符的最長字元串。所以 < = 是兩個詞符,但 <= 是一個,掃描器偏好較長的那個。掃描器不理解巢狀或平衡,括號對它而言只是標點詞符,因為正規語言不會計數;那是剖析器的工作。
把掃描與剖析分開是一種刻意的分工,在速度與簡潔上都有回報。掃描器用一台快速的有限自動機做大量、逐字元的工作,使剖析器能在一串簡短乾淨的詞符上工作,而非原始文字,並能使用更簡單、更強大的上下文無關文法理論,而不被拼字細節淹沒。這種兩層設計,正規掃描器餵給上下文無關剖析器,幾乎是每個真實編譯器的標準架構。
掃描這行 if (x>=10) 產生詞符串流 [keyword:if, (, id:x, >=, num:10, )]。掃描器跳過空白,把 >= 當成一個運算子詞符(最長匹配,而非先 > 再 =),且從不過問括號是否成對。
掃描器是一台快速的有限自動機,以最長匹配把字元變成詞符。
掃描器是正規的,而非上下文無關的:它無法檢查括號是否成對,或 if 是否有對應的 else。任何需要計數或巢狀的事都延後到剖析器。
又称
另见