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. 简单封装cookie操作

    1 //设置cookie 2 function setCookie(name, value, day) { 3 var oDate = new Date(); 4 oDate.setDate(oDat ...

  2. C# Sqlite事务

    在 C#中执行Sqlite数据库事务有两种方式:Sql代码和C#代码 1.Sql代码: BEGIN… COMMIT /ROLLBACK 2.C#代码: using (SQLiteConnection ...

  3. vIDC v2.0 强大的端口转发神器使用总结-开放内网tfs代码服务

    vIDC2.0 端口映射工具,最近在公司闲来无事,想自己整个tfs来管理自己的研究代码. 本来是想用微软Visual Studio提供的免费tfs,但是无奈速度太慢.他们的服务器在美国,中国也没有代理 ...

  4. Ettercap中间人攻击--介绍

    前言 Ettercap有四种界面:Text,Curses,GTK2,Daemonize. -T      命令行界面,只显示字符.通常与配套的参数有-q(安静模式),加上该选项,则不会显示抓到的数据包 ...

  5. GridView总结一:GridView自带分页及与DropDownList结合使用

    GridView自带的分页功能实现: 要实现GrdView分页的功能 操作如下: 1.更改GrdView控件的AllowPaging属性为true. 2.更改GrdView控件的PageSize属性为 ...

  6. view.performClick()触发点击事件

    1.主要作用 自动触发控件的点击事件 2.界面的布局文件  activity_main.xml <RelativeLayout xmlns:android="http://schema ...

  7. UWP开发-重新理解MVVM

    MVVM是一个比较热门的开发框架,尽管已经出现很久了,仍然比较受欢迎.MVVM框架包括: M:Model:Model指的是数据模型,例如你要在页面展示联系人信息,那么Model就是联系人的模型,包括联 ...

  8. App开发流程之字符串处理工具类

    记录字符串的处理,不是一个简单的工作. NSString是代码中随处可见的类型,也是应用和处理繁多的对象,在此只记录需要常备的方法,并且加以说明. #pragma mark -- [计算字符串尺寸 + ...

  9. iOS之github第三方框架(持续更新)

    1.MBProgressHUD MBProgressHUD是一个开源项目,实现了很多种样式的提示框 使用上简单.方便,并且可以对显示的内容进行自定义,功能很强大,很多项目中都有使用到. 到Github ...

  10. javascripts 实习自动提交表单 onsubmit

    html: <form id="formwb" onsubmit="return setPassword();"> <script> d ...