/* E = T | T [+|-] E T = P | P [*|/] T P = NUMBER | ( E ) */ long E(void), T(void), P(void); extern _gp; asm("la $28,_gp"); asm("j main"); int nxt_ch; int sig_exit=0; #define to_num(x) (x-'0') int is_num(int ch) { return (ch>='0')&&(ch<='9'); } int is_white(int ch) { return (ch==' ')||(ch=='\t'); } void skip_white(void) { while(is_white(nxt_ch)) nxt_ch = getchar(); } long P(void) { long v; int s; nxt_ch = getchar(); skip_white(); if(nxt_ch=='-'){ s = 1; nxt_ch = getchar(); } else if(nxt_ch=='q'){ sig_exit = 1; } else s = 0; skip_white(); if(is_num(nxt_ch)){ v = to_num(nxt_ch); while(is_num(nxt_ch=getchar())) v = v*10 + to_num(nxt_ch); } else if(nxt_ch=='('){ v = E(); skip_white(); if(nxt_ch!=')') printf("missing )!\n"); nxt_ch = getchar(); } else{ return 0; } return (s)? -v : v; } long T(void) { long v1,v2; int op; v1 = P(); skip_white(); op = nxt_ch; if((op!='*')&&(op!='/')){ return v1; } v2 = T(); return (op=='*')? v1*v2 : v1/v2; } long E(void) { long v1,v2; int op,op2; v1 = T(); skip_white(); op = nxt_ch; if((op!='+')&&(op!='-')){ return v1; } loop: v2 = T(); skip_white(); op2 = nxt_ch; if((op2!='+')&&(op2!='-')){ return (op=='+')? v1+v2 : v1-v2; } if(op=='+') v1 += v2; else v1 -= v2; op = op2; goto loop; } main() { sig_exit = 0; while(1){ printf("->"); printf("\r\n= %d\n", E()); if(sig_exit) break; } return 0; }