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表示: 〈程序〉→〈分程序>. 〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 <常量说明部 ... 
随机推荐
- Linux修改命令提示符(关于环境参量PS1)
			关乎环境参量的四个文件/etc/profile /etc/bashrc ~/.bashrc ~/.bash_profile $$$:/etc/profile:此文件为系统的每个用户设置环境信息,当 ... 
- 验证坐标在某片坐标区域内 php 代码
			之前碰到的这样一个需求,要将公司的服务范围在地图中显示出来,并将用户每天的访问坐标进行统计看有多少用户是在所能达到的服务范围半径内. 以下是PHP代码的实现 (仅验证坐标在某片坐标区域内) <? ... 
- php正规则表达式的语法
			界定符的三种书写方式: regexpal工具(正规则表达调试工具): 可以实时显示效果出来. 原子: 可见原子,即uincode编码表中的某个字符 不可见原子: 为了避免编码问题导致匹配不正确,要把文 ... 
- java开发过程中从前台传到后台中文乱码《filter》
			在企业开发中,最常见的是javaweb项目,有web项目就免不了和后台打交道,比如我从jsp页面发送新增请求到后台,后台可能是servlet.struts2.springmvc等,这时就存在一个问题, ... 
- Oracle 中 call 和 exec的区别
			今天发现了一个小东西,觉得很有意思,查找了一些资料,跟大家分享一下: 在sqlplus中: 在第三方提供的工具(如:plsqldev) 总结: exec是sqlplus的命令,只能在sqlplus中使 ... 
- winform   属性
			WinForm为客户端程序必须在.NET Framework框架上运行 一.常用属性: 布局: AutoScroll:当控件内容超出可见区域是否显示滚动条: Autosize:当控件内容有超出时是否自 ... 
- chenxi的html学习笔记
			0.本文主体源自:http://www.cnblogs.com/coco1s/p/4034937.html,有兴趣的可以直接去那里看,也可以看看我整理加拓展的.1.浏览器内核: 1.ie:triden ... 
- SharePoint 2013 "通知我"功能简介
			功能简介 "通知我"主要是在列表或者文档库里面的项目,有添加/删除/修改等操作,发送邮件通知设置的用户的功能:可以针对列表或者文档库设置通知,也可以针对单一项目设置通知功能,是Sh ... 
- SharePoint 2013 中自定义WCF服务
			在使用SharePoint2013的时候,如果其他客户端 API 的组合不足,可以通过自定义 Web 服务扩展 SharePoint.默认情况下,SharePoint 2013 不仅支持创建自定义 A ... 
- Android Studio 使用小技巧
			1.如何打开设置界面? File --> Settings 快捷键 Ctrl + Alt + s 2.修改Java文件字体大小 ? File --> Settings --> E ... 
