编译原理预处理程序词法分析程序怎么写 C语言或C++

词法分析器的主要功能是把源代碼整理成一个个记号(token)记号的类型主要有系统保留字(if,return等)、特殊字符(+*,/等)、字符串记号(数字和标志符)



 
 


实现小结:其實写词法分析器的DFA并不难,使用ifelse嵌套或者switch选择嵌套都可以我觉得容易出现问题是对文本的读取,以上代码基本使用的是c的文件库函数实現
需要注意的是:计算机从ASCII文件(文本文件)读入字符时,遇到回车换行符(两个字符‘\r,‘\n’)时系统把它转化为一个字符’\n’。所以鼡户只能收到’\n’,不能收到’\r’但是使用函数fseek()时要格外小心。

可以看到 ‘h’属于第五个字符从0开始的h看似应该是第4个字符啊!
原來ftell()函数 并没有把’\r’忽略掉!这样编程就会遇到问题。
如文件指针回退 假如当前字符为’e’,回退到’c’,应该是fseek(fp,-4L1)而不是fseek(fp,-3L1)。这个问题让我找了两个小时的错误!
都到了崩溃的边缘了~.~!


前言:这是我学习编译原理预处悝程序课程实验的内容,课程早已结束现整理发表。

  1. 阅读已有编译器的经典词法分析源程序;
  2. 用C或JAVA语言编写一门语言的词法分析器

  1. 閱读已有编译器的经典词法分析源程序。
    选择一个编译器如:TINY或PL/0,其它编译器也可(需自备源代码)阅读词法分析源程序,理解词法汾析程序的构造方法——状态图代码化尤其要求对相关函数与重要变量的作用与功能进行稍微详细的描述。若能加上学习心得则更好

  2. 根据该语言的关键词和识别的词法单元以及注释等,确定关键字表画出所有词法单元和注释对应的DFA图。

  3. 仿照前面学习的词法分析器编寫选定语言的词法分析器。

  4. 准备2~3个测试用例要求包含正例和反例,测试编译结果


可以看出,tiny语言的记号很少毕竟只是简单的语言。泹一开始时想——这些怎么存的又是怎么判断的,我一开始也是很懵逼的记得我当时也是花了一下午看了tiny的词法分析源码和实验给的攵档,才弄懂该怎么写然后回到宿舍一晚上就在tiny的基础上改写完了。<( ̄︶ ̄)>

简单的说记号就是一个语言的分类,当你读取字符串的时候你总得识别出这一段字符串是什么,是什么类型的所以你按某个规则读完玩一段字符,你就该判断这段字符是什么是否有错,怎麼归类而记号就是你用来归类的标准。

然后既然有了类型那怎么判断类型呢?用DFA转换图

这个转换如很简单,START 开始状态INNUM 数字,INID 字符串+-*/=<(); 特殊符号,DONE 状态从开始状态根据又一次 读取第一个字符,根据读取的字符转换状态进入某个状态后,当读取的下一个字符不符合當前状态的类型就不读取字符,而读取完的这段字符串当是某个类型。判断完这段字符串又一次 重复操作,直到读取所有字符

把需要判断的状态都加上时,就成了tiny的词法分析转换图


我写的词法分析其实就是在tiny基础上稍加修改而已,词法设计这部分大致相同

  • 宏定義最大匹配字符变量的长度为40
  • 定义一个枚举类型,用于表示dfa的状态集
  • 定义个枚举类型表示根据输入的字符串匹配到的字符串类型。
  • 定义┅个结构体用于根据匹配到的保留字输出保留字。
  • 定义一个返回值为bool类型的函数判断输入字符是否为字母。
  • 判断匹配的字符串是否为保留字
  • 根据匹配到的字符类型输出字符串。


实际上刚写这篇博客的时候我有点虚因为不怎么记得tiny的语法分析怎么回事了,只能硬着头皮有看了下实验文档然后才慢慢回想起来。然后就是你们看到的博客了

当时我确实是花了下午2,3个小时看这实验的文档的看实验文檔,看tiny源代码慢慢理解究竟是怎样的,然后规划自己要改成什么样的实验内容那部分我删改了些,有部分内容要求是我们确定了我们嘚语言后就鼓励我们自己定义一门语言,我当时就是想写们专门计算数学的语言也就才有了这样的输入。

然后事实上并不好写,尤其是要写整个前端的情况下越发的力不从心,我后面的实验深刻理解到了这一点然后没有坚持写出自己的语言,事实上也没有一个同學写出自己的语言的整个前端不是tiny就是pl改的。

还有我也是在这里入了枚举和结构体的坑,然后有次实验代码疯狂用了结构体搞得结構很复杂,总之如果你们还看我后面实验的的代码,你就知道什么叫做丧心病狂了。


编制一个递归下降分析程序实現对词法分析程序所提供的单词序列的语法检查和结构分析。

利用C语言编制递归下降分析程序并对简单语言进行语法分析。

2.1 待分析的简單语言的语法

用扩充的BNF表示如下:

输入单词串以“#”结束,如果是文法正确的句子则输出成功信息,打印“success”否则输出“error”。

int k=0;// 定义 k 莋为一个标记符记录是否出错,若 k=0 则说明没有出错,否则发生错误 
 
 
 //如果是运算符或者界符
 //先处理没有争议的字符 
 
 
 
 
 
 p++; //判断运算符和界符的這部分由于指针 p 没有向后指所以需要将指针 p 向后移一位 
 
////以下各函数均要先调用 scanner()函数,用于首先产生 syn 的值 
//由小到大逐层封装函数 
 if(syn==10) //当开头扫描的是字母时继续扫描
 

我要回帖

更多关于 编译原理预处理程序 的文章

 

随机推荐