PL/0 词法分析器
PL/0 词法分析器
- #include<stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- typedef enum SymEnum
- {
- Identifier=, //标识符
- Const=, //常数
- Key=, //关键字
- Operator=, //运算符
- Delimiter= //界符
- } SymEnum;
- char KeyWord[][]; //关键字
- void Init()
- {
- strcpy(&KeyWord[][],"begin");
- strcpy(&KeyWord[][],"call");
- strcpy(&KeyWord[][],"const");
- strcpy(&KeyWord[][],"do");
- strcpy(&KeyWord[][],"end");
- strcpy(&KeyWord[][],"if");
- strcpy(&KeyWord[][],"odd");
- strcpy(&KeyWord[][],"procedure");
- strcpy(&KeyWord[][],"read");
- strcpy(&KeyWord[][],"then");
- strcpy(&KeyWord[][],"var");
- strcpy(&KeyWord[][],"while");
- strcpy(&KeyWord[][],"write");
- }
- //判断一个单词是否为关键字
- int IsKeyWord(char *word)
- {
- int i=,j=;
- while(i<=j)
- {
- int k=(i+j)/;
- if(strcmp(word,KeyWord[k])<=)
- j=k-;
- if(strcmp(word,KeyWord[k])>=)
- i=k+;
- }
- return i->j ? : ;
- }
- //判断一个单词是否为界符
- int IsDelimiter(char word)
- {
- if(word==','||word==';'||word=='.'||word=='('||word==')')
- return ;
- return ;
- }
- //判断一个单词是否为操作符
- int IsOperator(char *word)
- {
- if(word[]=='+'||word[]=='-'||word[]=='*'||word[]=='/'||word[]=='<'||word[]=='>'||strcmp(word,":=")==||strcmp(word,">=")==||strcmp(word,"<=")==||word[]=='#'||word[]=='=')
- return ;
- return ;
- }
- //判断一个单词是否是常数
- int IsConst(char *word)
- {
- if(word[]>=''&&word[]<='')
- return ;
- return ;
- }
- //判断连个字符是否属于相同类型
- int IsSame(char f,char s)
- {
- int bf = (f>=''&&f<=''||f>='a'&&f<='z'||f>='A'&&f<='Z')? : ;
- int bs = (s>=''&&s<=''||s>='a'&&s<='z'||s>='A'&&s<='Z')? : ;
- return bf == bs;
- }
- //判断 word 的类型
- SymEnum TypeOfWord(char *word)
- {
- if(IsKeyWord(word))
- return Key;
- if(IsConst(word))
- return Const;
- if(IsOperator(word))
- return Operator;
- return Identifier;
- }
- int GetSym()
- {
- FILE *fp,*fout;
- if((fp=fopen("PL0.txt","r"))==NULL || (fout=fopen("source.txt","w+"))==NULL)
- {
- printf("Open Error!\n");
- exit();
- }
- SymEnum SYM; //存放每个单词的类别,用内部编码形式表示;
- char word[]; //存储单词
- word[]='\0';
- int len=; //单词长度
- char ch;
- while(fscanf(fp,"%c",&ch)!=EOF)
- {
- // ch 为空格,回车符,制表符
- if(ch==' '||ch=='\n'||ch=='\t')
- {
- // word 不为空
- if(len)
- {
- //判断单词类型
- SYM=TypeOfWord(word);
- fprintf(fout,"%d %s\n",SYM,word);
- //清空缓存区
- len=;
- word[len]='\0';
- }
- // word 为空,忽略 ch
- }
- else if(IsDelimiter(ch))
- {
- //word 不为空
- if(len)
- {
- //判断单词的类型
- SYM=TypeOfWord(word);
- fprintf(fout,"%d %s\n",SYM,word);
- // ch == delimiter
- SYM=Delimiter;
- fprintf(fout,"%d %c\n",SYM,ch);
- //清空缓存区
- len=;
- word[len]='\0';
- }
- else
- {
- //word 为空, ch 为界符
- SYM=Delimiter;
- fprintf(fout,"%d %c\n",SYM,ch);
- //清空缓存区
- len=;
- word[len]='\0';
- }
- }
- else
- {
- if(len>)
- {
- if(IsSame(word[len-],ch))
- {
- //判断 word 与 ch 是否同类型
- word[len++]=ch;
- word[len]='\0'; //字符串终结符
- }
- else
- {
- //判断单词类型
- SYM=TypeOfWord(word);
- fprintf(fout,"%d %s\n",SYM,word);
- //清空缓存区,并把 ch 放入缓存区
- len=;
- word[len++]=ch;
- word[len]='\0'; //字符串终结符
- }
- }
- else
- {
- word[len++]=ch;
- word[len]='\0';
- }
- }
- }
- fclose(fp);
- fclose(fout);
- return ;
- }
- void PrintToScream()
- {
- FILE *fp;
- if((fp=fopen("source.txt","r+"))==NULL)
- {
- printf("Open File Error!\n");
- exit();
- }
- int id;
- char word[];
- printf("0-标识符 1-常数 2-关键字 3-操作符 4-界符\n");
- while(fscanf(fp,"%d %s",&id,word)!=EOF)
- {
- printf("(%d,%s)\n",id,word);
- }
- fclose(fp);
- }
- int main()
- {
- Init();
- GetSym();
- PrintToScream();
- return ;
- }
PL/0 词法分析器的更多相关文章
- PL/0语言词法分析器
前言:关于词法分析的基础知识的介绍可以看一下这篇博客,我再累述估计也不会有这篇讲的清楚QAQ. https://www.cnblogs.com/yanlingyin/archive/2012/04/1 ...
- PL/0编译器(java version)–Praser.java
1: package compiler; 2: 3: import java.io.IOException; 4: import java.util.BitSet; 5: 6: /** 7: ...
- 编译原理--05 用C++手撕PL/0
前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...
- PL/0编译器实践---后记
花了几天时间,把清华版的<编译原理>一书中的PL/0编译器实践了一遍.颇有收获,记录如下: 理解代码的技巧,如何理解一份代码,比如这个程序,其逻辑相对于一般程序就比较复杂了,如何翻译,虚拟 ...
- PL/0语言编译器的设计与实现
一.设计任务 1.1程序实现要求 PL/0语言可以看成PASCAL语言的子集,它的编译程序是一个编译解释执行系统.PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关. PL/0的编译程序和 ...
- PL/0编译器(java version) - MainFrame.java
1: /* 2: * To change this license header, choose License Headers in Project Properties. 3: * To chan ...
- 北航 编译实践 PL/0文法
编译实践-PL\0编译系统实现 姓名: 专业: 计算机科学与技术 学院: 软件学院 提交时间: 2013年12月25日 北京航空航天大学·软件学院 编译实践-PL\0编译系统实现 实验要求 以个人 ...
- PL/0与Pascal-S编译器程序详细注释
学校编译课的作业之一,要求阅读两个较为简单的编译器的代码并做注释, 个人感觉是一次挺有意义的锻炼, 将自己的心得分享出来与一同在进步的同学们分享. 今后有时间再做进一步的更新和总结,其中可能有不少错误 ...
- PL/0编译程序
Pl/0语言文法的BNF表示: 〈程序〉→〈分程序>. 〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 <常量说明部 ...
随机推荐
- transfer between javabean and map
1. java bean 转化成 map import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.P ...
- (旧)子数涵数·UI设计——扁平化设计
一.基本资料 1.由来 扁平化设计这个概念,是由Google(谷歌)在2008年提出的:它的首个实践者是microsoft(微软),microsoft在2012年发行了win8系统,这个系统的外观主题 ...
- Oauth笔记
上周的工作有安全验证这一块,但不懂,只知道有几个关键字Oauth.secret-key .token.签名等.今天就查下资料做笔记. Oauth是什么 不依靠用户账号和密码就能获得访问资源权限 本质: ...
- YUIDoc example代码高亮错误、生成API文档目录不按源文件注释顺序
1.如果发现yuidoc命令用不了,那就重装nodejs吧 昨天不知道是清扫电脑的原因,yuidoc命令用不了(命令不存在),也没有找到好的解决方法,怒重装YUIDoc也不行.最后想了想,怒重装了no ...
- teambition的热血团队
一群热血年轻人开发了一套项目协作软件teambition,无意帮他们宣传,更多见网址www.teambition.com. 网站上简短的一段话,深深的打动了我.他们说teambition: 由热爱工作 ...
- IOS开发之功能模块--自定义UITabBarViewController的备用代码
前言:因为常用,所以我就备份到这里,然后如果需要修改,可以根据需求进行相关的更改. @implementation YMTabBarController - (void)viewDidLoad { [ ...
- linux+jre+apache+mysql+tomcat调优
一.不再为Apache进程淤积.耗尽内存而困扰 0. /etc/my.cnf,在mysqld那一段加上如下一行: log-slow-queries=queries-slow.log 重启MySQL 酌 ...
- Linux线程学习(二)
线程基础 进程 系统中程序执行和资源分配的基本单位 每个进程有自己的数据段.代码段和堆栈段 在进行切换时需要有比较复杂的上下文切换 线程 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, ...
- mysql集群之MYSQL CLUSTER
1. 参考文档 http://xuwensong.elastos.org/2014/01/13/ubuntu-%E4%B8%8Bmysql-cluster%E5%AE%89%E8%A3%85%E5%9 ...
- MongoDb的bin目录下文件mongod,mongo,mongostat命令的说明及使用
MongoDB的下载地址:http://www.mongodb.org/downloads. 下载好直接解压安装包,即可使用. bin目录下的几个文件说明: mongo 客户端程序,连接MongoDB ...