FLEX(快速词法分析器生成器)是 Vern Paxson 于 1987 年左右用 C 编写的用于生成词法分析器(扫描器或词法分析器)的工具/计算机程序。它与 Berkeley Yacc 解析器生成器或 GNU Bison 解析器生成器一起使用。 Flex 和 Bison 都比 Lex 和 Yacc 更灵活并且生成更快的代码。
Bison 根据用户提供的输入文件生成解析器。函数yylex()由 flex 在提供.l 文件时自动生成,解析器期望此 yylex()函数调用以从当前/此令牌流中检索令牌。
注意:函数yylex() 是运行规则部分的主要 flex函数,扩展名 (.l) 是用于保存程序的扩展名。
在 Ubuntu 上安装 Flex:
sudo apt-get update
sudo apt-get install flex
注意:如果有一段时间没有在机器上运行更新命令,最好先运行它,以便安装较新的版本,因为旧版本可能无法与安装的其他软件包一起使用,或者现在可能不存在。
给定的图像描述了如何使用 Flex:
步骤 1:一个输入文件描述了要生成的词法分析器,名为 lex.l 是用 lex 语言编写的。 lex 编译器将 lex.l 转换为 C 程序,文件名为 lex.yy.c。
第 2 步: C 编译器将 lex.yy.c 文件编译成一个名为 a.out 的可执行文件。
第 3 步:输出文件 a.out 获取输入字符流并生成标记流。
程序结构:
在输入文件中,有 3 个部分:
1. 定义部分:定义部分包含变量的声明、常规定义、清单常量。在定义部分,文本括在“%{ %}”括号中。在这个括号中写的任何东西都直接复制到文件lex.yy.c
句法:
%{
// Definitions
%}
2. 规则部分:规则部分包含以下形式的一系列规则:模式动作和模式必须是非预期的,动作在{}括号中的同一行开始。规则部分包含在“%% %%”中。
句法:
%%
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 语句和附加功能。我们也可以单独编译这些函数并用词法分析器加载。
基本程序结构:
%{
// Definitions
%}
%%
Rules
%%
User code section
如何运行程序:
要运行该程序,应首先使用扩展名.l 或 .lex保存它。在终端上运行以下命令以运行程序文件。
步骤 1: lex filename.l 或 lex filename.lex 取决于扩展文件的保存方式
第 2 步: gcc lex.yy.c
第 3 步: ./a.out
第 4 步:在需要时向程序提供输入
注意:按Ctrl+D或使用一些规则来停止接受用户的输入。如果对运行程序有疑问,请查看以下程序的输出图像以清除。
实施例1:计数在一个字符串的字符数
C
/*** Definition Section has one variable
which can be accessed inside yylex()
and main() ***/
%{
int count = 0;
%}
/*** Rule Section has three rules, first rule
matches with capital letters, second rule
matches with any character except newline and
third rule does not take input after the enter***/
%%
[A-Z] {printf("%s capital letter\n", yytext);
count++;}
. {printf("%s not a capital letter\n", yytext);}
\n {return 0;}
%%
/*** Code Section prints the number of
capital letter present in the given input***/
int yywrap(){}
int main(){
// Explanation:
// yywrap() - wraps the above rule section
/* yyin - takes the file pointer
which contains the input*/
/* yylex() - this is the main flex function
which runs the 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;
}
C
/* Declaring two counters one for number
of lines other for number of characters */
%{
int no_of_lines = 0;
int no_of_chars = 0;
%}
/***rule 1 counts the number of lines,
rule 2 counts the number of characters
and rule 3 specifies when to stop
taking input***/
%%
\n ++no_of_lines;
. ++no_of_chars;
end return 0;
%%
/*** User code section***/
int yywrap(){}
int main(int argc, char **argv)
{
yylex();
printf("number of lines = %d, number of chars = %d\n",
no_of_lines, no_of_chars );
return 0;
}
输出:
示例2:统计输入中的字符数和行数
C
/* Declaring two counters one for number
of lines other for number of characters */
%{
int no_of_lines = 0;
int no_of_chars = 0;
%}
/***rule 1 counts the number of lines,
rule 2 counts the number of characters
and rule 3 specifies when to stop
taking input***/
%%
\n ++no_of_lines;
. ++no_of_chars;
end return 0;
%%
/*** User code section***/
int yywrap(){}
int main(int argc, char **argv)
{
yylex();
printf("number of lines = %d, number of chars = %d\n",
no_of_lines, no_of_chars );
return 0;
}
输出:
想要从精选的视频和练习题中学习,请查看C 基础到高级C 基础课程。