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. No.012:Integer to Roman

    题目: Given an integer, convert it to a roman numeral.Input is guaranteed to be within the range from ...

  2. Servlet3.0 Test

    1. Servlet3.0 Test and Annotation used 你可以从tomcat7中lib文件夹中找到servlet-api.jar package com.goodfan.serv ...

  3. 发布ASP.NET Core程序到Linux生产环境

    原文翻译:Publish to a Linux Production Environment 作者:Sourabh Shirhatti 在这篇文章里我们将介绍如何在 Ubuntu 14.04 Serv ...

  4. (HY000): Cannot modify @@session.sql_log_bin inside a transaction

    昨天,线上发生一例(HY000): Cannot modify @@session.sql_log_bin inside a transaction代码缺少显示的start transaction控制 ...

  5. C# WM_NCMOUSELEAVE 消息触发

    public static extern bool TrackMouseEvent([In, Out] TRACKMOUSEEVENT lpEventTrack); [DllImport(" ...

  6. android的Project has no default.properties file! Edit the project properties to set one. 的解决

    网上找来这种方法基本解决: 在我们导入Android工程时,有时候会出现如题所述的错误,打开工程目录可以看到,目录下的default.properties文件没有了或者多出了一个project.pro ...

  7. Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39

    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39 V1  初步实现sina csdn cnblogs V2  实现qzone sohu 的发帖 ...

  8. 安卓开发_慕课网_ViewPager与FragmentPagerAdapter实现Tab实现Tab(App主界面)

    学习内容来自“慕课网” ViewPager与FragmentPagerAdapter实现Tab 将这两种实现Tab的方法结合起来.效果就是可以拖动内容区域来改变相应的功能图标亮暗 思路: Fragme ...

  9. HBase读写路径的工作机制

    出处:http://wuyudong.com/1946.html HBase 写路径工作机制 在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的.HBase 接到命令后存下变化信息, ...

  10. C实现通用数据结构--单链表

    单链表概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 从概念上讲,可以把链表想象成一系列连续的元素,然而,由于这些元素是动态分配的(C语言 ...