1. 程式人生 > >編譯原理——詞法分析(2)

編譯原理——詞法分析(2)

1.1串和語言

       字母表是一個有限的符號集合。符號的典型例子包括字母、數位和標點符號。如集合{0,1}是二進位制字母表。

某個字母表的串(string)是該字母表符號的有窮序列,空串是長度為0的串。

語言(language):是某個給定字元表上任意的可數的串的集合,像空集和僅包括空串的集合都是語言。

1.2語言上的運算

1.3 正則表示式

正則表示式可以描述所有通過對某個字母表上的符號應用這些運算子而得到的語言。比如,在這種表示法中,如果使用letter_來表示任一字母或下劃線,用digit_來表示數位,那麼可以用如下的正則表示式來描述對應於C語言識別符號的語言:letter_(letter_|digit)*

其中豎線表示並運算,星號表示”零個或多個”括號中表達式的連線。

       每個正則表示式r表示一個語言(正則集)L(r)

        下面是正則表示式運算的例子:

用一個正則表示式定義的語言叫做正則集合,以下是對於任意正則表示式r、s和t都成立的代數定律。

Lex的正則表示式的擴充套件表示方法:

1.4狀態轉換圖

作為構造詞法分析器的一箇中間步驟,我們首先將模式轉換成具有特定風格的流圖,稱為狀態轉換圖。狀態轉換圖有一組被稱為“狀態”的結點或圓圈。詞法分析器在掃描輸入串的過程中尋找和某個模式匹配的詞素,而轉換圖中的每個狀態代表一個可能在這個過程中出現的情況。

       以下是關於狀態轉換圖的重要約定:

(1)某些狀態稱為接受狀態或最終狀態。這些狀態表面已經找到了一個詞素,雖然實際的詞素可能不包括lexemeBegin指標和forward指標之間的所有字元。我們用雙層的圈來表示一個接受狀態,並且如果改狀態要執行一個動作的話——通常是向語法分析器返回一個詞法單元和相關屬性值——我們將把這個動作附加到該接受狀態上。

(2)另外,如果需要將forward回退一個位置(即相應的詞素並不包含那個在最後一步使我們到達接受狀態的符號),那麼我們將在該接受狀態的附近加上一個*。若出現需要將forward指標回退多個位置,我們將為接受狀態附加相應數目的*。

(3)有一個狀態被指定為開始狀態,也稱初始狀態,該狀態由一條沒有出發結點的、標號為“start“的邊指明。在讀入任何輸入符號之前,狀態轉換圖總是位於它的開始狀態。

這裡附上龍書上的例子:

識別所有與詞法單元relop匹配的詞素的狀態轉換圖:

保留字和識別符號的識別:

首先,先明確保留字和識別符號具體是什麼,保留字指在高階語言中已經定義過的字,使用者不能再將這些字作為變數名或過程名使用,而我膚淺的把它認為它是關鍵字;識別符號是指用來標識某個實體的一個符號,這裡為了方便理解,把他當作是使用者定義的變數。

我們可以使用兩種方法來處理那些看起來很像識別符號的保留字:

(1)初始化時就將各個保留字填入符號表中,如上圖3-14就是使用了這種方式。

(2)為每個關鍵字建立單獨的狀態轉換圖,如下圖的3-15是關鍵字then的例子。

下圖為無符號數字(number)的狀態轉換圖: