lex/yacc简介
lex/yacc与flex/bison的关系
lex/yacc是一种思想,flex/bison是其gnu实现
lex/yacc的优势
轻易构造c/c++编译器
程序例子下载地址
ftp://ftp.iecc.com/pub/file/flexbison.zip
学习资料
flex语法(分为三部分)
三部分通过%%分割
第一部分lex代码
%%
第二部分lex代码
%%
第三部分lex代码
第一部分:声明和选项设置(直接复制到生成的lex.yy.c中)
%{
变量为要复制到lex.yy.c中的c语言变量,动作中可以使用这些变量
%}
第二部分:单词匹配后进行某种动作(核心部分语法分析器,生成yylex()函数到lex.yy.c中)
语法
正则表达式1 动作1
正则表达式2 动作2
正则表达式3 动作3
- 正则表达式要按照正则表达式语法写,lex会编译为词法分析代码
- 动作是c语言语句,动作c语言语句直接复制到lex.yy.c中
- 两者合起来即是yylex()函数,yylex()函数可以在yacc中使用
lex将lex代码编译为词法分析器的编译理论基础
这部分代码是lex根据用户描述的语法自动生成的,背后是编译原理中的自动机理论。
单词匹配(正则表达式)
基本用法
- 最长匹配原则,词法分析器匹配输入时,匹配尽可能多的字符串
如果两个模式都可以匹配,那么匹配在程序中更早出现的那个模式
当把连字号用于两个字符中间时, 表示字符的范围。当把抑扬号用在开始位置时,表示对后面的表达式取反。 如果两个范式匹配相同的字符串,就会使用匹配长度最长的范式。如果两者匹配的长度相同,就会选用第一个列出的范式。
单词匹配举例
一个Lex/Yacc完整的示例(可使用C++) - huyansoft的专栏 - 博客频道 - CSDN.NET
匹配除\n以外的字符
.
匹配\n字符
\n
忽略空白字符
[\t ]+ * 忽略空白 *;
wc中定义的没有空白的字符
[^ \t\n\r\f\v]+
匹配单词
非数字由大小写字母、下划线组成
nondigit ([_A-Za-z])匹配数字
一位数字,可以是0到9
digit ([0-9])匹配整数
整数由1至多位数字组成
integer ({digit}+)匹配标识符
非数字由大小写字母、下划线组成
nondigit ([_A-Za-z])
一位数字,可以是0到9
digit ([0-9])标识符,以非数字开头,后跟0至多个数字或非数字
identifier ({nondigit}({nondigit}|{digit})*)文法规则中使用这些变量需要加{indentifier}注意加括号
匹配一段连续空白串
一个或一段连续的空白符
blank_chars ([ \f\r\t\v]+)
匹配到单词后的动作
语法
{一条或者多条c语言语句}
动作中使用的变量
- 使用lex代码中第一部分声明中定义的变量
lex默认定义的内部变量
变量名 作用 yytext 指向本次匹配的输入文本 引入y.tab.h使用yacc中定义的变量
打印匹配的数据
如果不写动作,默认动作是打印。因此宏{ECHO;}可以不用写。
{ECHO;}
ECHO是一个C语言宏
\#define ECHO fwrite(yytext, yyleng, 1, yyout)向语法分析器传递记号信息
传递字符串的值-使用函数strdup(yytext)
passing values(yylval) other than string from flex to bison | GeekWentFreak
lex内置变量
名称 | 功能 |
---|---|
char \*yytext | 指针,指向所匹配的字符串 |
yyleng | 所匹配的字符串的长度 |
yylval | 与标记相对应的值 |
FILE \*yyout | 输出文件 |
FILE \*yyin | 输入文件 |
INITIAL | 初始化开始环境 |
BEGIN | 按条件转换开始环境 |
ECHO | 输出所匹配的字符串 |
lex内置函数
名称 | 功能 |
---|---|
int yylex(void) | 调用扫描器, 返回标记 |
int yywrap(void) | 约束,如果返回 1 表示扫描完成后程序就结束了, 否则返回 0 |
语法分析器每次需要一个记号的时候调用 yylex()从要解析的文件中读取一部分数据,然后返回相应的记号。当语法分析器需要下一个记号的时候,再次调用yylex(),词法分析器以协同的工作方式运行,每次返回时,yylex()会记录读到的文件的位置,语法分析器再次调用yylex()时,从该位置继续读取。
第三部分:直接复制到生成的lex.yy.c中
int main()
{
yylex();
}
flex程序编译
flex code.l //生成lex.yy.c
cc lex.yy.c -lfl //链接flex库文件