flex and bison學習筆記01


工作需要,學習一下Flex and bison,以前在編譯原理的課上聽老師說過他們的前輩,lex and yacc。Flex and bison就是lex and yacc的升級版。

參考書:flex 與 bison

1、Flex and bison簡介

Flex和bison是兩個用來生成程序的工具,它們生成的程序分別叫做詞法分析器和語法分析器,工作中主要是用來生成SQL語句的詞法和語法分析器。

2、詞法分析器和語法分析器是如何工作的?

任何一種語言,都是有一定的語法規則的,不管是人類的語言,還是計算機語言(如C/C++編程語言等),因此,可以利用這些已知的規則,來對相應的語言進行分析。舉個例子,漢語中的一個句子,基本的格式是:主(名詞/代詞)+謂(動詞)+賓(名詞/代詞),當你在說一句話的時候,我們把你說的話(輸入)先拆分成一個個有意義的字或者詞組,然后對照該語法,看詞性及組合,是否符合既定的語法規范,如果符合,則可以知道你說的話是符合規范的。比如,你說“我吃飯”,輸入會被依次拆成“我”“吃”“飯”,它們分別是代詞、動詞、名詞,因此符合上面的語法規則,因此這句話是OK的。而如果說“我飯吃”,則會發現與上面的規范不符合(也沒有其他符合的規范),因此這句話語法上市有問題的。Flex和bison生成的詞法和語法分析器就是干這兩件事的,Flex生成的詞法分析器將輸入拆分成一個個記號(token),bison生成的語法分析器根據已有的規則,分析這些token的組合,是否符合語法規范。

3、Flex源文件格式

 4 Flex是用來生成詞法分析器的
 5 Flex源文件擴展名.l
 6 分為三個段:定義段、規則段、用戶子程序段
 7 /* 定義段 */
 8 %{
 9 ...
10 %}
11 ...
12 
13 %%
14     /* 規則段 */
15 ...
16 %%
17 
18     /* 用戶子程序段 */
19 ...
20 
21 三個段用%%進行分隔
22 1.定義段
23     這一部分一般是一些聲明及選項設置等。C語言的注釋、頭文件包含等一般就放在%{%}之間,這一部分的內容會被直接復制到輸出文件的開頭部分.
24 2.規則段
25 
26     規則段為一系列匹配模式和動作,模式一般使用正則表達式書寫,動作部分為C代碼:
27     模式1 {動作1 (C代碼)}
28     在輸入和模式1匹配的時候,執行動作部分的代碼。
29 3.用戶子程序段
30     
31     這里為C代碼,會被原樣復制到輸出文件中,一般這里定義一些輔助函數等,如動作代碼中使用到的輔助函數。
32     
33     詞法分析器所做的,就是在輸入中尋找字符的模式(pattern)。在詞法分析器中,我們要給定我們需要識別的模式,因此需要使用一種方式來描述模式,這就是常用的正則表達式。學習正則表達式

4、Flex小例子

1.編寫以下Flex源文件(01.l,注意后綴名是l字母)

%{
    #include <stdio.h>
%}

%%

[a-zA-Z]+ {printf("get word:%s\n", yytext);}
[0-9]+ {printf("get number:%d\n", yytext);}
\n {printf("New line\n");}
. {}

%%

代碼中定義了四條規則,前面的部分就是模式,處於一行的開始位置,后面部分是動作,也就是,輸入中匹配到了這個模式的時候,對應進行什么動作(就像機器人接受到了什么樣的指令,然后會執行相應的動作一樣)

第一個模式,匹配連續一到多個字符串,匹配之后就將其打印出來。yytext:在輸入中匹配到該模式的時候,匹配的部分就存儲在這個yytext里面了。這里的動作是把它作為字符串直接輸出。

第二個模式,匹配連續一個或者多個數字,匹配到之后就將其輸出。

第三個模式,匹配一個換行符,匹配到之后就打印一個新行的信息。

第四個模式,匹配出了\n之外的字符,沒有任何動作。

總體來說,這個規則就是匹配到英語單詞,則將其輸出;匹配到連續數字,則將其輸出;匹配到換行符,打印一條信息;匹配到任何其他字符直接忽略({}也就是動作為空,就是什么都不做了。)

源文件寫好了之后就是編譯、生成可執行程序,然后測試是否按我們所想的那樣了。

找一個安裝有Flex、bison的機器試一下吧,如果沒有自行安裝

centos下使用下面命令安裝,

yum install flex

yum nistall bison

生成C代碼:felx ./01.l

編譯生成的C代碼:gcc -o scanner ./lex.yy.c -lfl

然后運行scanner程序即可。

 

第二個小例子的代碼:

 1 %{
 2     int chars = 0;
 3     int words = 0;
 4     int lines = 0;
 5 %}
 6 
 7 %%
 8 
 9 [a-zA-Z]+ {words++; chars += strlen(yytext);}
10 \n {chars++; lines++;}
11 . {chars++;}
12 
13 %%
14 
15 main(int argc, char **argv)
16 {
17     yylex();
18     printf("lines:%8d\nwords:%8d\nchars:%8d\n", lines, words, chars);
19 }

這個例子的規則是,統計輸入的單詞數,字符數以及行數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM