iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
自我挑戰組

Lex & Yacc 學習筆記系列 第 8

[Day8] Yacc - 基本介紹與原理

  • 分享至 

  • xImage
  •  

本篇內容

  • 介紹Yacc
  • 介紹Lex & Yacc的編譯流程

Yacc介紹

前面的幾天主要都是介紹 Lex,我們使用它來生成詞法分析器。從本日起,我們要開始探討 Yacc的部分了。與 Lex 識別Regular Expression的情況不同,Yacc 則是識別整個文本的語法。Lex將Input劃分為token,然後Yacc將這些片段以邏輯方式組合在一起。因此,Yacc必須搭配Lex才能運作。

Yacc 的運作方式主要分成兩大步驟:語法樹建立與程式規則執行。前者是根據開發者提供的語法規則來分析輸入的文本,將其轉換為語法樹或抽象語法樹的結構,這有助於理解和處理語言中的複雜語法結構。後者是程式執行某語法規則所對應的操作,這部分由C++程式語言撰寫。

以下我們將一步步解釋這個流程。

Token

我們先前提到,lex可以把複雜的訊息分類並標記token。這些token在Yacc可以用來建立程式規則。

舉例來說,我們若要計算1+2是多少,首先必須先定義下列事項:

  1. 相加的兩個數字是多少?
  2. 相加的符號是甚麼?

這兩個問題很簡單,但是要讓程式知道,則必須做下面兩件事:

  1. 將相加的兩個數字標記為”數值”
  2. 將"+"號標記為”加法符號”

以上的”標記”動作是由lex完成,經由編譯與整合,讓yacc端知道這些標記符號的意義是甚麼。

語法樹

在標記動作完成後,我們便要根據Yacc的語法規則,定義甚麼情況下要進行操作。

以剛剛的例子來說,加法規則的定義如下

數值 加法符號 數值 -> 將兩數值相加

也就是說,當讀取到三個相鄰字串的token分別為”數值” “加法符號” “數值”,此時便匹配到加法規則。

以此類推,當所有字串匹配相對應的規則後,便會形成語法樹,說明符合操作的字串序列,並列出操作的先後順序。

Yacc運作流程

我們用四則運算來說明整體流程。

https://ithelp.ithome.com.tw/upload/images/20230908/20157613mOjHdO9tkq.png

上圖中,輸入的文字是一條算式,由變數、等號、運算符號(加法與乘法)組成。Lex會先將不同類別的字串分類,並為其加上token。如上圖例子中,a, b, c, d四個變數被標記成”id”,運算符號與等號則自成一個token。

接著,Yacc會透過規則的建立,將標記好的標籤依規則做後續處理。上圖例子中,需要建立的規則如下:

  • 儲存運算結果 → 於等號左邊的變數
  • 乘法 → 將乘號左邊的變數與右邊的變數相乘
  • 加法 → 將加號左邊的變數與右邊的變數相加
  • 運算順序判斷 → 先乘除後加減

規則建立之後,當遇到特定的條件後,就會觸發相對應的規則,並執行該規則下的後續動作。

Lex & Yacc的編譯流程

接著,我們來看看Lex & Yacc是如何與C++結合,編譯出一個執行檔的:

https://ithelp.ithome.com.tw/upload/images/20230908/20157613UCqStbmSaq.png

上圖說明了Lex和Yacc形成語法剖析器的過程。Lex的程式主要寫在.l檔中,內有自訂義的標籤及其名稱。Yacc的程式主要寫在.y檔中,內有自訂義的規則及相對應的處理函式。接著,我們透過以下幾個步驟生成一個語法剖析器。

yacc -d bas.y
lex bas.l
g++ lex.yy.c y.tab.c -o bas.exe

看到這裡,有沒有發現,yacc的編譯是放在lex編譯之前?這是因為token的宣告是在.y檔內,所以在yacc編譯過程中會產生一個y.tab.h檔。接著,Lex會讀取.l檔裡的pattern敘述式及y.tab.h內的宣告,產生一個詞法分析器(lexical analyzer),並寫在lex.yy.c內。另外,Yacc會讀取.y檔內的語法規則並產生一個語法分析器,並寫在y.tab.c中。最後一步則是透過編譯把兩者連結在一起,產生一個執行檔。

結語

今天介紹的Yacc需要搭配Lex才能運作,因此結構比較複雜。

我們明天會來談談Yacc的語法規則是怎麼建立的。這部分會用到BNF表示式。

參考資料

  • Levine, John R., Tony Mason and Doug Brown [1992]. Lex & Yacc. O’Reilly & Associates, Inc. Sebastopol, California.
  • Tom Niemann. Lex & Yacc

上一篇
[Day7] Lex - Error Handling
下一篇
[Day9] Yacc - BNF表示式
系列文
Lex & Yacc 學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言