一、实验目的
利用flex工具生成一个PL/0语言的词法分析程序,对PL/0语言的源程序进行扫描,识别出单词符号的类别,输出各种符号的信息。
二、实验要求
(一)基本要求
对于PL/0源程序,将程序中的单词分为六类,然后按照单词符号出现的顺序依次输出各个单词符号的种类和出现在源程序的位置(行数和列数)。
PL/0语言中单词的种类说明见表1。
单词种类 | 类别表示 | 例子 |
---|---|---|
关键词 | K类 | var、while、do等 |
标识符 | I类 | a、b、test等长度小于11的变量名、过程名 |
常量 | C类 | 1、2、3等长度小于15的整数 |
算符 | O类 | +、-、:=等运算符 |
界符 | D类 | ; 、. 、, 等符号 |
其他(非法符、空白符等) | T类 | 3a、3@a、a_3_4等非法符号;\t\r\v和空格等空白符号 |
(二)扩展要求(for循环语句)
实现for循环语句。能够识别for语句的关键词。
本实验中设计的for语句见代码1.
for i := 1, i <= 10 do
begin
a := a + 1;
i := i + 1;
end;
三、实验环境
词法分析生成工具:flex
编程语言:C
操作系统:macOS
四、实验内容
(一)PL/0源程序分析
对每一类单词符号进行分析后,总结如下:
1、K类
基本单词有13个:if、then、while、do、read、write、call、procedure、begin、end、const、var、odd;扩展for 语句后添加关键词:for。
2、I类
长度小于1的变量名、过程名。以字母开头的字母和数字的组合。
3、C类
长度小于15的整数。
4、O类
涉及到的运算符有:"+"、"-"、"*"、"/"、"#"、"<"、">"、"="、"<>"、"!="、">="、"<="、":="
5、D类
涉及到的界符有:"("、")"、","、":"、";"、"."
6、T类
(1)空白字符:包括空格、制表符、换行符
(2)非法单词:定义非法符号有?!@#¥&|$\·_。非法单词的组合类型有:包含非法符号的字符串、数字开头的数字字母组合、浮点数。
(二)辅助定义和识别规则的设计
1、不同类型单词符号的正规式表达(辅助定义)
不同类型单词符号的正规式的设计方案见表2.
表示 | 正规式 | 含义 |
---|---|---|
digit | [0-9] | 单个数字 |
letter | [a-zA-Z] | 单个字母 |
identifier | {letter}({letter}|{digit})* | I类字符 |
number | {digit}+ | C类字符 |
wrong_1 | ([^\t\n\f\v\r ])([_?!$&#@`]+)({letter}|{digit}) | 含非法符号的字符串,T类字符 |
wrong_2 | ({digit}+){letter}({letter}|{digit})* | 数字开头的数字字母组合,T类字符 |
wrong_3 | ({digit}+)([.]+)({digit}+) | 浮点数,T类字符 |
whitespace | [\t\v ] | 空白符,T类字符 |
newline | [\n\r] | 换行符,用于更新行列号 |
2、识别规则
当识别到符合标识符规则的单词后执行analyse程序。识别规则见代码2.
/*识别K类字符*/
"procedure" |"call" |"begin" |"end" |"var" |"const" |"if" |"then"|"while" |"do" |"read" |"write" |"odd" |"for" {
analyse(1);}
/*识别I类字符*/
{
identifier} {
analyse(2);}
/*识别C类字符*/
{
number} {
analyse(3);}
/*识别O类字符*/
"+"|"-"|"*"|"/"|"#"|"<"|">"|"="|"<>"|"!="|">="|"<="|":=" {
analyse(4);}
/*识别D类字符*/
"("|")"|","|":"|";" |"." {
analyse(5);}
/*识别T类字符*/
{
whitespace}|{
wrong_1}|{
wrong_2}|{
wrong_3}</