此语法分析程序的基本词法分析能够识别基本字、标识符、有符号整数、有符号浮点数、运算符和界符)。
语法结构定义
::= { +|-}
::= {*|/}
::=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的原理实现高级语言中浮点数的识别算法
C语言浮点数转字符串
c语言浮点数高精度加法计算
程序说明: 1、不考虑自定义头文件,#include 规定这样开头,尖括号前面只能空一格。 2、标识符长度,否则越界。 3、字符(串)常量,长度不...由于struct中不是指针,比较占用空间,故不可分析太大的程序,容易数组越界。
识别浮点数的有穷自动机识别浮点数的有穷自动机识别浮点数的有穷自动机识别浮点数的有穷自动机
单精度浮点数与十六进制转换_C语言程序__单片机也可用
062 浮点数转换为字符串 C语言
浮点数与十六进制转换,c语言开发 Float 转换成16进制(HEX)
嵌入式C语言浮点数到字符数组转换.pdf
因此,单片机的C程序,在发送或接收外围设各的参数值时,需要解决如何实现浮点数与IEEE格式转换的问题。 2.IEEE浮点数的格式 在计算机中,浮点数的存储均采用4字节的IEEE-754格式。例如,浮点数50.0的IEEE表示形式...
C语言中浮点数精度问题分析.pdf
这是一个简单的以字符形式输入浮点数程序,对于错误进行了很好的处理,本程序主要体现了程序设计中对错误处理方法的思考。
C语言浮点数转换四字节16进制数工具,将浮点数转化为四字节。
C语言浮点数的二进制表示
本文主要介绍c语言中如何获取整数和浮点数的符号位问题,感性趣的朋友可以看看。
浮点数用十六进制表示和十进制表示的相互转换
计算机通讯协议中,会遇到返回信息中,4个整型数字组合代表一个浮点数,本案例是通过位运算将4个整型组合转化成浮点数。
实现一个递归下降语法分析程序,识别用户输入的算术表达式。 二、实验主要内容 1、文法如下: E®TE` E’®+TE’|-TE’|e T®FT` T’®*FT’|/FT’|e F®(E)|i 2、求取各非终结符的First及Follow集合 3、编程...
用C#写的32位浮点数转换成十进制小数程序。输入32位二进制数如01000000000000000000000000000000
学习c过程中,编写的浮点数转成ASCII字符串的函数,包括源代码和测试程序,在gcc-3.4.5-20060117-3和VS2008下均编译通过,并运行结果正确。 如果你在测试的过程中发现输出结果不正确,欢迎跟我联系,以便进一步改进...