| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 557 人关注过本帖
标题:这个怎么实现四则运算?
取消只看楼主 加入收藏
cilubutong
Rank: 1
等 级:新手上路
帖 子:119
专家分:2
注 册:2007-5-22
结帖率:75%
收藏
已结贴  问题点数:10 回复次数:0 
这个怎么实现四则运算?
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 256
#define SHIFT(NUM) memcpy(&(stack[top].token),&curtoken,sizeof(TokenType));\
                   stack[++top].state=NUM;\
                   getnexttoken(word);\
                   break;
#define ERRORPROCESS  fprintf(out,"Error line:%d\n",lineno);\
                      return;

typedef enum {NONE=-3, FEOF, ERROR,
              /*词法符号*/
              INTC,FLOATC,OPADD,OPSUB,OPMUL,OPDIV,LPAREN,RPAREN,LINE,ASSIGN,             
              /*文法的非终极符*/
              S,E,T,P
} LexType;

static LexType lexstateflag[]={ERROR,INTC,FLOATC,ERROR,ERROR,ERROR,FLOATC,OPADD,
                               OPSUB,OPMUL,OPDIV,LPAREN,RPAREN,LINE,ASSIGN};

static FILE *in;
static FILE *out;
static char lexcurch=' ';

static char lexstack[BUFSIZE];
static int lexstacktop=-1;

static char lextryword[BUFSIZE];
static LexType lextryflag[BUFSIZE];
static int lexindex;

/*实现语法分析时使用的变量*/
typedef struct{
    LexType type;
    enum {INT,FLOAT} valuetype;
    union{
        int intv;
        float floatv;
    } value;
} TokenType;
static TokenType curtoken,buftoken={NONE};
static int lineno=1;

LexType lex(char *word)
{ int state;

  lexindex=0;
  state=0;
  while(lexcurch==' '||lexcurch=='\t')
     if (lexstacktop==-1)
        lexcurch=fgetc(in);
     else
        lexcurch=lexstack[lexstacktop--];
  while (1)
  {
    if (lexindex) lextryflag[lexindex-1]=lexstateflag[state];
    switch (state){
        case 0:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=1;break;
                 case '.':
                         state=3;break;
                 case '+':
                         state=7;break;
                 case '-':
                         state=8;break;
                 case '*':
                         state=9;break;
                 case '/':
                         state=10;break;
                 case '(':
                         state=11;break;
                 case ')':
                         state=12;break;
                 case '\n':
                         state=13;break;
                 case '=':
                         state=14;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 1:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=1;break;
                 case '.':
                         state=2;break;
                 case 'E': case 'e':
                         state=4;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 2:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=2;break;
                 case 'E': case 'e':
                         state=4;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 3:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=2;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 4:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=6;break;
                 case '+': case '-':
                         state=5;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 5:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=6;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 6:
             switch (lexcurch){
                 case '0': case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
                         state=6;break;
                 default:
                         state=-1;break;
             } ;
             break;
        case 7:
             state=-1;break;
        case 8:
             state=-1;break;
        case 9:
             state=-1;break;
        case 10:
             state=-1;break;
        case 11:
             state=-1;break;
        case 12:
             state=-1;break;
        case 13:
             state=-1;break;
        case 14:
             state=-1;break;
        default:
             state=-1;break;
    }
    if (state==-1)
        break;
    lextryword[lexindex++]=lexcurch;/*maybe overflow*/
    if (lexstacktop==-1)
        lexcurch=fgetc(in);
    else
        lexcurch=lexstack[lexstacktop--];
  }
  if (lexindex==0&&lexcurch==EOF)
      return FEOF;
  lextryword[lexindex]=lexcurch;
  lextryflag[lexindex]=ERROR;
  while (lexindex>0 && lextryflag[lexindex]==ERROR)
      lexstack[++lexstacktop]=lextryword[lexindex--];/*maybe overflow*/
  lextryword[lexindex+1]=0;
  strcpy(word,lextryword);
  if (lexstacktop==-1)
      lexcurch=fgetc(in);
  else
      lexcurch=lexstack[lexstacktop--];
  return lextryflag[lexindex];
}

void getnexttoken(char *word)
{
   if (buftoken.type==NONE)
      do {
         curtoken.type=lex(word);
         if (curtoken.type==INTC){
             curtoken.valuetype=INT;
             curtoken.value.intv=atoi(word);
         }
         if (curtoken.type==FLOATC){
             curtoken.valuetype=FLOAT;
             curtoken.value.floatv=atof(word);
         }
         if (curtoken.type==ERROR)
            fprintf(out,"Error line:%d %s\n",lineno,word);
         if (curtoken.type==LINE)
            lineno++;
      }while(curtoken.type==ERROR||curtoken.type==LINE);
   else {
      memcpy(&curtoken,&buftoken,sizeof(TokenType));
      buftoken.type=NONE;
   }
}

void parse(void)
{
   struct{
       int state;
       TokenType token;
   } stack[BUFSIZE];
   int top=-1;
   char word[80];
   float ta,tb;

   stack[++top].state=0;
   getnexttoken(word);
   while (1){
      switch(stack[top].state){
          case 0:
              switch(curtoken.type) {
                  case E:       SHIFT(1)
                  case T:       SHIFT(2)
                  case P:       SHIFT(3)
                  case INTC:    SHIFT(4)
                  case FLOATC:  SHIFT(5)
                  case LPAREN:  SHIFT(6)
                  default:      ERRORPROCESS
              }
              break;
          case 1:
              switch(curtoken.type) {
                  case ASSIGN:  /* R1 */
                                memcpy(&buftoken,&curtoken,sizeof(TokenType));
                                memcpy(&curtoken,&(stack[top-1].token),sizeof(TokenType));
                                curtoken.type=S;
                                top=top-1;
                                /* ACCEPT */
                                if (curtoken.valuetype==INT)
                                    fprintf(out, "%d\n",curtoken.value.intv);
                                if (curtoken.valuetype==FLOAT)
                                    fprintf(out, "%f\n",curtoken.value.floatv);
                                return;
                  case OPADD:   SHIFT(7)
                  case OPSUB:   SHIFT(8)
                  default:      ERRORPROCESS
              }
              break;

          /* need code here */

          case 15:
              switch(curtoken.type) {
                  case ASSIGN:
                  case OPADD:
                  case OPSUB:
                  case RPAREN:
                  case OPMUL:
                  case OPDIV:   /* R7 */
                                memcpy(&buftoken,&curtoken,sizeof(TokenType));
                                curtoken.type=T;
                                if ( stack[top-3].token.valuetype==INT &&
                                     stack[top-1].token.valuetype==INT &&
                                     (stack[top-3].token.value.intv %
                                        stack[top-1].token.value.intv==0) ){
                                    curtoken.valuetype=INT;
                                    curtoken.value.intv=stack[top-3].token.value.intv /
                                                        stack[top-1].token.value.intv;
                                }else{
                                    curtoken.valuetype=FLOAT;
                                    if (stack[top-3].token.valuetype==INT)
                                         ta=(float)(stack[top-3].token.value.intv);
                                    else ta=stack[top-3].token.value.floatv;
                                    if (stack[top-1].token.valuetype==INT)
                                         tb=(float)(stack[top-1].token.value.intv);
                                    else tb=stack[top-1].token.value.floatv;
                                    curtoken.value.floatv=ta/tb;
                                }
                                top=top-3;
                                break;
                  default:      ERRORPROCESS
              }
              break;
          case 16:
              switch(curtoken.type) {
                  case ASSIGN:
                  case OPADD:
                  case OPSUB:
                  case RPAREN:
                  case OPMUL:
                  case OPDIV:   /* R10 */
                                memcpy(&buftoken,&curtoken,sizeof(TokenType));
                                memcpy(&curtoken,&(stack[top-2].token),sizeof(TokenType));
                                curtoken.type=P;
                                top=top-3;
                                break;
                  default:      ERRORPROCESS
              }
              break;
          default:
              ERRORPROCESS
      }
   }
}

int main()
{

   in=stdin;
   out=stdout;

   parse();

   getchar();getchar();
   return 0;
}
搜索更多相关主题的帖子: 运算 
2010-07-09 20:18
快速回复:这个怎么实现四则运算?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.034406 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved