lex实现扩展的pl0语言的词法分析器(附源码)

词法分析器实验报告

源代码和相关文件都放在了github上 !github link

实验目的

  1. 理解编译器的工作机制,掌握编译器的工作原理
  2. 掌握词法分析器生成工具LEX的用法

实验构成以及说明

实验说明

  • 使用LEX实现扩展的pl0语言的词法分析器

  • pl0语法扩展包括:

    1. 支持字符类型及相关运算

    2. 支持浮点类型及相关运算

    3. 支持整形数组

    4. 支持for循环语句

    5. 支持repeat语句

  • 保留字:

    if | then | while | do | read | write | call | begin | end | const | var | procedure | odd | for | to | repeat | until|of|Array

    for, to, repeat, until, of, Array 这几个保留字是根据扩展语法新加入的

  • 界符

    “[”|"("|")"|","|":"|";"|"."|"]"|"…"

    []和…会在array声明中用到

  • 语句类型:

    • 赋值语句:if…then…, while…do…, read, write, call,
    • 复合语句:begin… end,
    • 说明语句: const…, var…, procedure…
    • 重复语句:for…to…, repeat…until…
  • 输出类型:

    • K类(关键字)
    • I类(标识符)
    • C类(常量)
    • O类(算符)
    • D类(界符)
    • T类(其他) 将错误的类型,比如长度不和规范的标识符、常量,含有非法字符的标识符也归于此类

代码说明

辅助定义
  • real类型支持负数运算,并且支持科学计数法

  • integer类型和real类型都有长度限制

  • array类型,采用pascal的数组声明方式

  • illegal是非法类型

    将所有正确的字符排除以后的所有其他字符或是字符串全部算作非法类型

  • 空格、回车、换行符、制表符分开处理,在打印出分析结果时,没有输出空格

digit [0-9]
letter [a-zA-Z]
identifier {letter}({letter}|{digit})*
integer {digit}+
real -?{digit}+(\.{digit}+)([Ee][-+][0-9]+)?
whitespace [ ]
newline [\n]
return_ [\r]
col_8 [\t]
char (\'[^ \n\r\t]\')
string (\".{2,}\")
array Array\ \[(1\.\.{integer})(\,1\.\.{integer})*\]\ of\ (integer|real|char|string)
t_1 ([^\t\n\f\v\r ])([_?!$&#@`]+)({letter}|{digit})+  
t_2 ({digit}+){letter}({letter}|{digit})*  

识别规则
  • {integer}|{real}|-{integer} 包含对于常量长度的检查
  • {char} 包含对char类型的检查(是否只包含一个字符)
  • {identifier} 对标识符长度进行检查
{integer}|{real}|-{integer} {
	/*检查长度*/
	if(yyleng > 14)
	{
		printf("Error! The length of this number is too long!\n");
		exit(0);
	}
	print_out('C');col = col + yyleng;
	}
{char} {
	if(yyleng > 3){
		/*char类型 'k' 长度为3*/
		printf("The length of char must be 1.");
		exit(0);
	}
	print_out('C'); col = col + yyleng;
}
{identifier} {
	/*检查长度是否超出范围*/
	if(yyleng > 10){
		printf("Error! The length of this idetifier is too long!\n");
		exit(0);
	}
	print_out('I');col = col + yyleng;
	}

  • 错误处理
{illegal} {
	/*含有非法字符的字符串*/
	/*数字开头的identifier*/
	/*real里是错误类型*/
	printf("This word is incorrect! ");
	print_out('T');
}
用户子程序

此处子程序借鉴的老师ppt里的例子

将所需处理的文件名用 argv传递进来

处理以后的结果输出到文件中

设计思路

在教材中,把词法分析器安排成一个子程序,每当语法分析器需要一个单词符号时就调用这个子程序;每调用一次,词法分析器就从输入串中识别出一个单词符号,然后把它交给语法分析器。

图片已丢失。。。

因此,生成的词法分析器需要能够顺序逐个将单词的属性和位置(列数、行数)输出。

单词按照不同的属性进行单独处理。

在代码中使用全局变量File* fout将词法分析结果输出到文件中。

实验步骤

  • 根据词法规则和扩展语法要求,将对应的词法定义规则写到code.l文件中
  • 用flex工具将lex源程序生成lex.yy.c文件
  • 在c语言环境下,对lex.yy.c文件进行编译,生成可执行文件a.out
  • 使用a.out文件对pl0测试集中数据进行测试
  • 将结果存放在输出集文件夹中

源代码

github link

github address: https://github.com/Ethan00Si/Pl0-compiler/tree/master/%E8%AF%8D%E6%B3%95%E5%88%86%E6%9E%90%E5%99%A8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值