PL/0 词法分析器

  1. #include<stdio.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. typedef enum SymEnum
  7. {
  8. Identifier=, //标识符
  9. Const=, //常数
  10. Key=, //关键字
  11. Operator=, //运算符
  12. Delimiter= //界符
  13. } SymEnum;
  14.  
  15. char KeyWord[][]; //关键字
  16.  
  17. void Init()
  18. {
  19. strcpy(&KeyWord[][],"begin");
  20. strcpy(&KeyWord[][],"call");
  21. strcpy(&KeyWord[][],"const");
  22. strcpy(&KeyWord[][],"do");
  23. strcpy(&KeyWord[][],"end");
  24. strcpy(&KeyWord[][],"if");
  25. strcpy(&KeyWord[][],"odd");
  26. strcpy(&KeyWord[][],"procedure");
  27. strcpy(&KeyWord[][],"read");
  28. strcpy(&KeyWord[][],"then");
  29. strcpy(&KeyWord[][],"var");
  30. strcpy(&KeyWord[][],"while");
  31. strcpy(&KeyWord[][],"write");
  32. }
  33.  
  34. //判断一个单词是否为关键字
  35. int IsKeyWord(char *word)
  36. {
  37. int i=,j=;
  38. while(i<=j)
  39. {
  40. int k=(i+j)/;
  41. if(strcmp(word,KeyWord[k])<=)
  42. j=k-;
  43. if(strcmp(word,KeyWord[k])>=)
  44. i=k+;
  45. }
  46. return i->j ? : ;
  47. }
  48.  
  49. //判断一个单词是否为界符
  50. int IsDelimiter(char word)
  51. {
  52. if(word==','||word==';'||word=='.'||word=='('||word==')')
  53. return ;
  54. return ;
  55. }
  56.  
  57. //判断一个单词是否为操作符
  58. int IsOperator(char *word)
  59. {
  60. if(word[]=='+'||word[]=='-'||word[]=='*'||word[]=='/'||word[]=='<'||word[]=='>'||strcmp(word,":=")==||strcmp(word,">=")==||strcmp(word,"<=")==||word[]=='#'||word[]=='=')
  61. return ;
  62. return ;
  63. }
  64.  
  65. //判断一个单词是否是常数
  66. int IsConst(char *word)
  67. {
  68. if(word[]>=''&&word[]<='')
  69. return ;
  70. return ;
  71. }
  72.  
  73. //判断连个字符是否属于相同类型
  74. int IsSame(char f,char s)
  75. {
  76. int bf = (f>=''&&f<=''||f>='a'&&f<='z'||f>='A'&&f<='Z')? : ;
  77. int bs = (s>=''&&s<=''||s>='a'&&s<='z'||s>='A'&&s<='Z')? : ;
  78. return bf == bs;
  79. }
  80.  
  81. //判断 word 的类型
  82. SymEnum TypeOfWord(char *word)
  83. {
  84. if(IsKeyWord(word))
  85. return Key;
  86. if(IsConst(word))
  87. return Const;
  88. if(IsOperator(word))
  89. return Operator;
  90. return Identifier;
  91. }
  92.  
  93. int GetSym()
  94. {
  95. FILE *fp,*fout;
  96. if((fp=fopen("PL0.txt","r"))==NULL || (fout=fopen("source.txt","w+"))==NULL)
  97. {
  98. printf("Open Error!\n");
  99. exit();
  100. }
  101. SymEnum SYM; //存放每个单词的类别,用内部编码形式表示;
  102. char word[]; //存储单词
  103. word[]='\0';
  104. int len=; //单词长度
  105. char ch;
  106. while(fscanf(fp,"%c",&ch)!=EOF)
  107. {
  108. // ch 为空格,回车符,制表符
  109. if(ch==' '||ch=='\n'||ch=='\t')
  110. {
  111. // word 不为空
  112. if(len)
  113. {
  114. //判断单词类型
  115. SYM=TypeOfWord(word);
  116. fprintf(fout,"%d %s\n",SYM,word);
  117. //清空缓存区
  118. len=;
  119. word[len]='\0';
  120. }
  121. // word 为空,忽略 ch
  122. }
  123. else if(IsDelimiter(ch))
  124. {
  125. //word 不为空
  126. if(len)
  127. {
  128. //判断单词的类型
  129. SYM=TypeOfWord(word);
  130. fprintf(fout,"%d %s\n",SYM,word);
  131. // ch == delimiter
  132. SYM=Delimiter;
  133. fprintf(fout,"%d %c\n",SYM,ch);
  134. //清空缓存区
  135. len=;
  136. word[len]='\0';
  137. }
  138. else
  139. {
  140. //word 为空, ch 为界符
  141. SYM=Delimiter;
  142. fprintf(fout,"%d %c\n",SYM,ch);
  143. //清空缓存区
  144. len=;
  145. word[len]='\0';
  146. }
  147. }
  148. else
  149. {
  150. if(len>)
  151. {
  152. if(IsSame(word[len-],ch))
  153. {
  154. //判断 word 与 ch 是否同类型
  155. word[len++]=ch;
  156. word[len]='\0'; //字符串终结符
  157. }
  158. else
  159. {
  160. //判断单词类型
  161. SYM=TypeOfWord(word);
  162. fprintf(fout,"%d %s\n",SYM,word);
  163. //清空缓存区,并把 ch 放入缓存区
  164. len=;
  165. word[len++]=ch;
  166. word[len]='\0'; //字符串终结符
  167. }
  168. }
  169. else
  170. {
  171. word[len++]=ch;
  172. word[len]='\0';
  173. }
  174. }
  175. }
  176. fclose(fp);
  177. fclose(fout);
  178. return ;
  179. }
  180.  
  181. void PrintToScream()
  182. {
  183. FILE *fp;
  184. if((fp=fopen("source.txt","r+"))==NULL)
  185. {
  186. printf("Open File Error!\n");
  187. exit();
  188. }
  189. int id;
  190. char word[];
  191. printf("0-标识符 1-常数 2-关键字 3-操作符 4-界符\n");
  192. while(fscanf(fp,"%d %s",&id,word)!=EOF)
  193. {
  194. printf("(%d,%s)\n",id,word);
  195. }
  196. fclose(fp);
  197. }
  198.  
  199. int main()
  200. {
  201. Init();
  202. GetSym();
  203. PrintToScream();
  204. return ;
  205. }

PL/0 词法分析器的更多相关文章

  1. PL/0语言词法分析器

    前言:关于词法分析的基础知识的介绍可以看一下这篇博客,我再累述估计也不会有这篇讲的清楚QAQ. https://www.cnblogs.com/yanlingyin/archive/2012/04/1 ...

  2. PL/0编译器(java version)–Praser.java

    1: package compiler; 2:   3: import java.io.IOException; 4: import java.util.BitSet; 5:   6: /** 7: ...

  3. 编译原理--05 用C++手撕PL/0

    前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...

  4. PL/0编译器实践---后记

    花了几天时间,把清华版的<编译原理>一书中的PL/0编译器实践了一遍.颇有收获,记录如下: 理解代码的技巧,如何理解一份代码,比如这个程序,其逻辑相对于一般程序就比较复杂了,如何翻译,虚拟 ...

  5. PL/0语言编译器的设计与实现

    一.设计任务 1.1程序实现要求 PL/0语言可以看成PASCAL语言的子集,它的编译程序是一个编译解释执行系统.PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关. PL/0的编译程序和 ...

  6. PL/0编译器(java version) - MainFrame.java

    1: /* 2: * To change this license header, choose License Headers in Project Properties. 3: * To chan ...

  7. 北航 编译实践 PL/0文法

    编译实践-PL\0编译系统实现 姓名:   专业: 计算机科学与技术 学院: 软件学院 提交时间: 2013年12月25日 北京航空航天大学·软件学院 编译实践-PL\0编译系统实现 实验要求 以个人 ...

  8. PL/0与Pascal-S编译器程序详细注释

    学校编译课的作业之一,要求阅读两个较为简单的编译器的代码并做注释, 个人感觉是一次挺有意义的锻炼, 将自己的心得分享出来与一同在进步的同学们分享. 今后有时间再做进一步的更新和总结,其中可能有不少错误 ...

  9. PL/0编译程序

    Pl/0语言文法的BNF表示: 〈程序〉→〈分程序>. 〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 <常量说明部 ...

随机推荐

  1. transfer between javabean and map

    1. java bean 转化成 map import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.P ...

  2. (旧)子数涵数·UI设计——扁平化设计

    一.基本资料 1.由来 扁平化设计这个概念,是由Google(谷歌)在2008年提出的:它的首个实践者是microsoft(微软),microsoft在2012年发行了win8系统,这个系统的外观主题 ...

  3. Oauth笔记

    上周的工作有安全验证这一块,但不懂,只知道有几个关键字Oauth.secret-key .token.签名等.今天就查下资料做笔记. Oauth是什么 不依靠用户账号和密码就能获得访问资源权限 本质: ...

  4. YUIDoc example代码高亮错误、生成API文档目录不按源文件注释顺序

    1.如果发现yuidoc命令用不了,那就重装nodejs吧 昨天不知道是清扫电脑的原因,yuidoc命令用不了(命令不存在),也没有找到好的解决方法,怒重装YUIDoc也不行.最后想了想,怒重装了no ...

  5. teambition的热血团队

    一群热血年轻人开发了一套项目协作软件teambition,无意帮他们宣传,更多见网址www.teambition.com. 网站上简短的一段话,深深的打动了我.他们说teambition: 由热爱工作 ...

  6. IOS开发之功能模块--自定义UITabBarViewController的备用代码

    前言:因为常用,所以我就备份到这里,然后如果需要修改,可以根据需求进行相关的更改. @implementation YMTabBarController - (void)viewDidLoad { [ ...

  7. linux+jre+apache+mysql+tomcat调优

    一.不再为Apache进程淤积.耗尽内存而困扰 0. /etc/my.cnf,在mysqld那一段加上如下一行: log-slow-queries=queries-slow.log 重启MySQL 酌 ...

  8. Linux线程学习(二)

    线程基础 进程 系统中程序执行和资源分配的基本单位 每个进程有自己的数据段.代码段和堆栈段 在进行切换时需要有比较复杂的上下文切换   线程 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, ...

  9. mysql集群之MYSQL CLUSTER

    1. 参考文档 http://xuwensong.elastos.org/2014/01/13/ubuntu-%E4%B8%8Bmysql-cluster%E5%AE%89%E8%A3%85%E5%9 ...

  10. MongoDb的bin目录下文件mongod,mongo,mongostat命令的说明及使用

    MongoDB的下载地址:http://www.mongodb.org/downloads. 下载好直接解压安装包,即可使用. bin目录下的几个文件说明: mongo 客户端程序,连接MongoDB ...