编译原理:实验一练习



词法分析器
编译原理实验报告


上面的第一个链接中的词法分析器有一点问题,修改后的代码如下:
 #include "string.h"#include "math.h"#include "stdio.h"char keywords[28][12]={"program","begin","end","var","while","do","repeat","until","for","to","if","then","else",";", ":", "(", ")", ",",":=", "+", "-", "*", "/", ">", ">=", "==", "<", "<="};int num_key=28;int aut[11][8]={{0, 0, 0, 0, 0, 0, 0, 0},{0, 2, 0, 0, 0, 8, 9,15},{0, 2, 3, 5,11, 0, 0,11},{0, 4, 0, 0, 0, 0, 0, 0},{0, 4, 0, 5,11, 0, 0,11},{0, 7, 0, 0, 6, 0, 0, 0},{0, 7, 0, 0, 0, 0, 0, 0},{0, 7, 0, 0,11, 0, 0,11},{0, 8, 0, 0, 0, 8, 0,12},{0, 0, 0, 0, 0, 0,10,14},{0, 0, 0, 0, 0, 0, 0,13}};char ID[50][12];float C[20];int num_ID=0,num_C=0;struct token{int code;int value;};                                    //Token结构struct token tok[100];                //Token数组int i_token=0,num_token=0;            //Token计数器和Token个数char strTOKEN[15];                    //当前单词int i_str;                            //当前单词指针int n,p,m,e,t;                        //尾数值,指数值,小数位数,指数符号,类型double num;//常数值char w[50];                           //源程序缓冲区int i;                                //源程序缓冲区指针,当前字符为w[i]struct map{                            //当前字符到状态转换矩阵列标记的映射char str[50];int col;};struct map col1[4]={{"0123456789",1},{".",2},{"Ee",3},{"+-",4}};        //数字struct map col2[2]={{"abcdefghijklmnopqrstuvwxyz",5},{"0123456789",1}}; //关键字或标识符struct map col3[1]={{";:(),+-*/=><",6}};                                //界符struct map *ptr;int num_map;void act(int s);int find(int s,char ch);int InsertConst(double num);int Reserve(char *str);int InsertID(char *str);int main(int argc, char* argv[]){FILE *fp;int s;//当前状态fp=fopen("testcase.txt","r");while (fgets(w,50,fp)!=NULL){//读取文件中的50个字符i=0;do{//w[50] = begin /n endwhile (w[i]==' '){//滤空格i++;}if (w[i]>='a' && w[i]<='z'){//读取的首个字符是字母ptr=col2;num_map=2;}else if (w[i]>='0' && w[i]<='9'){//读取的首个字符是数字ptr=col1;num_map=4;}else if (strchr(col3[0].str,w[i])==NULL){printf("非法字符%c\n",w[i]);i++;continue;}else{ptr=col3;num_map=1;}i--;s=1;//开始处理一个单词//当s不为0时执行循环,s代表的是有限状态自动机中的状态集while (s!=0){act(s);//s=1时,strTOKEN[0]='\0'if (s>=11 && s<=14){break;}/*getchar()i= (-1)=>{0}*/i++;/*s=1 w[0]='b'*/s=find(s,w[i]);}//如果s是等于0跳出的循环if (s==0){strTOKEN[i_str]='\0';//代表字符串的结尾printf("词法错误:%s\n",strTOKEN);}}while (w[i]!=10);}printf("关键字表:");//输出结果printf("\n");for (i=0;i<28;i++){printf("%s ",keywords[i]);}printf("\n");printf("Token序列 :");printf("\n");for (i=0;i<num_token;i++){printf("(%d,%d)",tok[i].code,tok[i].value);}printf("\n");printf("符号表:");printf("\n");for (i=0;i<num_ID;i++){printf("%s ",ID[i]);}printf("\n");printf("常数表:");printf("\n");for (i=0;i<num_C;i++){printf("%.4f ",C[i]);}printf("\n");fclose(fp);return 0;}void act(int s){int code;switch (s){case 1:n=0;m=0;p=0;t=0;e=1;num=0;i_str=0;strTOKEN[i_str]='\0';                   //其它变量初始化break;/*n,p,m,e,t;尾数值,指数值,小数位数,指数符号,类型*/case 2:n=10*n+w[i]-48;break;case 3:t=1;break;case 4:n=10*n+w[i]-48;m++;break;case 5:t=1;break;case 6:if (w[i]=='-'){e=-1;}break;case 7:p=10*p+w[i]-48;break;case 8:strTOKEN[i_str++]=w[i];  //将ch中的符号拼接到strTOKEN的尾部;break;case 9:strTOKEN[i_str++]=w[i];  //将ch中的符号拼接到strTOKEN的尾部;break;case 10:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 11:num=n*pow(10,e*p-m);           //计算常数值tok[i_token].code=2;tok[i_token++].value=InsertConst(num);  //生成常数Tokennum_token++;break;//case12是当你的首个输入字符是字母,而后的情况中遇到了输入非字母和数字会执行的情况case 12:strTOKEN[i_str]='\0';code=Reserve(strTOKEN);//查界符表if (code){//如果匹配到界符表中的元素,生成关键字Tokentok[i_token].code=code;//将之前减去的3加回来tok[i_token++].value=0;}else{tok[i_token].code=1;tok[i_token++].value=InsertID(strTOKEN);}//生成标识符Tokennum_token++;//token的个数break;case 13:strTOKEN[i_str]='\0';code=Reserve(strTOKEN);//查界符表if (code){tok[i_token].code=code;tok[i_token++].value=0;}//生成界符Tokenelse{strTOKEN[strlen(strTOKEN)-1]='\0';//单界符i--;code=Reserve(strTOKEN);//查界符表tok[i_token].code=code;tok[i_token++].value=0;//生成界符Token}num_token++;break;case 14:strTOKEN[i_str]='\0';code=Reserve(strTOKEN);//查界符表tok[i_token].code=code;tok[i_token++].value=0;//生成界符Tokennum_token++;break;}}//find方法:输入一个int和一个char//s=1,ch='b'//s代表的是当前状态集,ch代表的是当前读取到的字符//find方法,接收一个状态集和一个字符集,返回下一步的状态集int find(int s,char ch){int i;int col=7;//默认了i的值是-1,如果之后查找不到的话直接认作是其他符号输入,再进行判断是不是界符struct map *p = ptr;for (i=0;i<num_map;i++){/*ch='b' 返回'b'在str数组中的位置,即判断是否存在这个元素*/if (strchr((p+i)->str,ch)){col=(p+i)->col;//如果是'd',则col=5break;}}//返回当前状态和字符所对应的有限状态自动机中的位置return aut[s][col];}//插入数字int InsertConst(double num){int i;for (i=0;i<num_C;i++){if (num==C[i]){return i+1;}}C[i]=num;num_C++;return i+1;}/*Reserve方法,读入一个字符判断是不是界符,如果是界符,则返回符合界符数组的下标+3,否则返回0*/int Reserve(char *str){int i;for (i=0;i<num_key;i++){//判断str的元素是不是keywords里的if (!strcmp(keywords[i],str)){return (i+1);}}return 0;}/*InsertId方法,输入一个字符返回当前的字符串在ID字符串数组中的下标*/int InsertID(char *str){//查看在ID数组中有没有和输入字符串相同的元素//第一个字符串没有,i=num_ID=0int i;for (i=0;i<num_ID;i++){if (!strcmp(ID[i],str)){return i+1;}}//将当前输入的str copy到ID[i]中strcpy(ID[i],str);num_ID++;return i+1;}

编译原理:实验一练习相关推荐

  1. html解析器编译原理,编译原理实验报告词法分析器(内含源代码).docx

    编译原理实验报告词法分析器(内含源代码) 编译原理实验(一) --词法分析器 实验描述 运行环境:vc++2008 对某特定语言A ,构造其词法规则. 该语言的单词符号包括: 1该程序能识别的单词符号 ...

  2. 编译原理逆波兰式实验java_逆波兰式算法的编译原理实验过程.doc

    逆波兰式算法的编译原理实验过程 实验目的 深入理解算符优先分析法 掌握FirstVt和LastVt集合的求法有算符优先关系表的求法 掌握利用算符优先分析法完成中缀表达式到逆波兰式的转化 实验内容及要求 ...

  3. 编译原理实验:代码生成作业(1)

    编译原理实验4:中间代码生成实验包-C++文档类资源-CSDN下载编译原理实验4:中间代码生成实验包更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn.net/d ...

  4. 编译实验 lr c语言代码,编译原理-实验5-LR(1)分析法

    <编译原理-实验5-LR(1)分析法>由会员分享,可在线阅读,更多相关<编译原理-实验5-LR(1)分析法(6页珍藏版)>请在人人文库网上搜索. 1.编译原理实验报告项目名称 ...

  5. 编译原理--实验2 语法分析

    文章目录 前言 1.1实验目的 1.2 实验任务 1.3 实验内容 1.3.1 实验要求 1.3.2 输入格式 1.3.3 输出格式 1.3.4 样例 1.4 程序 1.4.1 程序流程图 1.4.2 ...

  6. 编译原理实验二:赋值语句的语法分析程序设计

    编译原理实验二:赋值语句的语法分析程序设计 1.1实验内容 目的: 在前面实验的基础上,通过设计.编制.调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握 ...

  7. 编译原理实验:自上而下语法分析

    编译原理实验:自上而下语法分析 1. 实验题目:自上而下语法分析 实验目的 实验内容 实验要求 输入输出 2. 设计思想 3. 算法流程 4. 源程序 5. 调试数据 1. 实验题目:自上而下语法分析 ...

  8. java编程实现算符优先分析法,编译原理实验三-算符优先分析法

    编译原理实验3-算符优先分析法 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数 ...

  9. 编译原理实验 -- 文法分析

    编译原理实验 – 文法分析 终结符 和 非终结符 终结符 通常使用小写字母表示,例如 abcdef 非终结符 通常使用大写字母表示,例如 ABCDEF 产生式 通俗来说,就是由终结符和非终结符组合成的 ...

  10. c语言词法分析器实验原理,词法分析器的设计与实现 编译原理实验报告.doc

    词法分析器的设计与实现 编译原理实验报告 中北大学软件学院 实 验 报 告 专 业 软件工程 课程名称 编译原理 学 号 姓 名 辅导教师 张静 成绩 实验日期2015.5.19实验时间14:00~1 ...

最新文章

  1. 没有云平台,又不会代码?MicrobiomeAnalyst:一款综合的可视化微生物组学数据分析网页工具
  2. IIS6.0限制上传文件大小的解决办法
  3. (转载)Python数据分析之pandas学习
  4. 第一个WindowService服务
  5. python中readlines,在Python中连续两次使用readlines
  6. 计算机网络选择重传,计算机网络选择重传协议实验报告..docx
  7. 基于android公交车线路查询论文文献,本科毕业论文---基于android的手机公交线路查询系统.doc...
  8. xcode工程命令行生成ipa安装包
  9. H3C批量收集服务器信息,H3C设备服务器采集参数认证过程(包含redfish和restfull协议)...
  10. 插件代码_我们开源了一款 SonarQube iOS 代码扫描插件
  11. python map函数_Python map()函数
  12. plt.imshow显示CT/MRI图像
  13. 破解windows7系统密码
  14. cisco路由器配置
  15. UT000054: The maximum size 1048576 for an individual file in a multipart req
  16. MSE(MeanSquaredError) loss 与 CE(CrossEntropyLoss) loss
  17. 【转载】关于MSHTML
  18. 爬取bilibili视频
  19. 硬件知识:电机驱动芯片——DRV8833、TB6612、A4950、L298N的详解与比较
  20. 机器学习进阶之概率论(1)

热门文章

  1. 时频特性分析(Matlab)
  2. 取特定字符串后的数字 linux_Linux相关操作(四)
  3. 运放使用中不稳定怎么办?
  4. 噪声对于训练神经网络的重要性
  5. Java并发——CAS
  6. 教你怎么样在 Java8 中优雅的避开空指针异常
  7. java B2B2C电子商务平台分析之十一------配置中心和消息总线
  8. 关于REID的mAP指标
  9. 贝塞尔曲线与CAShapeLayer的关系以及Stroke动画
  10. TextVew中文空格