会员登录 用户名: 密码: 登录 新会员注册 [找回密码]
当前位置:编程论坛 >> C/S程序开发专区 >> 汇编语言专区 >> 关于数学表达式的语法分析
首页
中资源
  发表一个新主题  发表一个新投票  回复主题 您是本帖的第 304 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
 * 贴子主题:关于数学表达式的语法分析 悬赏分200 [已结帖] 报告本帖给版主  显示可打印的版本  把本贴打包邮递  把本贴加入论坛收藏夹  发送本页面给朋友  把本贴加入IE收藏夹 
 718225250 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:433
  专家分:228
  提问帖:4/4
  回答帖:31
  总帖数:44
  经验值:112
  注 册:2008-9-7
给718225250发送一个短消息 把718225250加入好友 查看718225250的个人资料 搜索718225250在汇编语言专区的所有贴子  引用回复这个贴子 回复这个贴子楼主

发贴心情 关于数学表达式的语法分析

我正在学编译原理,如题,
是关于简单的数学表达式的语法分析和代码生成的问题。
文法G[A]:
E  ->  I | E+E | E*E | E-E | E/E | (E)
I    -> 0|1|2|3|4|5|6|7|8|9
算符优先关系参照数学上的。

要求输入表达式,输出四元式。要有过程。

我的算法和代码(C语言)如下://测试代码时,请注意表达式的最后要有#号

#include <string.h>
#include <stdio.h>
#include <math.h>
char a[20], optr[10]; /** 数组a模拟栈,最初存放输入表达式,optr存放运算符*/
int opnd[10];  /** 存储参与运算的从字符转换为int的一位数*/
int i,j,k;  /** 分别对应数组a;optr;opnd的临时下标*/
char s;   /** s为从数组a取出的一个字符*/
int x1,x2,x3;  /** 参与运算的两个数和运算结果*/
char op;  /** 运算符*/

int operand(s)  /** 判断是否为数字字符*/
{
 if((s>=48)&&(s<=57)) return(1);
 else return(0);
}

int f(s)/**优先函数 入栈函数*/
 {
 switch(s){
      case'+': return(4);
      case'-': return(4);
      case'*': return(6);
      case'/': return(6);
      case'(': return(2);
      case')': return(6);
      case'#': return(0);
      defeult: printf("error!\n");
       }
}

int g(s)/**优先函数 比较函数*/
{
  switch(s)
  {
     case'+': return(3);
     case'-': return(3);
     case'*': return(5);
     case'/': return(5);
     case'(': return(7);
     case')': return(2);
     case'#': return(0);
     defeult: printf("error!\n");
       }
}

void get()   /**在数组a中取出一个字符*/
{
 s=a[i];
 i++;
}


main()
{

  printf("please input your expression(include a '#' in the end of expression):\n");
     i=0;
     do{
         i=i+1;
         scanf("%c",&a[i]);
        }while(a[i]!='#');
    
 i=1;j=k=1;  /** 初始化*/
    optr[j]='#';
    get();
    while( !((optr[j]=='#')&&(s=='#')) )/**不满足结束条件时*/
    {
       if (operand(s))  /** 若为数字字符,存入opnd*/
        {
          opnd[k]=s-48;
          k=k+1;
          get();
         }
       else if(f(optr[j]) > g(s))  /** 运算符出栈*/  
       {
         op=optr[j];
   j=j-1;
         x1 = opnd[k-1];
         x2 = opnd[k-2];
   k=k-2;
       switch(op)
       {
        case'+':x3=x1+x2;break;
        case'*':x3=x1*x2;break;
        case'-':x3=x1-x2;break;
        case'/':x3=x1/x2;break;
        }
        opnd[k]=x3;
        k++;
        printf("(%c,%d,%d,%d)\n",op,x1,x2,x3);
       } 
       else if(f(optr[j]) < g(s)) /** 运算符入栈*/ 
       {
         j=j+1;
         optr[j]=s;
         get();
        }
      else if(f(optr[j]) == g(s))
       {
          if(optr[j] == '(' || optr[j] == ')') /** 归约一对括号*/
          {
          j=j-1;
          get();
          }
          else printf("error!!!\n");
         }
       else printf("error!!!\n");
      }

    }
    

当输入简单时,结果能对,但表达稍长就错了,
我输入了 2*5-(3*4-5)#  测试,结果错了
输出如下:
(*,5,2,10)
(*,4,3,12)
(-,5,12,-7)
(-,-7,10,-17)

到底哪里错了,还有我的这个题只要求运算一位整数,但要支持多位又该怎么办?


修改时注,错误已经改正(6楼),回帖者帮我看看怎么扩展支持多位数的功能。


[此贴子已经被作者于2008-11-21 19:28:49编辑过]

我不想把电脑当做游戏机

发帖:2008-11-21 14:36:00
  鲜花(0)  鸡蛋(0)
 甘道夫 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:1867
  专家分:1177
  提问帖:0/0
  回答帖:90
  总帖数:95
  经验值:153
  注 册:2008-11-14
给甘道夫发送一个短消息 把甘道夫加入好友 查看甘道夫的个人资料 搜索甘道夫在汇编语言专区的所有贴子 引用回复这个贴子 回复这个贴子2

发贴心情 

好麻烦,上班中,有时间研究下。
发帖:2008-11-21 14:43:00
 zhangyizhe 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:555
  专家分:365
  提问帖:5/5
  回答帖:43
  总帖数:59
  经验值:130
  注 册:2008-10-9
给zhangyizhe发送一个短消息 把zhangyizhe加入好友 查看zhangyizhe的个人资料 搜索zhangyizhe在汇编语言专区的所有贴子 引用回复这个贴子 回复这个贴子3

发贴心情 

“我输入了 2*5-(3*4-5)#  测试,结果错了
输出如下:
(*,5,2,10)
(*,4,3,12)
(-,5,12,-7)
(-,-7,10,-17)”
这个式子正确的应该是什么?我没有学过编译,你上面的程序也不能运行,我改了一下;
#include <string.h>
#include <stdio.h>
#include <math.h>
char a[20], optr[10]; /** 数组a模拟栈,最初存放输入表达式,optr存放运算符*/
int opnd[10];  /** 存储参与运算的从字符转换为int的一位数*/
int i,j,k;  /** 分别对应数组a;optr;opnd的临时下标*/
char s;   /** s为从数组a取出的一个字符*/
int x1,x2,x3;  /** 参与运算的两个数和运算结果*/
char op;  /** 运算符*/

int operand(char s)  /** 判断是否为数字字符*/
{
 if((s>=48)&&(s<=57)) return 1;
 else return 0;
}

int f(char s)/**优先函数 入栈函数*/
 {int  k;
 switch(s){
      case'+': k=4;break;
      case'-': k=4;break;
      case'*': k=6;break;
      case'/': k=6;break;
      case'(': k=2;break;
      case')': k=6;break;
      case'#': k=0;break;
      default: printf("error!\n");break;
       }
   return k;
}

int g(char s)/**优先函数 比较函数*/
{char k;
  switch(s)
  {
     case'+': k=3;break;
     case'-': k=3;break;
     case'*': k=5;break;
     case'/': k=5;break;
     case'(': k=7;break;
     case')': k=2;break;
     case'#': k=0;break;
     default: printf("error!\n");break;
       }
  return k;
}

void get()   /**在数组a中取出一个字符*/
{
 s=a[i];
 i++;
}


void main()
{

  printf("please input your expression(include a '#' in the end of expression):\n");
     i=0;
     do{
         i=i+1;
         scanf("%c",&a[i]);
        }while(a[i]!='#');
    
 i=1;j=k=1;  /** 初始化*/
    s=optr[j]='#';
    get();
    while( !((optr[j]=='#')&&(s=='#')) )/**不满足结束条件时*/
    {
       if (operand(s))  /** 若为数字字符,存入opnd*/
        {
          opnd[k]=s-48;
          k=k+1;
          get();
         }
       if(f(optr[j]) > g(s))  /** 运算符出栈*/  
       {
         op=optr[j];
          j=j-1;
         x1 = opnd[k-1];
         x2 = opnd[k-2];
         k=k-2;
       switch(op)
       {
        case'+':x3=x1+x2;break;
        case'*':x3=x1*x2;break;
        case'-':x3=x1-x2;break;
        case'/':x3=x1/x2;break;
       }
        opnd[k]=x3;
        k++;
        printf("(%c,%d,%d,%d)\n",op,x1,x2,x3);
       } 
       else if(f(optr[j]) < g(s)) /** 运算符入栈*/ 
       {
         j=j+1;
         optr[j]=s;
         get();
       }
      else if(f(optr[j]) == g(s))
       {
          if(optr[j] == '(' || optr[j] == ')') /** 归约一对括号*/
          {
          j=j-1;
          get();
          }
          else printf("error!!!\n");
       }
       else printf("error!!!\n");
 }

    

发帖:2008-11-21 16:29:00
 mathprice 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:347
  专家分:68
  提问帖:0/0
  回答帖:8
  总帖数:35
  经验值:98
  注 册:2008-11-5
给mathprice发送一个短消息 把mathprice加入好友 查看mathprice的个人资料 搜索mathprice在汇编语言专区的所有贴子 引用回复这个贴子 回复这个贴子4

发贴心情 

代码不错,值得研究一下。由于时间关系先收藏了

做事最忌虎头蛇尾~
坚持!坚持!坚持到句号出现~~~
拒绝妥协!!!!!!

发帖:2008-11-21 16:59:00
 718225250 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:433
  专家分:228
  提问帖:4/4
  回答帖:31
  总帖数:44
  经验值:112
  注 册:2008-9-7
给718225250发送一个短消息 把718225250加入好友 查看718225250的个人资料 搜索718225250在汇编语言专区的所有贴子  引用回复这个贴子 回复这个贴子5

发贴心情 

能运行的啊,请问3楼你改了什么地方?

我不想把电脑当做游戏机

发帖:2008-11-21 18:52:00
 718225250 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:433
  专家分:228
  提问帖:4/4
  回答帖:31
  总帖数:44
  经验值:112
  注 册:2008-9-7
给718225250发送一个短消息 把718225250加入好友 查看718225250的个人资料 搜索718225250在汇编语言专区的所有贴子  引用回复这个贴子 回复这个贴子6

发贴心情 

对不起各位,我自己发现了错误(在78,79行),原来
         x1 = opnd[k-1];
         x2 = opnd[k-2];
这写错了,分析错误。应改为
         x1 = opnd[k-2];
         x2 = opnd[k-1];
x1优先于x2,本来在原帖上改了一下,后来发现这样太不礼貌,对不起回帖的朋友,在这说明一下

我不想把电脑当做游戏机

发帖:2008-11-21 19:19:00
 718225250 帅哥哟,离线,有人找我吗?
  
  
  等 级:初出江湖
  积 分:433
  专家分:228
  提问帖:4/4
  回答帖:31
  总帖数:44
  经验值:112
  注 册:2008-9-7
给718225250发送一个短消息 把718225250加入好友 查看718225250的个人资料 搜索718225250在汇编语言专区的所有贴子  引用回复这个贴子 回复这个贴子7

发贴心情 

是否应该用一个栈来代替数组a,不过这样要改的地方就多了,谁有这方面的源程序,在这谢谢了

我不想把电脑当做游戏机

发帖:2008-11-21 19:31:00
 我挂科了 帅哥哟,离线,有人找我吗?狮子座1986-8-4
  
  
  头 衔:西南科技大学
  等 级:版主
  威望:5
  积 分:3624
  专家分:2889
  提问帖:32/32
  回答帖:347
  总帖数:985
  经验值:1501
  注 册:2007-4-14
给我挂科了发送一个短消息 把我挂科了加入好友 查看我挂科了的个人资料 搜索我挂科了在汇编语言专区的所有贴子 引用回复这个贴子 回复这个贴子8

发贴心情 

为什么把代码发到汇编版来了呢??

把我埋在沙子里,我会生根发芽...

欢迎光临我的E盘 http://shary.ys168.com

发帖:2008-11-29 14:33:00

本主题贴数8,分页:[返回帖子列表] [上一页] [1] [下一页]

此主题已经结帖:

mathprice-50,zhangyizhe-50,甘道夫-50,我挂科了-50

 *快速回复:关于数学表达式的语法分析  [ 回帖是一种美德 :) ]
会员账号 用户名    还没注册?    密码    忘记密码?
内容
  • HTML标签: 不可用
  • UBB标签: 可用
  • 贴图标签: 可用
  • 多媒体标签:可用
  • 表情字符转换:可用
  • 上传图片:不可用
  • 最多15KB
  • 点击表情图即可在帖子中加入相应的表情
                                
    邮件回复 显示签名   [Ctrl+Enter直接提交贴子]

    管理选项锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告