`
ErinToJerry
  • 浏览: 56639 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
社区版块
存档分类
最新评论

能识别浮点数的简单语法分析程序(C语言实现)

阅读更多

此语法分析程序的基本词法分析能够识别基本字、标识符、有符号整数、有符号浮点数、运算符和界符)。

 

语法结构定义 ::= { +|-} ::= {*|/} ::=ID|num|() num::= ( +|-|ε ) 数字数字*(.数字数字* | ε)( e ( +|-|ε ) 数字数字*|ε) ID::=字母(字母|数字)* 字母::=a|b|c…|z|A|B|C…|Z 数字::=0|1|2…|9

 

词法分析程序需具备词法分析的功能:输入:所给文法的源程序字符串。(字符串以“#”号结束) 输出:success 是文法正确句子;error 不是文法正确句子 例如:输入 a+b*c# 输出success.

 

参考输入字符串:

 

(+123.456+-456.789e-120)*m2+(a++456)*c123

(+123.456+-456.789e-120)*m2+(a++456)*-123

(+123.456+-456.789e-120)*m2+(a++456)*-c123(标识符前加负号,输出error)

d+-11.7e-17

a+-149+49.7e+127+-m123(标识符前加负号,输出error)

a+-149+49.7e+127+m123

((a+b)*-14.79e+127)*379+m32

A+-128e-127-b21

A+-128e-127+-6

 

实现截图:


 

 

源代码:

 

 

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

int isError;

char prog[80]; //存放所有输入字符   
char token[8]; //存放词组   
char ch; //单个字符   
  
int syn,p,m,n;  //syn:种别编码   
double sum;        
int count;   

int isSignal; //是否带正负号(0不带,1负号,2正号)

int isDecimal; //是否是小数   
double decimal;  //小数   
int isExp;  //是否是指数   
int index;  //指数幂   
int isNegative; //是否带负号   
double temp;   
int temp2;

int repeat; //是否连续出现+,-
  
void scanner();   
  
char *rwtab[9]={"main","int","float","double","char","if","else","do","while"};

void E();
void T();
void F();
void scanner();

void main()
{
	p=0;
	count=0;
	isDecimal=0;
	index=0;
	repeat=0;

	printf("\n please input the source string:\n");
	do{
		ch=getchar();
		prog[p++]=ch;
	}while(ch!='#');
	p=0;
	isError=0;
	scanner();
	if((syn==20)||(syn==10)||(syn==26)) 
	{
	E();
	}
	if((ch=='#')&&(isError==0))
		printf("success\n");
	else
		printf("error\n");
}

void E()
{
	T();
	while((syn==22)||(syn==23))
	{
		scanner();
		T();
	}
}

void T()
{
	F();
	while((syn==24)||(syn==25))
	{
		scanner();
		F();
	}
}

void F()
{
	if((syn==20)||(syn==10))
		scanner();
	else if(syn==26)
	{
		scanner();
		E();
		if(syn==27)
		{
			scanner();
		}
		else isError=1;
	}
	else isError=1;
}

void scanner()   
{   
    sum=0;   
    decimal=0;   
    m=0;   

  
    for(n=0;n<8;n++)   
        token[n]=NULL;   
    ch=prog[p++]; //从prog中读出一个字符到ch中   
    while(ch==' ')  //跳过空字符(无效输入)   
        ch=prog[p++];   
  
    if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))) //ch是字母字符   
    {   
        while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9')))   
        {   
            token[m++]=ch; //ch=>token   
            ch=prog[p++]; //读下一个字符   
        }   
        token[m++]='\0';   
        p--; //回退一格   
        syn=10; //标识符   
  
        //如果是"begin","if","then","while","do","end"标识符中的一个   
        for(n=0;n<9;n++)   
            if(strcmp(token,rwtab[n])==0)   
            {   
                syn=n+1;   
                break;   
            }   
    }   
  
   else if((ch>='0')&&(ch<='9'))   
    {   
IsNum:
   if(isSignal==1)
   {
	   //token[m++]='-';
   }
        while((ch>='0')&&(ch<='9'))   
        {   
            sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的   
            ch=prog[p++];   
        }   
        if(ch=='.')   
        {   
            isDecimal=1;   
            ch=prog[p++];   
			count=0; //之前忘了清零,123.123+123.123#两个浮点数就无法识别
            while((ch>='0')&&(ch<='9'))   
            {   
                //pow(x,y)计算x的y次幂   
                temp=(ch-'0')*pow(0.1,++count);   
                decimal=decimal+temp;   
                //AddToDec();   
                ch=prog[p++];   
            }   
            sum=sum+decimal;   
        }   
        if(ch=='e'||ch=='E')   
        {   
            isExp=1;   
            ch=prog[p++];   
            if(ch=='-')   
            {   
                isNegative=1;   
                ch=prog[p++];   
            }   
            while((ch>='0')&&(ch<='9'))   
            {   
                //指数   
                index=index*10+ch-'0';   
                ch=prog[p++];   
            }   
            //10的幂   
            //123e3代表123*10(3)   
            //sum=sum*pow(10,index);是错误的   
            if(isNegative)   
                sum=sum*pow(0.1,index);   
            else  
                sum=sum*pow(10,index);   
  
        }   

		if(isSignal==1)
		{
			sum=-sum;
			isSignal=0;
		}
        p--;   
        syn=20;   
    }   
  
    else switch(ch)   
    {   
        case '<':   
            m=0;   
            token[m++]=ch;   
            ch=prog[p++];    
            if(ch=='=')   
            {   
                syn=35;   
                token[m++]=ch;   
            }   
            else  
            {   
                syn=34;   
                p--;   
            }   
            break;   
  
        case '>':   
            m=0;   
            token[m++]=ch;   
            ch=prog[p++];   
            if(ch=='=')   
            {   
                syn=33;   
                token[m++]=ch;   
            }   
            else  
            {   
                syn=32;   
                p--;   
            }   
            break;   
  
        case '=':   
            m=0;   
            token[m++]=ch;   
            ch=prog[p++];   
            if(ch=='=')   
            {   
                syn=36;   
                token[m++]=ch;   
            }   
            else  
            {   
                syn=21;   
                p--;   
            }   
            break;   
  
		case '+':
			temp2=prog[p];

			token[m++]=ch;

			if((temp2>='0')&&(temp2<='9')&&(repeat==1))
			{
				isSignal=2;
				ch=prog[p++];
				repeat=0;
				goto IsNum;
			}

			if(((temp2=='+')||(temp2=='-'))&&(repeat==0))  //如果重复出现符号,才将后边的+,-视为正负号
			{
				repeat=1;
				//ch=prog[p++];
			}


			syn=22;

			break;
		case '-':
			temp2=prog[p];
			token[m++]=ch;

			if((temp2>='0')&&(temp2<='9')&&(repeat==1))
			{
				isSignal=1;
				ch=prog[p++]; //读“-”下一个字符
				repeat=0;
				goto IsNum;  //转到数字的识别
			}

			if(((temp2=='+')||(temp2=='-'))&&(repeat==0))  //如果重复出现符号,才将后边的+,-视为正负号
			{
				repeat=1;  //预言会重复
				//ch=prog[p++];  //读下一个字符
			}

			syn=23;

			break; 
			/*
        case '*':   
            syn=24;   
            token[m++]=ch;   
            break;
			*/
		case '*':
			temp2=prog[p];
			token[m++]=ch;

			if(temp2=='+')
			{
				isSignal=2;
				repeat=1;
			}
			else if(temp2=='-')
			{
				isSignal=1;
				repeat=1;
			}
			syn=24;
			break;

        case '/':   
            syn=25;   
            token[m++]=ch;   
            break;    

			/*
        case '(':   
            syn=26;   
            token[m++]=ch;   
            break;
			*/

		case '(':
			temp2=prog[p];
			token[m++]=ch;
		
			if(temp2=='+')
			{
				isSignal=2;
				repeat=1;
			}
			else if(temp2=='-')
			{
				isSignal=1;
				repeat=1;
			}

			syn=26;
			break;
        case ')':   
            syn=27;   
            token[m++]=ch;   
            break;   
        case '{':   
            syn=28;   
            token[m++]=ch;   
            break;   
		case '}':   
            syn=29;   
            token[m++]=ch;   
            break;  
		case ',':   
            syn=30;   
            token[m++]=ch;   
            break;  
		case ';':   
            syn=31;   
            token[m++]=ch;   
            break;  
        case'#':   
            syn=0;   
            token[m++]=ch;   
            break;   
        default:   
            syn=-1;   
    }   
}
  • 大小: 14.2 KB
  • 大小: 17.8 KB
分享到:
评论

相关推荐

    浮点数的DFA识别算法

    设计DFA识别浮点数的关键在于定义状态和转换规则。在DFA中,每个状态代表了处理输入字符串的不同阶段。例如,初始状态可能是等待读取符号或数字,而后续状态可能涉及读取到了小数点或指数。转换规则定义了在读取特定...

    用C语言实现词法分析程序

    本项目是用C语言实现的一个词法分析程序,它能够识别并处理保留字、标识符以及数字等基本元素。 首先,我们来了解一下词法分析的基本概念。词法分析器,又称为扫描器或词法分析器,它的任务是读取源代码,识别出...

    C语言词法分析程序(编译原理)

    本项目聚焦于C语言的词法分析,通过利用C语言的文件读写功能,实现对源代码的解析,生成token值并保存到新文件中,为后续的语法分析和编译工作打下基础。 词法分析,又称扫描,是将源代码文本分解成一系列有意义的...

    编译原理词法分析程序(C语言)

    在这个“编译原理词法分析程序(C语言)”项目中,我们关注的是如何用C语言实现一个词法分析器。 词法分析器的主要任务是从源代码中识别出关键字、标识符、常量、运算符以及分隔符等基本元素。在C语言中,这些元素都...

    词法分析(C语言实现)虚假

    这个阶段的任务是从源代码中识别出关键字、标识符、常量、运算符、分隔符等基本元素,为后续的语法分析和语义分析奠定基础。 C语言是一种静态类型、编译型的编程语言,其词法规则相对固定且明确。例如,C语言的...

    词法分析器c语言实现

    - 实现一个简单的错误处理机制,比如当遇到无法识别的字符时,报告错误并提供源代码位置信息。 - 考虑性能优化,比如使用滑动窗口缓冲区,避免频繁分配和释放内存。 - 使用枚举类型来定义token的类型,并用结构体...

    词法分析及其C语言实现.pdf

    针对C语言的词法分析实现,分析器需要识别的关键元素涵盖了C语言的核心语法元素。这些元素包括但不限于关键字(如`if`、`else`、`for`、`while`等)、标识符(变量名和函数名)、各种类型的常量(如整数、浮点数、...

    词法分析程序(可记录行号、识别注释和小数、文件输出)

    在本项目中,我们关注的是一个特定的词法分析器,它具备记录行号、识别注释和处理小数的能力,并能进行文件输入输出。 首先,让我们详细讨论词法分析器的基本功能。词法分析器通常接收源代码文件作为输入,然后按照...

    Mini C的词法和语法分析程序

    Mini C的词法分析程序会识别并分类这些元素,为后续的语法分析做准备。 词法分析通常采用正则表达式来定义各种标记的模式。例如,数字可能被定义为一串连续的数字字符,而标识符可能是以字母开头,后跟任意数量的...

    C语言词法分析程序

    《C语言词法分析程序详解》 在编程领域,词法分析...通过学习源代码、运行测试用例和分析实验报告,不仅可以掌握LEX工具的使用,还能提升对C语言编译原理的理解,为后续的语法分析、语义分析和代码生成打下坚实基础。

    编译原理词法语法分析器

    运行结果分析部分会展示程序在实际运行时的行为,包括识别的单词、处理的语法结构以及可能遇到的错误情况。这部分分析对于理解和改进分析器至关重要,因为它提供了实际应用中的反馈。 六、收获与体会 完成编译原理...

    C语言词法分析器和C-语言语法分析器毕业设计论文.doc

    在C语言中,语法分析器需要根据C语言的语法规则来分析Token流,例如,识别函数定义、变量声明、表达式等。语法分析器需要使用上下文无关文法(Context-Free Grammar)来描述语言的语法规则。 正则表达式 正则...

    [工学]编译原理--词法分析_语法分析_语义分析C语言.doc

    数字的处理由 `digit()` 完成,它不仅能识别整数,还能处理浮点数和科学计数法。在处理浮点数时,还需要考虑到小数点、指数部分以及正负符号。 总结来说,编译原理是软件开发中的重要组成部分,它涉及了从源代码到...

    基于java的C语言词法分析器

    总结来说,"基于Java的C语言词法分析器"是一个用Java编写的程序,它可以读取C语言源代码,通过识别和分类常数、界符、运算符、关键字和标识符,为后续的语法分析提供基础。这样的工具对于学习编译原理,理解和调试...

    词法分析器 c语言编写

    词法分析器是编译器设计中的重要组成部分,它的主要任务是将源代码文本转换成一个个有意义的符号,称为标记(Token),为后续的语法分析和编译过程提供基础。在C语言中编写词法分析器,需要深入理解C语言特性和编译...

    C语言词法分析程序_解析C语言源程序.zip

    在“C语言词法分析程序_解析C语言源程序.zip”这个压缩包中,包含了实现C语言词法分析的资源。这些文件可能是用于构建一个简单的词法分析器的源代码和辅助文件: 1. `cifafenxi.cpp`: 这是主程序文件,很可能包含了...

    课程设计基于C语言子集的词法分析器

    在这个基于C语言子集的课程设计中,你可能需要编写一个简单的词法分析器,通过正则表达式或其他方法来匹配和识别上述元素。源程序文件将包含实现这些功能的C代码,可能包括自定义的字符串处理函数、状态机模型或正则...

    C语言实现的词法分析器

    在这个案例中,我们关注的是一个用C语言实现的词法分析器,它专门用于解析简单的Pascal语言。 Pascal是一种结构化编程语言,它的语法相对清晰,因此对于初学者和教学来说非常合适。词法分析器的任务是对Pascal源...

    词法分析器、语法分析器、语义分析器一起实现

    在这个C程序中,由于描述提到不支持数字分析,因此可能需要扩展词法分析器以识别整数、浮点数等数值类型。同时,语义分析器需要进一步实现类型系统,以处理C语言中的各种数据类型。 实现这些功能的`main.cpp`文件...

    C语言的程序设计实现方法

    1. 实现词法分析器,能够对给定的程序进行分析,识别出一个个的单词符号,并以二元式的形式(单词种别码,单词符号的属性值)展示出来。例如,程序会读取文件,分析其中的文本,并以特定格式输出,如 "( 1 , 无符号...

Global site tag (gtag.js) - Google Analytics