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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

flex工具学习二

發布時間:2025/7/25 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flex工具学习二 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考書:flex與bsion

目標:讀入文本并打印文本信息及行號,遇到文本中包含#include "file" 則讀入嵌套文本并打印

創建text.l寫入以下代碼:

1 %option noyywrap 2 %x IFILE 3 4 %{ 5 struct bufstack { 6 struct bufstack *prev; 7 YY_BUFFER_STATE bs; 8 int lineno; 9 char *filename; 10 FILE *f; 11 } *curbs = 0; 12 char *curfilename; 13 int newfile(char *fn); 14 int popfile(void); 15 %} 16 17 %% 18 [ \t]*#include[ \t]*[\"|<] { 19 BEGIN IFILE; 20 } 21 22 <IFILE>[^ \t\n\">]+ { 23 { 24 int c; 25 while((c = input()) && c != '\n'); 26 } 27 yylineno++; 28 if(!newfile(yytext)) yyterminate(); 29 BEGIN INITIAL; 30 } 31 32 <IFILE>.|\n { 33 fprintf(stderr, "%4d bad include line\n", yylineno); 34 } 35 36 <<EOF>> { if(!popfile()) yyterminate(); } 37 38 ^. { fprintf(yyout, "%4d %s", yylineno, yytext); } 39 40 \n { ECHO; yylineno++; } 41 %% 42 43 main(int argc, char **argv) 44 { 45 if(argc<2) { 46 fprintf(stderr, "need filename\n"); 47 return 1; 48 } 49 if(newfile(argv[1])) yylex(); 50 } 51 52 int newfile(char *fn) 53 { 54 FILE *f = fopen(fn, "r"); 55 struct bufstack *bs = malloc(sizeof(struct bufstack)); 56 if(!f){ 57 perror(fn); 58 return 0; 59 } 60 if(!bs){ 61 perror("malloc"); 62 exit(1); 63 } 64 if(curbs) curbs->lineno = yylineno; 65 bs->prev = curbs; 66 bs->bs = yy_create_buffer(f, YY_BUF_SIZE); 67 bs->f = f; 68 bs->filename = fn; 69 yy_switch_to_buffer(bs->bs); 70 curbs = bs; 71 yylineno = 1; 72 curfilename = fn; 73 return 1; 74 } 75 76 int popfile(void) 77 { 78 struct bufstack *bs = curbs; 79 struct bufstack *prevbs; 80 if(!bs) return 0; 81 fclose(bs->f); 82 yy_delete_buffer(bs->bs); 83 prevbs = bs->prev; 84 free(bs); 85 if(!prevbs) return 0; 86 yy_switch_to_buffer(prevbs->bs); 87 curbs = prevbs; 88 yylineno = curbs->lineno; 89 curfilename = curbs->filename; 90 return 1; 91 }

?

?

編譯代碼:

flex text.l gcc -o test lex.yy.c -lfl

創建test.txt、test2.txt,里面內容分別為:

#include "test2.txt" local i = 1; local x = 2

測試:

./test test.txt

輸出:

1 local x = 22 local i = 1;

?源碼分析:

第1行的%option 為flex選項,noyywrap表示不調用yywrap()函數。yywrap()函數可以用于掃描多個源文件。

其它選項有:

%option yylineno // 自動使用yylineno記錄符號所在行號

%option case-insensitive // 匹配時自動忽略大小寫,比如[a-z]也可以匹配A-Z字符,但不改變yytext里字符的大小寫。

%option debug // 掃描器在debug模式下運行

第2行的%IFILE定義一個狀態,用戶可以定義多個狀態。flex本身有一個默認狀態INITIAL,規則區的正則表達式前加入<IFILE>表示該正則表達式只在IFILE狀態時啟用后面的處理例程。沒有加狀態的正則表達式則是在默認狀態下匹配。

源代碼第36行的<<EOF>>是指掃描任意源文件結束時調用后面例程:將當前文本出棧

bufstack是一個棧結構,當掃描器匹配到#include時,則進入IFILE狀態,接下來讀取緊跟的文件名,然后調用newfile記錄當件文本當前掃描位置并入棧,讀取新的文本,然后進入默認狀態。在默認狀態下匹配\n ^.等規則。ECHO為回車。

?

轉載于:https://www.cnblogs.com/liumu1209/p/5664751.html

總結

以上是生活随笔為你收集整理的flex工具学习二的全部內容,希望文章能夠幫你解決所遇到的問題。

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