インタプリタのしくみ(その2)

今日紹介するのは、算術演算インタプリタです。但し、一桁の計算しかできませんが...


-- Production Rules --
<expression> ::= <term> | <term> <addsub> <expression>
<term> ::= <factor> | <factor> <muldiv> <term>
<factor> ::= <number> | <addsub> <number> | '(' <expression> ')'
<addsub> ::= '+' | '-'
<muldiv> ::= '*' | '/'
<number> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

interpreter.c


#include <stdio.h>
#include <stdlib.h>

int flag;
char token;
void gettoken(void);
int expression(void);
int term(void);
int factor(void);
void error(const char[]);

int main(void) {
  int i;
  for (;;) {
    flag = 0;
    gettoken();
    i = expression();
    if (token == '\n') printf("-> %d\n", i);
  }
  return 0;
}

void gettoken(void) {
  char c;
  do {
    c = getchar();
  } while (c == ' ' || c == '\t');
  token = c;
  if (token == '+' || token == '-' || token == '*' || token == '/') {
    if (flag == 0) flag = 1;
    else error("Syntax Error!");
  }
  else flag = 0;
}

int expression(void) {
  int i = term();
  for (;;) {
    switch (token) {
      case '+': gettoken(); i += term(); break;
      case '-': gettoken(); i -= term(); break;
      default: return i;
    }
  }
}

int term(void) {
  int i = factor();
  for (;;) {
    switch (token) {
      case '*': gettoken(); i *= factor(); break;
      case '/': gettoken(); i /= factor(); break;
      default: return i;
    }
  }
}

int factor(void) {
  int i;
  if ('0' <= token && token <= '9') {
    i = token - '0';
    gettoken();
  }
  else if (token == '+') {
    gettoken();
    i = +factor();
  }
  else if (token == '-') {
    gettoken();
    i = -factor();
  }
  else if (token == '(') {
    gettoken();
    i = expression();
    if (token == ')') gettoken();
    else error("Syntax Error!");
  }
  else error("Syntax Error!");
  return i;
}

void error(const char message[]) {
  fprintf(stderr, "%s\n", message);
  exit(1);
}

使用例


(5*(-1+3))-2*(-3*2)
-> 22

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中