天天看點

linux終端lex程式運作,lex的簡單使用

Lex & Flex 簡介

Lex是lexical compiler的縮寫,是Unix環境下非常著名的工具, Lex (最早是埃裡克·施密特和 Mike Lesk 制作)是許多 UNIX 系統的标準詞法分析器(lexical analyzer)産生程式,而且這個工具所作的行為被詳列為 POSIX 标準的一部分。

Lex的基本工作原理為:由正規表達式生成NFA,将NFA變換成DFA,DFA經化簡後,模拟生成詞法分析器。

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

linux終端lex程式運作,lex的簡單使用

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

FLEX (fast lexical analyzer generator) is a tool/computer program for generating lexical analyzers (scanners or lexers) written by Vern Paxson in C around 1987. It is used together with Berkeley Yacc parser generator or GNU Bison parser generator. Flex and Bison both are more flexible than Lex and Yacc and produces faster code.

Bison produces parser from the input file provided by the user. The function yylex() is automatically generated by the flex when it is provided with a .l file and this yylex() function is expected by parser to call to retrieve tokens from current/this token stream.

Lex & Flex 輸入檔案格式

Flex 的輸入檔案包含了三部分,分别是定義區(definitions)、規則區(rules)和使用者代碼區(user code)并且由單獨占一行的兩個連續的百分号("%%")分隔開:

definitions

%%

rules

%%

user code

下面對 Flex 輸入檔案的三個部分做出解釋:

1 定義部分:定義部分包含變量的聲明,正則定義,清單常量。在定義部分,文本放在“%{%}”括号中。用花括号括起來的所有内容都會直接複制到lex.yy.c檔案中。

文法

%{

// Definitions

%}

2 規則部分:rules部分包含一系列規則,格式為:pattern action,并且模式 pattern 位于行首不能縮進,action 也應該起始于同一行,規則部分包含在“%% %%”中。

文法:

%%

pattern action

%%

下表顯示了一些模式比對。

Pattern

It can match with

[0-9]

all the digits between 0 and 9

[0+9]

either 0, + or 9

[0, 9]

either 0, ‘, ‘ or 9

[0 9]

either 0, ‘ ‘ or 9

[-09]

either -, 0 or 9

[-0-9]

either – or all digit between 0 and 9

[0-9]+

one or more digit between 0 and 9

[^a]

all the other characters except a

[^A-Z]

all the other characters except the upper case letters

a{2, 4}

either aa, aaa or aaaa

a{2, }

two or more occurrences of a

a{4}

exactly 4 a’s i.e, aaaa

.

any character except newline

a*

0 or more occurrences of a

a+

1 or more occurrences of a

[a-z]

all lower case letters

[a-zA-Z]

any alphabetic letter

w(x \

y)z

wxz or wyz

3 使用者代碼部分:這部分包含C語句和其他功能。我們還可以分别編譯這些函數并使用詞法分析器加載。

如何運作程式:

要運作該程式,首先應将其儲存為擴充名.l或.lex。在終端上運作以下指令以運作程式檔案。

步驟1:lex filename.l或lex filename.lex取決于擴充檔案

步驟2:gcc lex.yy.c

步驟3:./ a.out

步驟4:在需要時将輸入提供給程式

注意:按Ctrl + D或使用某些規則停止接受使用者輸入。請檢視以下程式的輸出圖像以清除是否有疑問以運作程式。

簡單例子

計算字元串中的字元數

%{

int count = 0;

%}

%%

[A-Z] {printf("%s capital letter\n", yytext);

count++;}

. {printf("%s not a capital letter\n", yytext);}

\n {return 0;}

%%

int yywrap(){}

int main(){

// Explanation:

// yywrap() - wraps the above rule section

// yytext is the text in the buffer

// Uncomment the lines below

// to take input from file

// FILE *fp;

// char filename[50];

// printf("Enter the filename: \n");

// scanf("%s",filename);

// fp = fopen(filename,"r");

// yyin = fp;

yylex();

printf("\nNumber of Captial letters "

"in the given input - %d\n", count);

return 0;

}

運作:

linux終端lex程式運作,lex的簡單使用

查找讀取文本所有整數

%{

int count = 0;

%}

%%

[+-]?[0-9]+ { count++; printf("%s\n", yytext); }

\n {}

. {}

%%

void main() {

yylex();

printf("Number count is %d\n", count);

}

int yywrap() {

return 1;

}

運作:

linux終端lex程式運作,lex的簡單使用

參考文章: