用来描叙化学分子式的书写规则(例如:AL2(CO3)3 ,Cu(OH)2)
a-->mn/(c)
mn 为一个大写字母和一个小写字母
c-->b/bc
c为一个分子式
b-->a/an
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 300
#define GMLEN 10
struct elem{
char name[2];
double v;
}nTbl[MAXN];
char *pos;
char cmstr[GMLEN];
FILE *fp;
int c;
double FACTOR();
double ATOM() //处理文法 a
{
int i=0;
char W[3];
double num;
int j;
while((c=*pos++)==' '||c=='/t');
if(c=='/n')
return 0.0;
if(c>='A'&&c<='Z')
{
W[i]=c;
c=*pos++;
if(c>='a'&&c<='z')
W[++i]=c;
W[i]='/0';
for(j=0;nTbl[j].v>0.0;j++)
if(strcmp(W,nTbl[j].name)==0)
return nTbl[j].v;
printf("元素表中没有所输入的元素!/n");
return 0.0;
}
else if(c=='(')
{
if((num=FACTOR())<0.0)
return -1.0;
if((c=*pos++)!=')')
printf("括号不必配!/n");
return num;
}
printf("分子式中存在非法字符!/n");
return -1.0;
}
double MATOM() //处理文法 b
{
double num;
int n=1;
if((num=ATOM())<0.0)
return -1.0;
c=*pos++;
if(c>='0'&&c<='9')
{
n=0;
while(c>='0'&&c<='9')
{
n=n*10+c-'0';
c=*pos++;
}
pos--;
return num*n;
}
}
double FACTOR() //处理文法c
{
double num,d;
if((num=MATOM())<0.0)
{
return -1.0;
}
while(*pos>='A'&&*pos<='Z'||*pos=='(')
{
if((d=MATOM())<0.0)
return -1.0;
num+=d;
}
return num;
}
int main(int argc, char *argv[])
{
int i=0;
double num;
char fname[]="atom.dat";
if((fp=fopen(fname,"r"))==NULL)
{
printf("打开文件%s失败!/n",fname);
return 0;
}
while(i<MAXN&&fscanf(fp,"%s%f",nTbl[i].name,&nTbl[i].v)==2)
i++;
fclose(fp);nTbl[i].v=-1.0;
while(1)
{
printf("输入分子式!(空一下)/n");
gets(cmstr);
pos=cmstr;
if(cmstr[0]=='/0')
break;
if((num=FACTOR())>0.0)
{
if(*pos!='/0')
printf("分子式不完整!/n");
else
printf("分子式的分子量为%f:/n",num);
}
}
return 0;
}