设为首页 加入收藏

TOP

编译原理:C语言词法分析器(一)
2016-04-26 11:12:36 】 浏览:1142
Tags:编译 原理 语言 词法 分析器

编译原理的实验:完成对C语言的词法分析

先说一下整体框架:

基类:Base 封装了一些基础的字符判断函数,如下:

int charkind(char c);//判断字符类型
	int spaces(char c); //当前空格是否可以消除
	int characters(char c);//是否是字母
	int keyword(char str[]);//是否是关键字
	int signwords(char str[]);//是否是标识符
	int numbers(char c);//是否是数字
	int integers(char str[]);//是否是整数
	int floats(char str[]);//是否是浮点型

派生类 LexAn 继承Base并且封装了对行和单词处理的函数,如下:

void scanwords(); //处理每一行
		void clearnotes();//清除注释和多余的空格
		void getwords(int state);//处理出单词
		void wordkind(char str[]);//判断单词类型并且输出

函数之间调用关系如下:

\

好了,整体框架说完了,我们来说具体的实现:

(一)清除注释和多余的空格

(1)C语言的注释有//和/* 两种形式,所以如果当前读进的是 / 只需分情况判断下一个:

如果是/ 那么本行 //之后的肯定都是注释,只需要保存注释,更新当前行即可;

如果是* ,那么接着寻找直至 */位置,保存注释,更新当前行,然后继续这个操作(有可能有本行有多个 /* */).

不足:不能处理跨行注释。

(2)处理多余的空格这里较为草率,只处理了形如if ( a >= b ),即特殊符号和字母(数字)之间的空格;只要空格两端有特殊符号,那么去掉当前空格便不会造成错误。

void LexAn::clearnotes()
{
	int i, j, k;
	int noteCount = 0;
	int flag = 0;
	char note[100];

	/*注释*/
	for (i = 0; bufferin[buffernum][i] != '\0'; i++)
	{
		if (bufferin[buffernum][i] == '"')
		{
			flag = 1 - flag;
			continue;
		}
		if (bufferin[buffernum][i] == '/' && flag == 0)
		{
			if (bufferin[buffernum][i + 1] == '/')
			{
				for (j = i; bufferin[buffernum][j] != '\0'; j++)
				{
					note[noteCount++] = bufferin[buffernum][j];
				}
				note[noteCount] = '\0';
				noteCount = 0;
				fprintf(fout, "  [ %s ]  ----  [ 注释 ]\n", note);
				bufferin[buffernum][i] = '\0';
				break;
			}

			if (bufferin[buffernum][i + 1] == '*')
			{
				note[noteCount++] = '/';
				note[noteCount++] = '*';
				for (j = i + 2; bufferin[buffernum][j] != '\0'; j++)
				{
					note[noteCount++] = bufferin[buffernum][j];
					if (bufferin[buffernum][j] == '*' && bufferin[buffernum][j + 1] == '/')
					{
						j += 2;
						note[noteCount++] = bufferin[buffernum][j];
						note[noteCount] = '\0';
						noteCount = 0;
						fprintf(fout, "  [ %s ]  ----  [ 注释 ]\n", note);
						break;
					}
				}
				for (; bufferin[buffernum][j] != '\0'; j++, i++)
				{
					bufferin[buffernum][i] = bufferin[buffernum][j];
				}
				if (bufferin[buffernum][j] == '\0')
				{
					bufferin[buffernum][i] = '\0';
				}
			}
		}
	}

	//空格 
	for (i = 0, flag = 0; bufferin[buffernum][i] != '\0'; i++)
	{
		if (bufferin[buffernum][i] == '"')
		{
			flag = 1 - flag;
			continue;
		}
		if (bufferin[buffernum][i] == ' ' && flag == 0)
		{
			for (j = i + 1; bufferin[buffernum][j] != '\0' && bufferin[buffernum][j] == ' '; j++)
			{
			}
			if (bufferin[buffernum][j] == '\0')
			{
				bufferin[buffernum][i] = '\0';
				break;
			}
			if (bufferin[buffernum][j] != '\0' && ((spaces(bufferin[buffernum][j]) == 1) || (i > 0 && spaces(bufferin[buffernum][i - 1]) == 1)))
			{
				for (k = i; bufferin[buffernum][j] != '\0'; j++, k++)
				{
					bufferin[buffernum][k] = bufferin[buffernum][j];
				}
				bufferin[buffernum][k] = '\0';
				i--;
			}
		}
	}

	//制表符 
	for (i = 0, flag = 0; bufferin[buffernum][i] != '\0'; i++)
	{
		if (bufferin[buffernum][i] == '\t')
		{
			for (j = i; bufferin[buffernum][j] != '\0'; j++)
			{
				bufferin[buffernum][j] = bufferin[buffernum][j + 1];
			}
			i = -1;
		}
	}
}

(二)最重要的状态机的转化

画图不是很好话,我尽量用语言清除地描述,大家还需结合源码分析:

主要分为 <字母, 1> <数字, 2> <$ _ , 3> <4 ,/ >(转义)

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇用C语言讲一讲位运算 入门级(详.. 下一篇一个C语言开发的炸金花纸牌游戏附..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目