日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Lex入门

發布時間:2024/6/21 综合教程 19 生活家
生活随笔 收集整理的這篇文章主要介紹了 Lex入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Lex主要功能是生成一個詞法分析器(scanner)的 C 源碼,描述規則采用正則表達式(regular expression)。描述詞法分析器的文件 *.l 經過lex編譯后,生成一個lex.yy.c 的文件,然后由 C 編譯器編譯生成一個詞法分析器。詞法分析器,簡言之,就是將輸入的各種符號,轉化成相應的標識符(token),轉化后的標識符很容易被后續階段處理,如YACC 或 Bison,過程如圖

,“lex”和“yacc”這兩個名字所代表的也包括這些工具的 GNU 版本 flex 和 bison。 給出的代碼應該適用于所有主流版本,比如 MKS yacc。它完全是一個融洽的大家族!

Flex (fast lexical analyser generator) 是 Lex 的另一個替代品。它經常和自由軟件 Bison 語法分析器生成器 一起使用。Flex 最初由 Vern Paxson 于 1987 年用C語言寫成。Flex手冊里對 Flex 描述如下:

Flex是一個生成掃描器的工具,能夠識別文本中的詞法模式。Flex 讀入給定的輸入文件,如果沒有給定文件名的話,則從標準輸入讀取,從而獲得一個關于需要生成的掃描器的描述。此描述叫做規則,由正則表達式和 C代碼對組成。Flex 的輸出是一個 C 代碼文件——lex.yy.c——其中定義了yylex() 函數。編譯輸出文件并且和 -lfl 庫鏈接生成一個可執行文件。當運行可執行文件的時候,它分析輸入文件,為每一個正則表達式尋找匹配。當發現一個匹配時,它執行與此正則表達式相關的C代碼。Flex 不是GNU工程,但是GNU為Flex 寫了手冊。

總之,Flex 是詞法分析工具,它讀取輸入源文件,然后生成 C 語言源程序,通常默認的是 "lex.yy.c", 該文件中包含 yylex( ) 例程,并且可以被 C 編譯器編譯鏈接為可執行文件,在該詞法分析器運行時,它會根據已定義的規則,在遇到一定的匹配模式時執行相應的 C 代碼,從而完成詞法分析動作

gcc lex.yy.c 報錯:

In function `yylex':
lex.yy.c:(.text+0x39b): undefined reference to `yywrap'
/tmp/ccIx8oEA.o: In function `input':
lex.yy.c:(.text+0xcdb): undefined reference to `yywrap'

The scanner calls this function on end of file, so you can point it to another file and continue scanning its contents. If you don't need this, use

%option noyywrap (一般在文件開頭加,類似這樣
%option noyywrap
%{
/* * * * * * * * * * * *
 * * * DEFINITIONS * * *
 * * * * * * * * * * * */
%}

)

or link with-lflto use the default yywrap() function in the libraryfl.(就是gcc lex.yy.c -lfl )

還有一種辦法,我們自己寫一個不做什么的yywrap()函數;

int yywrap()
{
	return 1;
}

以上3中解決方案都可以。

輸入幾行字,計算行數,單詞數和字符數.

%option noyywrap

%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+  { words++; chars += strlen(yytext); }
\n         { chars++; lines++; }
.          { chars++; }
%%
main(int argc, char **argv)
{
  yylex();
  printf("%8d%8d%8d\n", lines, words, chars);
}
{}內的是c編寫的動作

按照下面過程編譯。

#flex test.l

#gcc lex.yy.c -o main.out

#./main.out (不要再這行接著輸入文字,flex不會計數的)

hello world

you can say

按ctrl+d結束

輸出結果 2 5 24

修改上面的例子,將正則表達式放在全局聲明中:

%{
int chars = 0;
int words = 0;
int lines = 0;
%}
mywords    [a-zA-Z]+ 
mylines    \n 
mychars    .  
%%
{mywords}  { words++; chars += strlen(yytext); }
{mylines}  { chars++; lines++; }
{mychars}  { chars++; }
%%
main(int argc, char **argv)
{
  yylex();
  printf("%8d%8d%8d\n", lines, words, chars);
}

小知識:

flex有很多選項,我們不想使用默認的lex.yy.c名字,加上

-o lexname 就可以了。

flex -o b.yy.c b.l

可以使用man flex查看幫助

The Scanner as Coroutine(協同程序)

即怎樣將掃描到的標記給其他程序使用,下面的例子,希望掃描到+ 或 -時做一個特殊輸出。

當調用yylex時,若掃描到return對應的標記時,yylex返回,且值就為return后的值;

若沒掃描到return對應的標記,yylex繼續執行,不返回。

下次調用自動從前一次的掃描位置處開始。

%option noyywrap
%{
enum yytokentype{
    ADD=259,
    SUB=260
    };
%}

myadd "+"
mysub  "-"
myother .

%%
{myadd} { return ADD;}
{mysub} { return SUB;}
{myother} {printf("Mystery character\n");}

%%
main(int argc,char **argv)
{
 int token;
 while(token=yylex())
 {
    if(token==ADD||token==SUB )
    {//yylex的返回值只能是ADD 或 SUB.
      printf("meet + or -\n");
     }
     else {
     printf("this else statement will not be printed, \
            because if yylex return,the retrun value must be ADD or SUB.");
            }
   }
 }

$./b.out

h+f-w
Mystery character
meet + or -
Mystery character
meet + or -
Mystery character

參考:http://www.cnblogs.com/vestinfo/archive/2012/09/29/2708931.html

http://xiaoxia.org/2011/10/24/writing-a-compiler-learning-gnu-flex-write-a-lexical-analyzer/

http://web.eecs.utk.edu/~bvz/cs461/notes/flex/

http://www.ibm.com/developerworks/cn/linux/sdk/lex/

http://www.ibm.com/developerworks/cn/linux/l-lexyac.html

http://course.cug.edu.cn/bianyi/shiyan/CHAPTER/f1.htm

http://wenku.baidu.com/view/5b46758da0116c175f0e4898.html

總結

以上是生活随笔為你收集整理的Lex入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。