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 词法分析器的更多相关文章

  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. 从零开始学习Linux(ls命令)

    学习Linux已经两年了,可是仍然是小白一个.用过很多命令,可是很多都没记住,基础不扎实,很大程度上是不记笔记,得过且过. 从今天起,开始整理Linux笔记. Linux每个命令都有--help这个选 ...

  2. HDU 2159---FATE---带限制的完全背包

    HDU   2159 Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一 ...

  3. lnmp+phpmyadmin配置与出现问题

    本博客归moka同学(新浪微博:moka同学)本人亲自整理,如有使用,请加链接注明出处. lnmp 安装完全后,配置phpmyadmin .其访问方式为 http://202.18.400.379/p ...

  4. java开发过程中从前台传到后台中文乱码《filter》

    在企业开发中,最常见的是javaweb项目,有web项目就免不了和后台打交道,比如我从jsp页面发送新增请求到后台,后台可能是servlet.struts2.springmvc等,这时就存在一个问题, ...

  5. java service wrapper 级别为info导致内存剧增直至溢出

    上周,公司某一环境发生java service wrapper内存剧增导致最后被自动killed的情况,经过分析,确定导致java service wrapper(后续简称wrapper)守护进程内存 ...

  6. 初识HTTP协议

    本篇文章从概念上初识HTTP协议,参考链接:http://www.runoob.com/http/http-tutorial.html 目录: 一.HTTP协议    HTTP 工作原理    HTT ...

  7. jquery动态创建节点

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. ArcEngine尝试读取或写入受保护的内存

    先说一下我的开发环境: Win10 + ArcGIS10.0 + ArcEngine10.0 + Framework4.0 今天调用新的GP工具则出现"尝试读取或写入受保护的内存.这通常指示 ...

  9. FME2014汉化问题

    问题:FME2014汉化包安装上不起作用,安装环境是是Win7 64位,FME是64位版本的,默认位置在Program Files\FME下,而汉化包安装默认位置在Program Files (x86 ...

  10. Purchase购物车实例分析

    源代码下载地址:http://code4app.com/ios/55655def933bf09d328b5141 此源代码从中学到以下四个知识点 第一:关于右边只有一个被选中的效果展现,左边部分代码内 ...