iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
自我挑戰組

Lex & Yacc 學習筆記系列 第 14

[Day14] Yacc - OR語法

  • 分享至 

  • xImage
  •  

本篇內容

  • 介紹Yacc中的OR語法
  • 範例 - 簡易計算機2

Yacc語法介紹 - OR

我們在前幾天試著做出一個簡單的加法計算機。我們今天來試著擴充這個計算機的功能,讓它可以做加減乘除四種運算。

當然,我們可以直接加入另外三種運算方式的規則,像是下面這樣:

expr_add: NUMBER '+' NUMBER   { $$ = $1 + $3; }
expr_minus: NUMBER '-' NUMBER { $$ = $1 - $3; }
expr_mul: NUMBER '*' NUMBER   { $$ = $1 - $3; }
expr_div: NUMBER '/' NUMBER   { $$ = $1 / $3; }

這樣的寫法當然是沒問題,但如果要再擴充幾十個規則,那就要取幾十個規則名稱,實在是太辛苦了。
既然這些規則的架構都一樣,是對兩個數字做運算,我們便可以使用OR語法把這些規則寫在一起。

Yacc中的OR語法規則(也稱為選擇語法規則)用於定義多個可能的選項之間的選擇。當輸入中的一個結構可以匹配多個可能的規則時,OR語法規則允許解析器選擇其中一個選項來匹配輸入。

在Yacc檔案中,OR的寫法跟C++一樣,用 | 符號表示。因此,上述的規則可以改寫成下面的樣子:

expr:
      NUMBER '+' NUMBER   { $$ = $1 + $3; }
    | NUMBER '-' NUMBER   { $$ = $1 - $3; }
    | NUMBER '*' NUMBER   { $$ = $1 * $3; }
    | NUMBER '/' NUMBER   { $$ = $1 / $3; }
    ;

這樣一來,就不用每個運算都取一個名字了,而且做後續的修改與維護都變得更加方便!

範例 - 簡易計算機2

說明

請實作出一個簡易的計算機,能夠對兩個正整數做運算(加減乘除其中之一),並回傳結果。

程式實作

Lex

由於之前的範例中,我們只有定義+號的token,因此要補上其他三個運算符號。

我們可以利用Regular Expression把四個運算符寫在一起,這樣更加簡潔。

%{
#include "main.h"
#include "yacc.tab.h"
%}

posint      ([0-9]+)
blank_chars ([ \f\r\t\v]+)
expressions ([-*+/])

%%

{posint}        { yylval = atoi(yytext); return NUMBER; }
{expressions}   { return yytext[0]; }
{blank_chars}   { ; }
\n              { ; }

%%

int yywrap(void) {
    return 1;
}

Yacc

我們只要將Yacc規則改寫一下就可以了,其他部分跟之前一樣。

expr:
      NUMBER '+' NUMBER   { $$ = $1 + $3; printf("%d\n", $$); }
    | NUMBER '-' NUMBER   { $$ = $1 - $3; printf("%d\n", $$); }
    | NUMBER '*' NUMBER   { $$ = $1 * $3; printf("%d\n", $$); }
    | NUMBER '/' NUMBER   { $$ = $1 / $3; printf("%d\n", $$); }
    ;

結語

今天我們成功的用OR語法規則將多個相似的結構寫在一起,非常方便。

參考資料

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

上一篇
[Day13] Makefile 介紹
下一篇
[Day15] Yacc - 規則匹配
系列文
Lex & Yacc 學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言