1、实验项目一 词法分析器一、实验类型本实验为验证性实验。二、实验目的1通过本实验加深对词法分析程序的功能及实现方法的理解;2使用 flex 实现词法分析程序。三、准备工作和预备知识Lex(Lexical Analyzar 词法分析生成器)是 Unix 下十分重要的词法分析工具。经常用于语言分析,公式编译等广泛领域。1.Lex(Lexical Analyzar) 初步示例先看简单的例子:一个简单的 Lex 文件 exfirst.l 内容:%#include “stdio.h“%n ;0-9+ printf(“Int : %sn“,yytext);0-9*.0-9+ printf(“Float :
2、%sn“,yytext);a-zA-Za-zA-Z0-9* printf(“Var : %sn“,yytext);+-*/% printf(“Op : %sn“,yytext);“.” printf(“Unknown : %cn“,yytext0);%在命令行下执行命令 flex 解析,会自动生成 lex.yy.c 文件:rootlocalhost liweitestflex exfirst.l进行编译生成 parser 可执行程序:rootlocalhost liweitestcc -o parser lex.yy.c ll或者rootlocalhost liweitestgcc lex.y
3、y.c ll -o parser注意:如果不加-ll 链结选项,cc 编译时会出现以下错误,后面会进一步说明。/tmp/cciACkbX.o(.text+0x37b): In function yylex: undefined reference to yywrap/tmp/cciACkbX.o(.text+0xabd): In function input: undefined reference to yywrap 创建待解析的文件 file.txt:titlei=1+3.9;a3=909/6bcd=4%9-333通过已生成的可执行程序,进行文件解析。rootlocalhost liwei
4、test# ./parser 。其中规则部分是必须的,定义和用户子程序部分是任选的。 (1)定义部分定义部分起始于 % 符号,终止于 % 符号,其间可以是包括 include 语句、声明语句在内的 C 语句。这部分跟普通 C 程序开头没什么区别。%#include “stdio.h“int linenum;%(2) 规则部分规则部分起始于“%“符号,终止于“%“符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由 C 语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex 将识别出来的单词存放在 yytext字符数据中,因
5、此该数组的内容就代表了所识别出来的单词的内容。类似 yytext 这些预定义的变量函数会随着后面内容展开一一介绍。动作部分如果有多行执行语句,也可以用括起来。%title showtitle();n linenum+;0-9+ printf(“Int : %sn“,yytext);0-9*.0-9+ printf(“Float : %sn“,yytext);a-zA-Za-zA-Z0-9* printf(“Var : %sn“,yytext);+-*/% printf(“Op : %sn“,yytext);. printf(“Unknown : %cn“,yytext0);%A.规则部分的正则
6、表达式规则部分是 Lex 描述文件中最为复杂的一部分,下面列出一些模式部分的正则表达式字符含义:A-Z, 0-9, a-z 构成模式部分的字符和数字。- 指定范围。例如:a-z 指从 a 到 z 之间的所有字符。 转义元字符。用来覆盖字符在此表达式中定义的特殊意义,只取字符的本身。 表示一个字符集合。匹配括号内的任意字符。如果第一个字符是那么它表示否定模式。例如: abC 匹配 a, b, 和 C 的任何一个。 表示否定。* 匹配 0 个或者多个上述模式。+ 匹配 1 个或者多个上述模式。? 匹配 0 个或 1 个上述模式。$ 作为模式的最后一个字符时匹配一行的结尾。 表示一个模式可能出现的次
7、数。 例如: A1,3 表示 A 可能出现 1 次或 3次。a-z5 表示长度为 5 的,由 a-z 组成的字符。此外,还可以表示预定义的变量。. 匹配任意字符,除了 n。( )将一系列常规表达式分组。如:Letter(Letter|Digit)*| 表达式间的逻辑或。“一些符号“ 字符的字面含义。元字符具有。如:“*“ 相当于 *。/ 向前匹配。如果在匹配的模式中的“/“后跟有后续表达式,只匹配模版中“/“前面的部分。如:模式为 ABC/D 输入 ABCD,时 ABC 会匹配 ABC/D,而 D 会匹配相应的模式。输入 ABCE 的话,ABCE 就不会去匹配 ABC/D。B.规则部分的优先级
8、规则部分具有优先级的概念,先举个简单的例子:%#include “stdio.h“%n ;A printf(“ONEn“);AA printf(“TWOn“);AAAA printf(“THREEn“);%此时,如果输入内容:rootlocalhost liweitest# cat file1.txtAAAAAAArootlocalhost liweitest# ./parser = = != = ; , ( ) 3. 其他标记是ID 和NUM ,通过下列正则表达式定义:ID = letter letter*NUM = digit digit*letter = a|z|A|Zdigit = 0|9小写和大写字母是有区别的。要求:编写其对应的 lex 程序,然后编译,生成该简单 C 语言的词法分析器,然后用此词法分析器分析简单 C 语言的程序段。