这个怎么实现四则运算?
程序代码:
#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; }