学编译原理,一个文法规则的实现

用来描叙化学分子式的书写规则(例如: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;
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值