一个词法分析器源码的剖析
一,词法分析器
作用:读取源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列
二,设计原理
1)C程序语言的符号分类:关键字、标识符、常数、运算符、界符
2)词法分析器的二元输出:<单词种别,单词符号属性值>
3)正规式和状态转换图
4)程序说明:
1>main 中打开源码文件,从第一个字符流读取
2>如果第一个是字符,则交给letterprocess(str); 处理
3>如果第一个是数字,则交给numberprocess(str); 处理
4>如果第一个是数字,则交给otherprocess(str);处理
5>注意上述过程中,File *fp每读取一个词素,fp都会移动到下一个词素。对于空格的处理:isspace(ch)检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符
('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况
这个程序输出结果情况汇总:关键字、算术运算符、关系运算符、分割符号、特殊符号、注释符号、逻辑运算符、非法符号
三,程序源码
Html代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <conio.h>
#define NULL 0
FILE *fp;
char ch;
char *keyword[34]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef", "printf",
"union","unsigned","void","volatile","while","main"};
char *operatornum[6]={"+","-","*","/","++","--"};
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="};
char *interpunction[8]={",",";",":=",".","(",")","{","}"};
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊标识符
char *zhushifu[3]={"//","/*","*/"};//注释符
char *luoji[3]={"&&","||","!"};//逻辑运算符
bool search(char searchstr[],int wordtype)//符号匹配
{
int i;
switch (wordtype)
{
case 1:
for(i=0;i<=33;i++)
{
if(strcmp(keyword[i],searchstr)==0)
return(true);
}
break;
case 2:
for(i=0;i<=5;i++)
{
if(strcmp(operatornum[i],searchstr)==0)
return(true);
}
break;
case 3:
for(i=0;i<=7;i++)
{
if(strcmp(comparison[i],searchstr)==0)
return(true);
}
break;
case 4:
for(i=0;i<=7;i++)
{
if(strcmp(interpunction[i],searchstr)==0)
return(true);
}
break;
case 5:
for(i=0;i<=5;i++)
{
if(strcmp(biaoshifu[i],searchstr)==0)
return(true);
}
break;
case 6:
for(i=0;i<=2;i++)
{
if(strcmp(zhushifu[i],searchstr)==0)
return(true);
}
break;
case 7:
for(i=0;i<=2;i++)
{
if(strcmp(luoji[i],searchstr)==0)
return(true);
}
break;
}
return false;
}
char letterprocess (char ch)//字母处理函数
{
int i=-1;
char letter[20];
while (isalnum(ch)!=0)
{
letter[++i]=ch;
ch=fgetc(fp);
}
letter[i+1]='\0';
if (search(letter,1))
{
printf("<%s,关键字>\n",letter);
//strcat(letter,"\n");
//fputs('<' letter '>\n',outp);
}
else
{
printf("<%s,自定义变量>\n",letter);
//strcat(letter,"\n");
//fputs(letter,outp);
}
return(ch);
}
char numberprocess(char ch)//数字处理程序
{
int i=-1;
char num[20];
while (isdigit(ch)!=0)
{
num[++i]=ch;
ch=fgetc(fp);
}
if(isalpha(ch)!=0)//数字后面是字符
{
while(isspace(ch)==0)
{
num[++i]=ch;
ch=fgetc(fp);
}
num[i+1]='\0';
printf("错误!非法标识符:%s\n",num);
goto u;
}
num[i+1]='\0';
printf("<%s,数字>\n",num);
u: return(ch);
}
char otherprocess(char ch)//其他处理程序
{
int i=-1;
char other[20];
if (isspace(ch)!=0)
{
ch=fgetc(fp);
goto u;
}
while ((isspace(ch)==0)&&(isalnum(ch)==0))
{
other[++i]=ch;
ch=fgetc(fp);
}
other[i+1]='\0';
if (search(other,2))
printf("<%s,算数运算符>\n",other);
else if (search(other,3))
printf("<%s,关系运算符号>\n",other);
else if (search(other,4))
printf("<%s,分隔符号>\n",other);
else if (search(other,5))
printf("<%s,特殊标识符号>\n",other);
else if (search(other,6))
printf("<%s,注释符号>\n",other);
else if (search(other,7))
printf("<%s,逻辑运算符号>\n",other);
else
printf("错误!非法字符:%s\n",other);
u: return (ch);
}
int main ()
{
char str;
printf("**********************************词法分析器************************************\n");
if ((fp=fopen("源程序.txt","r"))==NULL)
printf("源程序无法打开!\n");
else
{
str =fgetc(fp);//从流中读取字符
while (str!=EOF)
{
if (isalpha(str)!=0)//如果是字符 isalpha包含在#include <cctype>
str=letterprocess(str);
else
{
if (isdigit(str)!=0)
str=numberprocess(str);
else
str=otherprocess(str);
}
};
printf("词法分析结束,谢谢使用!\n");
//printf("点任意键退出!\n");
}
//c=getch();
return 0;
}
一个词法分析器源码的剖析相关推荐
- libevent源码深度剖析
原文地址:http://blog.csdn.net/sparkliang/article/details/4957667 libevent源码深度剖析一 --序幕 张亮 1 前言 Libevent是一 ...
- libevent源码深度剖析八
libevent源码深度剖析八 --集成信号处理 张亮 现在我们已经了解了libevent的基本框架:事件管理框架和事件主循环.上节提到了libevent中I/O事件和Signal以及Timer事件的 ...
- libevent源码深度剖析一
libevent源码深度剖析一 --序幕 张亮 1 前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少.写这一系列文章的用意在于,一则分享心得:二则对libe ...
- libevent 源码深度剖析十三
libevent 源码深度剖析十三 -- libevent 信号处理注意点 前面讲到了 libevent 实现多线程的方法,然而在多线程的环境中注册信号事件,还是有一些情况需要小心处理,那就是不能在多 ...
- libevent源码深度剖析十二
libevent源码深度剖析十二 --让libevent支持多线程 张亮 Libevent本身不是多线程安全的,在多核的时代,如何能充分利用CPU的能力呢,这一节来说说如何在多线程环境中使用libev ...
- libevent源码深度剖析九
libevent源码深度剖析九 --集成定时器事件 张亮 现在再来详细分析libevent中I/O事件和Timer事件的集成,与Signal相比,Timer事件的集成会直观和简单很多.Libevent ...
- libevent源码深度剖析六
libevent源码深度剖析六 --初见事件处理框架 张亮 前面已经对libevent的事件处理框架和event结构体做了描述,现在是时候剖析libevent对事件的详细处理流程了,本节将分析libe ...
- libevent源码深度剖析五
libevent源码深度剖析五 --libevent的核心:事件event张亮 对事件处理流程有了高层的认识后,本节将详细介绍libevent的核心结构event,以及libevent对event的管 ...
- libevent源码深度剖析四
libevent源码深度剖析四 --libevent源代码文件组织 1 前言 详细分析源代码之前,如果能对其代码文件的基本结构有个大概的认识和分类,对于代码的分析将是大有裨益的.本节内容不多,我想并不 ...
最新文章
- Django 一些 简单 配置
- BufferedWriterTest
- Mac/Linux 安装联邦学习 Fate 框架单机部署所需的依赖(填坑大全)
- VMware 修复可窃取管理员凭据的高危漏洞
- python版本时间_python 获取文件版本号和修改时间
- 基于java springboot活动报名微信小程序源码(毕设)
- xml网站地图在线生成制作工具
- 快闪类企业校园招聘H5,这么设计才够炫!
- UE脱机激活如何不拔网线实现在线激活
- 向量的加减(运算符重载)
- Android 微信支付的统一下单
- cycJava基础以及集合总结
- 关于Android写入文件失败的问题
- java erc 2.0_如何使用java监听Erc20Token交易
- TRC丨艾美捷TRC ACP-5197说明书
- 视觉增强词向量:我是词向量,我开眼了!
- 判断是否已经安装vc2008运行时库
- JS判断输入的是否汉字
- Gox语言中配置在Linux系统中使用Sciter来进行GUI图形界面编程-GX23.2
- 对于SR协议而言,为什么滑动窗口长度必须小于或等于序号空间大小的一半?