词法分析器的设计与实现

这篇具有很好参考价值的文章主要介绍了词法分析器的设计与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、实验目的及要求

1.1、实验目的

        加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

1.2、实验要求

        1)对单词的构词规则有明确的定义;

        2)编写的分析程序能够正确识别源程序中的单词符号;

        3)识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;

        4)对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;

2、实验步骤

2.1、词法分析规则

        <标识符>::=<字母>|<标识符><字母>|<标识符><数字>

        <常数>::=<数字>|<数字序列><数字>

        <数字序列>::=<数字序列><数字>|<数字>|<.>

        <字母>::=a|b|c|……|x|y|z

        <数字>::=0|1|2|3|4|5|6|7|8|9

        <运算符>::=<关系运算符>|<算术运算符>|<逻辑运算符>|<位运算符>|<赋值运算符>

        <算数运算符>::=+|-|*|/|...|--

        <关系运算符>::=<|>|!=|>=|<=|==

        <逻辑运算符>::=&&| || |!

        <位运算符>::=&| | |!

        <赋值运算符>::==|+=|-=|/=|*=

        <分界符>::=,|;|(|)|{|}|:| // |/**/

        <保留字>::=main|if|else|while|do|for|...|void

2.2、单词符号的编码

单词符号

种别码

单词符号

种别码

main

0

>

26

if

1

>=

27

else

2

<

28

while

3

<=

29

do

4

!

30

for

5

!=

31

switch

6

=

32

case

7

==

33

int

8

(

34

double

9

)

35

float

10

{

36

long

11

}

37

void

12

;

38

+

13

39

+=

14

|

40

++

15

||

41

-

16

数字

42

-=

17

标识符

43

--

18

,

44

&

19

//

45

&&

20

/**/

46

#

21

*

22

*=

23

/

24

/=

25

2.3、状态转换图

词法分析器的设计与实现,课程设计,c语言,课程设计

2.4、算法分析

        ①词法分析器工作的第一步是输入源程序文本。为了更好地对单词符号识别,把输入串预处理一下。预处理主要滤掉空格,跳过注释、换行符等。

        ②对预处理后的输入串依次扫描单个字符,使用if-while嵌套语句和switch case语句判断字符的类型,具体识别方法可看状态转换图。有时为了确定词性,需要超前扫描,若超前扫描的字符对识别当前单词无用处,则需要退还给输入串,以备识别下一单词字符时使用。

        ③若读入的字符与单词符号编码表的字符匹配不上,则报错,并输出出错行数。对识别处的单词符号以(单词符号,种别码)二元式的形式输出。

3、实验内容

3.1、流程图

词法分析器的设计与实现,课程设计,c语言,课程设计

3.2、程序的变量与函数说明

  • input:全局字符数组,用来存放输入串
  • word:全局字符数组,用来存放获取到的单词符号,限定长度为8
  • ch:全局字符变量,用来存放最新读入的字符
  • syn:全局整型变量,表示单词符号的编码
  • p:全局整型变量,表示当前字符在input数组的位置
  • m:全局整型变量,表示最新读入的字符在word数组的下标
  • line:全局整型变量,当前行数
  • keyword:全局字符数组,存放关键字
  • init():获取输入串
  • isKey():判断关键字的函数,若参数数组中是关键字,则把syn置为该关键字对应的编码并返回1,否则返回0
  • isLetter():判断字母的函数,若参数字符是字母,则返回1,否则返回0
  • isDigit():判断数字的函数,若参数字符是数字,则返回1,否则返回0
  • isSpace():判断空白符的函数,若参数字符是空格、TAB或换行符,则返回1,否则返回0
  • scaner():扫描输入串的函数,对读出的字符进行判断,若是单词符号表中的符号,则将syn置为对应的编码

3.3、源代码

#include <stdio.h>
#include <string.h>

char input[1000];//输入串 
char word[8];//获取到的单词 
char ch;
int syn;//种别码 
int p; 
int m;
int line;//行数 
//关键字 
char keyword[][8]={"main","if","else","while","do","for","switch","case","int","double","float","long","void"};

void scaner(void);
//获取输入串 
void init()
{
	int i=0;
	printf("\n please input a string(end with '#'):\n");
 	do{
		scanf("%c",&ch);
		input[i++]=ch;
	}while(ch!='#');
} 
//判断是不是关键字 
int isKey(char *str)
{	
	int n; 
	for(n=0;n<13;n++)
	{
		if(strcmp(str,keyword[n])==0)
       	{
		   syn=n;
		   return 1;
       	}
	}
	return 0;
}

//判断是不是数字
int  isDigit(char c)
{
	if (c>='0'&&c<='9')
		return 1;
	else
		return 0;
}
//判断是不是字母
int isLetter(char c)
{
	if ((c<='z'&&c>='a')||(c>='A'&&c<='Z'))
		return 1;
	else
		return 0;
} 
int isSpace(char c)
{
	if (c==' '||c=='\t'||c=='\n')
	{
		return 1;
	}
	return 0;
}
void main()
{
	init();//输入字符串 
	line=0;
 	p=0;
	do{
		scaner();
		switch(syn)
	 	{
  			case -1:
  				printf("you have input a wrong string in line %d\n",line);
      			break;
			default: 
	  			printf("( %s,%d )\n",word,syn);
	      		break;
	  	}
	}while(syn!=21);
 }

void scaner(void)
{  
 	//清空word 
    for(m=0;m<8;m++) 
	{
		word[m] = ' ';
	} 
	//读取字符 
	ch=input[p++];
	m=0;
	//当ch为空格或换行符时,继续往下读 
    while(isSpace(ch))
    {
    	if (ch=='\n')
    	{
    		line++;
		}
    	ch=input[p++];
	}
	
	//如果以字母开头 
    if(isLetter(ch))
    {
		//如果往后是字母或数字,把字符存入word中,然后往下继续读 
		//串长超过8则截断 
      	while((isLetter(ch)||isDigit(ch))&&m<8)
      	{
      		word[m++]=ch;
       		ch=input[p++];
     	}
      	p--;
      	syn=43;
      	word[m++]='\0';
      	isKey(word);//判断是不是关键字 
     }
     //如果是以数字开头,并且往后是数字 
	 else if(isDigit(ch))
     {
      	while((isDigit(ch)||ch=='.')&&m<8)
    	{
	    	word[m++]=ch;
	      	ch=input[p++];
    	}
    	//如果数字之后是字母 ,则出错 
    	if (isLetter(ch))
    	{
    		while(!isSpace(ch))
    		{
    			ch=input[p++];
			}
			syn=-1;
			return ;
		}
		p--;
   		syn=42;

    }
    else 
    {
		switch(ch)
		{
			//比较运算符 
			case '<':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='=')
				{
					syn=29;
					word[m++]=ch;
				}
				else
				{
					syn=28;
					p--;
				}
				break;
			case '>':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='=')
				{
					syn=27;
					word[m++]=ch;
				}
				else
				{
					syn=26;
					p--;
				}
				break;
			case '!':
				ch=input[p++];
				if(ch=='=')
				{
					syn=31;
					word[m++]=ch;
				}
				else
				{
					syn=30;
					p--;
				}
				break;
			case '=':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='=')
				{
					syn=33;
					word[m++]=ch;
				}
				else
				{
					syn=32;
					p--;
				}
				break;
			//算术运算符+、-、*、/ 
			case '+':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='+')
				{
					syn=15;
					word[m++]=ch;
				}
				else if(ch=='=')
				{
					syn=14;
					word[m++]=ch;
				}
				else
				{
					syn=13;
					p--;
				}
				break;
			case '-':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='-')
				{
					syn=18;
					word[m++]=ch;
				}
				else if(ch=='=')
				{
					syn=17;
					word[m++]=ch;
				}
				else if (isDigit(ch))
				{
					while(isDigit(ch))
			    	{
				    	word[m++]=ch;
				      	ch=input[p++];
			    	}
			    	p--;
			   		syn=42;
				}
				else
				{ 
					syn=16;
					p--;
				}
				break;
			case '*':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='=')
				{
					syn=23;
					word[m++]=ch;
				}
				else
				{
					syn=22;
					p--;
				}
				break;
			case '/':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='=')
				{
					syn=25;
					word[m++]=ch;
				}
				//如果是单行注释,则读到换行符为止 
				else if (ch=='/')
				{
					word[m++]=ch;
					syn=45;
					while (ch!='\n')
					{
						ch=input[p++];
					}
					line++;
				}
				//如果是多行注释,则读到匹配的*/为止
				else if(ch=='*')
				{
					word[m++]=ch;
					syn=46;
					int flag=1;
					while (flag)
					{
						ch=input[p++];
						if (ch=='*')
						{
							if (input[p++]=='/')
							{
								word[m++]='*';
								word[m++]='/';
								flag=0;
							}
							else
							{
								p--;
							}
						}
						if (ch=='\n')
						{
							line++;
						}
					}
				}
				else
				{
					syn=24;
					p--;
				}
				break;
			//界符 
			case '(': 
				syn=34;
				word[m++]=ch;
				break;
			case ')':
				syn=35;
				word[m++]=ch;
				break;
			case '{': 
				syn=36;
				word[m++]=ch;
				break;
			case '}': 
				syn=37;
				word[m++]=ch;
				break;
			case ';':
				syn=38;
				word[m++]=ch;
				break;
			case '#': 
				syn=21;
				word[m++]=ch;
				break;
			case ':':
				syn=39;
				word[m++]=ch;
				break;
			case ',':
				syn=44;
				word[m++]=ch;
				break;
			//逻辑运算符
			case '&':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='&')
				{
					syn=20;
					word[m++]=ch;
				}
				else
				{ 
					syn=19;
					p--;
				}
				break;
			case '|':
				word[m++]=ch;
				ch=input[p++];
				if(ch=='|')
				{
					syn=41;
					word[m++]=ch;
				}
				else
				{ 
					syn=40;
					p--;
				}
				break;
			default:
				syn=-1;
				break;
			}
	}
	//字符串结束符 
	word[m++]='\0';
}

4、实验结果

词法分析器的设计与实现,课程设计,c语言,课程设计

因为printf和""不是单词符号表中的符号,因而判定输入有错

 词法分析器的设计与实现,课程设计,c语言,课程设计

 词法分析器的设计与实现,课程设计,c语言,课程设计

 完整实验报告:词法分析器的设计与实现-C文档类资源-CSDN文库文章来源地址https://www.toymoban.com/news/detail-646746.html

到了这里,关于词法分析器的设计与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编译原理词法分析器(C/C++)

            词法分析器不用多说,一开始我还不知道是什么样的,看了下别人的博客,再看看书,原来是输出二元组,这不就是字符串操作嘛。然后细看几篇博客,发现大都是用暴力判断来写的。我对代码重复性比较高的方法不太感冒,不是说我编程有多好,就是单纯的不喜欢

    2024年02月06日
    浏览(60)
  • 编译原理C++单词拼装器&词法分析器实验思路

    本文只涉及功能实现的思路,针对期末复习,不涉及制作操作界面。 实验内容 1. 把C++源代码中的各类单词(记号)进行拼装分类。 C++语言包含了几种类型的单词(记号):标识符,,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等【详细

    2024年04月08日
    浏览(51)
  • HNU-编译原理-实验1-利用FLEX构造C-Minus-f词法分析器

    计科210X 甘晴void 202108010XXX 详细的实验项目文档为 https://gitee.com/coderwym/cminus_compiler-2023-fall/tree/master/Documentations/lab1 学习和掌握词法分析程序的逻辑原理与构造方法。通过 FLEX 进行实践, 构造 C-Minus-f 词法分析器。具体完成过程如下: 学习 C-Minus-f 的词法规则 学习 FLEX 工具使

    2024年01月20日
    浏览(55)
  • 编译原理实验三:预测分析法语法分析器的设计

    ​ 根据文法编制预测分析法语法分析程序,以便对输入的符号串进行语法分析。通过编写预测分析法语法分析程序掌握预测分析法的基本原理、FIRST和FOLLOW集的计算、预测分析表的构造方法以及语法分析法主控程序的设计。 对于给定的上下文无关文法,编程完成以下功能:

    2024年02月05日
    浏览(55)
  • 基于PyTorch的中文情绪分析器设计与开发

    收藏和点赞,您的关注是我创作的动力    情感分析在最近的十年内得到了快速的发展,这归功于大数据的支持。相较于英语而言,中文的使用同样广泛。如何把握中文里的情感也是服务行业所关注的问题。本文旨在研究中文情绪分析的设计与开发,意在基于Pytorch平台,利

    2024年02月06日
    浏览(49)
  • 编译原理——语法分析器(C/C++代码实现)

    编写一个简单的LL(1)语法分析器。(注意:此实验是简化版的LL(1)文法,已给出预测分析表,不需要求FIRST和FOLLOW集,直接根据预测分析表编写程序即可) 根据编译原理理论课中学习的算术表达式文法,以及该文法LL(1)分析表,用C语言编写接受算术表达式为输入的语法

    2023年04月26日
    浏览(40)
  • 编译原理——SLR(1)语法分析器(C/C++代码实现)

    设计、编制、实现并调试SLR(1)语法分析器,加深对语法分析的理解。 根据编译原理理论课中学习的算术表达式文法以及该文法的LR分析表,用C语言编写接受算术表达式为输入的语法分析器,以控制台(或文本文件,也可以结合词法分析器完成)为输入,控制台(或文件)

    2024年02月11日
    浏览(41)
  • 【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数01

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让 云上运动会、线上运动会、健身打卡、AI体育指导 等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从

    2024年02月09日
    浏览(46)
  • 【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数02

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让 云上运动会、线上运动会、健身打卡、AI体育指导 等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从

    2024年02月13日
    浏览(47)
  • 分析器:常见问题

    源生成器(增量生成器)由于它特殊的定位,关于它的调试十分困难。在这里分享一些调试它的经验。 另外经常有写类库,然后提供可以生成代码的Attribute给用户的需求,此时需要用到传递引用的知识点。 源生成器项目和普通的项目不同。 普通的会在你按下运行或调试后才

    2024年02月01日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包