此词法分析程序能够识别基本字、标识符、有符号整数、有符号浮点数、运算符和界符)。
仅作交流,希望能抛砖引玉,获得更为简洁有效的词法分析程序。
输入:所给文法的源程序字符串。(字符串以“#”号结束)
输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。
例如:控制台输入beginx:=9: if x>9 then x:=2*x+1/3;end #,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
例如:控制台输入zzz123+-1234.56e-123+1+-2#,经过词法分析后输出:
(10,zzz123)(13,+)(11,-1.23456e-120)(11,1)(13,+)(11,-2)(0,#)
实现截图:

源代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
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[6]={"begin","if","then","while","do","end"};
void main()
{
p=0;
count=0;
isDecimal=0;
index=0;
repeat=0;
printf("\n Please input string:\n");
do{
ch=getchar();
prog[p++]=ch;
}while(ch!='#'); //输入以#号键结束
p=0;
do{
scanner(); //扫描,单词
switch(syn)
{
case 11:
if(isDecimal==0)
{
//加了1个强制类型转换
printf("(%2d,%8d)\n",syn,(int)sum);
break;
}
else if(isExp==1)
{
printf("(%2d,%10.5e)\n",syn,sum);
isExp=0;
isDecimal=0;
break;
}
else if(isDecimal==1)
{
printf("(%2d,%8.4f)\n",syn,sum);
isDecimal=0;
break;
}
case -1:
printf("input error\n");
break;
default:
printf("(%2d,%8s)\n",syn,token);
}
}while(syn!=0);
getch();
}
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<6;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=11;
}
else switch(ch)
{
case '<':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21; //<>对应21
token[m++]=ch;
}
else if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
p--;
}
break;
case '>':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
p--;
}
break;
case ':':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
p--;
}
break;
case '+':
temp2=prog[p];
token[m++]=ch;
if((temp2>='0')&&(temp2<='9')&&(repeat==1))
{
isSignal=2; //isSignal正数
ch=prog[p++];
repeat=0;
goto IsNum;
}
if(((temp2=='+')||(temp2=='-'))&&(repeat==0)) //如果重复出现符号,才将后边的+,-视为正负号
{
repeat=1;
//ch=prog[p++];
}
syn=13;
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=14;
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=16;
token[m++]=ch;
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=27;
break;
case ')':
syn=28;
token[m++]=ch;
break;
case'#':
syn=0;
token[m++]=ch;
break;
default:
syn=-1;
}
}
本文介绍了一款词法分析程序的设计与实现,该程序能识别基本字、标识符、整数、浮点数等,并输出相应的种别码及词法单元。通过具体示例展示了如何进行词法分析。
1542

被折叠的 条评论
为什么被折叠?



