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

Posted 甘木甘木

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于lex实现扩展的pl0语言的词法分析器(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

Yacc 与 Lex 快速入门(词法分析和语法分析)

Postgres数据库词法分析和语法分析源码解析

Postgres数据库词法分析和语法分析源码解析

Postgres数据库词法分析和语法分析源码解析

Postgres数据库词法分析和语法分析源码解析

linux 下怎样安装使用 Yacc 和 Lex