極小的運算式編譯器

執行結果

D:\ccc101\CL>gcc ecompiler.c -o ecompiler

D:\ccc101\CL>ecompiler 3+5*8+(4-3*6)
=== EBNF Grammar =====
E=T ([+-] T)*
T=F ([*/] F)*
F=N | '(' E ')'
==== parse:3+5*8+(4-3*6) ========
t0=3
t1=5
t2=8
t3=t1*t2
t4=t0+t3
t5=4
t6=3
t7=6
t8=t6*t7
t9=t5-t8
t10=t4+t9

程式:ecompiler.c

#include <stdio.h>
#include <assert.h>

int main(int argc, char * argv[]) {
    printf("=== EBNF Grammar =====\n");
    printf("E=T ([+-] T)*\n");
    printf("T=F ([*/] F)*\n");
    printf("F=N | '(' E ')'\n");
    printf("==== parse:%s ========\n", argv[1]);
    parse(argv[1]);
}

char stack[100];
int top = 0;

int push(char c) {
  stack[top++] = c;
}

char pop(char c) {
  char ctop = stack[--top];
  assert(ctop==c);
  return ctop;
}

void printStack() {
  int i;
  for (i=0; i<top; i++)
    printf("%c", stack[i]);
  printf("\n");
}

int tokenIdx = 0;
char *tokens;

char ch() {
  char c = tokens[tokenIdx];
  return c;
}

char next() {
  char c = ch();
  push(c);
//  printStack();
  pop(c);
  tokenIdx++;
  return c;
}

int isNext(char *set) {
  return (ch()!='\0' && strchr(set, ch())!=NULL);
}

int parse(char *str) {
     tokens = str;
     E();
}

int tempIdx = 0;

int nextTemp() {
    return tempIdx++;
}

int E() {
    push('E');
    int t1 = T();
    while (isNext("+-")) {
          char op=next();
          int t2 = T();
          int t = nextTemp();
          printf("t%d=t%d%ct%d\n", t, t1, op, t2);
          t1 = t;
    }
    pop('E');
    return t1;
}

int T() {
    push('T');
    int f1 = F();
    while (isNext("*/")) {
          char op=next();
          int f2 = F();
          int f = nextTemp();
          printf("t%d=t%d%ct%d\n", f, f1, op, f2);
          f1 = f;
    }
    pop('T');
    return f1;
}

int F() {
    int f;
    push('F');
    if (ch()=='(') {
      next();
      f = E();
      assert(ch()==')');
      next();
    } else {
      assert(ch()>='0' && ch()<='9');
      f = nextTemp();
      char c=next();
      printf("t%d=%c\n", f, c);
    }
    pop('F');
    return f; 
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License