計算語言學 -- 使用 C 編譯運算式 (字元版)

編譯器設計

編譯器簡介

高階語言

語法理論

剖析器

語意理論

符號表

直譯器

型態系統

中間碼

目標語言

最佳化

錯誤處理

進階議題

原始碼下載

程式實作

C 語言

案例研究

JavaScript

V8

Lua

Oberon

NeoPascal

pcc

tcc

gcc

C--

Lex

YACC

AntLR

LLVM

CLang

訊息

相關網站

參考文獻

最新修改

簡體版

English

執行結果

NQU-192-168-60-101:c csienqu$ gcc -std=c89 exp.c -o exp
NQU-192-168-60-101:c csienqu$ ./exp 3+5*8-9/6
=== EBNF Grammar =====
E=T ([+-] T)*
T=F ([*/] F)*
F=N | '(' E ')'
==== parse:3+5*8-9/6 ========
t0=3
t1=5
t2=8
t3=t1*t2
t4=t0+t3
t5=9
t6=6
t7=t5/t6
t8=t4-t7

程式:expc.c

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

int tokenIdx = 0;
char *tokens;

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

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;

void 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");
}

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 tempIdx = 0;

int nextTemp() {
    return tempIdx++;
}

// E=T ([+-] T)*
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;
}

// T=F ([*/] F)*
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;
}

// F=N | '(' E ')'
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; 
}

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License