`
ErinToJerry
  • 浏览: 55562 次
  • 性别: 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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics