收藏 分享(赏)

LEX.doc

上传人:w89153 文档编号:7228976 上传时间:2019-05-10 格式:DOC 页数:12 大小:42KB
下载 相关 举报
LEX.doc_第1页
第1页 / 共12页
LEX.doc_第2页
第2页 / 共12页
LEX.doc_第3页
第3页 / 共12页
LEX.doc_第4页
第4页 / 共12页
LEX.doc_第5页
第5页 / 共12页
点击查看更多>>
资源描述

1、LEX(词法分析器生成工具)学习笔记 1LEX介绍LEX(Lexical Analyzer Generator)即词法分析器生成工具是 1972年贝尔实验室的 M.E.Lesk和 E.Schmidt在UNIX操作系统上首次开发的。GNU 同时推出了和 LEX完全兼容的 FLEX(Fast Lexical Analyzer Genrator)。下面用到的例子都是基于 flex的。LEX工作原理:LEX 通过对源文件的扫描,经过宏替换将规则部分的正则表达式转换成与之等价的 DFA,并产生 DFA的状态转换矩阵(稀疏矩阵);利用该矩阵和源文件的 C代码产生一个名为 int yylex()的词法分析函

2、数,将 yylex()函数拷贝到输出文件 lex.yy.c中。函数 yylex()以在缺省条件下的标准输入(stdin)作为词法分析的输入文件。定义部分%规则部分%用户附加的 C语言代码例 1:int num_chars=0,num_lines=0;/*定义两个全局变量,一个及字符数,一个记行数 .注意:该语句不能顶行 */%n +num_chars+; +num_lines;. +num_chars;%int main()yylex();printf(“%d,%d”, num_chars,num_lines);int yywrap()/*文件结束处理函数,当 yylex()读到文件结束标记

3、EOF时,调用该函数时会,用户必须提供该函数,否则会提示编译出错 */return 1;/返回 1表示文件扫描结束,不必再扫描别的文件lex 的输入文件分成三个段,段间用% 来分隔。由于必须存在一个规则段,第一个% 总是要求存在。模式LEX的模式是机器可读的正则表达式。表意字符 匹配字符. 除换行外的所有字符n 换行* 0 次或无限次重复前面的表达式+ 1 次或更多次重复前面的表达式? 0 次或 1 次出现前面的表达式 行的开始$ 行的结尾a|b a 或者 b(ab)+ 1 次或玩多次重复 ab“a+b“ 字符串 a+b 本身( C 中的特殊字符仍然有效) 字符类ab 除 a,b 外的任意字符

4、ab a, , b 中的一个az 从 a 到 z 中的任意字符a-z a,-,z 中的一个a-z a, z 中的一个匹配文件结束标记表 1 :简单模式匹配在方括号() 中,通常的操作失去了本来含意。方括号中只保留两个操作,连字号(“ ”)和抑扬号(“ ” ) 。当把连字号用于两个字符中间时,表示字符的范围。当把抑扬号用在开始位置时,表示对后面的表达式取反。如果两个范式匹配相同的字符串,就会使用匹配长度最长的范式。如果两者匹配的长度相同,就会选用第一个列出的范式。定义 部分%规则部分%用户附加的 C语言代码例 1:int num_chars=0,num_lines=0;/*定义两个全局变量,一个

5、及字符数,一个记行数 .注意:该语句不能顶行 */%n +num_chars+; +num_lines;. +num_chars;%int main()yylex();printf(“%d,%d”, num_chars,num_lines);int yywrap()/*文件结束处理函数,当 yylex()读到文件结束标记 EOF时,调用该函数时会,用户必须提供该函数,否则会提示编译出错 */return 1;/返回 1表示文件扫描结束,不必再扫描别的文件lex 的输入文件分成三个段,段间用% 来分隔。由于必须存在一个规则段,第一个% 总是要求存在。LEX(词法分析器生成工具)我的自学笔记 2模

6、式LEX 的模式是机器可读的正则表达式。表意字符 匹配字符. 除换行外的所有字符n 换行* 0 次或无限次重复前面的表达式+ 1 次或更多次重复前面的表达式? 0 次或 1 次出现前面的表达式 行的开始$ 行的结尾a|b a 或者 b(ab)+ 1 次或玩多次重复 ab“a+b“ 字符串 a+b 本身( C 中的特殊字符仍然有效) 字符类ab 除 a,b 外的任意字符ab a, , b 中的一个az 从 a 到 z 中的任意字符a-z a,-,z 中的一个a-z a, z 中的一个匹配文件结束标记表 1 :简单模式匹配在方括号() 中,通常的操作失去了本来含意。方括号中只保留两个操作,连字号(

7、“ ”)和抑扬号(“ ” ) 。当把连字号用于两个字符中间时,表示字符的范围。当把抑扬号用在开始位置时,表示对后面的表达式取反。如果两个范式匹配相同的字符串,就会使用匹配长度最长的范式。如果两者匹配的长度相同,就会选用第一个列出的范式。定义部分定义部分由 c语言的代码、模式的宏定义和条件模式的开始条件说明等部分组成。其中 C代码由顶行的“%”和“%”引入,LEX 扫描源文件时该部分将首先被拷贝到输出文件之中(去掉)“%”和“%”,在此可以定义必要的全局变量和包含模式处理时用到的外部函数的头文件,如:%#includeint num_chars=0,num_lines=0;%此外,在定义中出现的

8、任何非顶行文字也将直接拷贝到输出文件中,可以利用这一规定了来定义 C的全局变量。还有定义部分开可以加上 C语言的注释/*/,该部分也将直接拷贝到输出文件中。规则部分规则部分是 LEX源文件的核心,它包括一组模式和生成分析器识别相应模式进行处理的 C语言动作。格式如下:C语言代码模式 1 动作 1模式 2 动作 2模式 3 动作 3。模式 n 动作 n同定义部分一样,C 语言代码也不能顶行书写,或则是用顶行的“%”和“%”所引用。这里可以定义输出的词法分析函数 yylex()的局部变量。该部分一定出现在第一个模式之前。而每一个模式必须顶行书写,而模式对应的 C语句必须和模式在一行。它们之间用白字

9、符分割,若对应模式的 C语句有多行,则可以用“”将这些 C语句括起来。用户代码部分LEX 对用户代码部分不做任何处理,仅仅将该部分拷贝到输出文件 lex.yy.c的尾部。在此部分可定义对模式进行处理的 C语言函数、主函数和 yylex()要调用的 yywrap()等。若用户在其它用户模块中提供了这些函数的定义,此部分可省略,则后两部分的%可省略了。yylex()函数的匹配原则yylex()的函数原型为 int yylex(void)。它被调用后,首先它检查全局文件指针变量 yyin是否有定义,如果是则设置将要扫描的文件为用户所定义的文件,否则设为标准输入文件 stdin。接着利用 yylex(

10、)所定义的 DFA分析被扫描的文件,如果有唯一的模式与被扫描的字符串匹配,则执行该模式的动作;如果有多个模式可以匹配相同的输入串,则 yylex()选择匹配最长输入串的模式;若多个模式串匹配相等的输入串,则选择最前的模式进行匹配。例如:%program printf(“%sn”,yytext);/*模式 1*/procedure printf(“%sn”,yytext);/*模式 2*/a-za-z,0-9* printf(“%sn”,yytext);/*模式 3*/当输入串为“programming”时,模式 1(匹配“program”)和模式 3(“programming”)都匹配,但会选择匹配串长的模式 3。当输入串为“program”时,因为模式 1和模式3匹配的串长度相等故会选择模式 1.试验:在 Linux操作系统(ubantu7.10 版本)下装有 flex和 GCC编译器后:1. 把例 1的内容保存到 lextest.l中;2. 运行 flex lextest.l; 这时生成了一个lex.yy.c文件;3. 编译这个 lex.yy.c ,用 gcc lex.yy.c o lexyy4. lexyytest.txt ,test.txt 是一个待测试文件;结果:会显示出来 test.txt中的行数和字符数。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报