//
// 四則演算用の再帰降下構文解析器
//

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

char* input;
int point;

double number( void );
double factor( void );
double term( void );
double expression( void );


// 「数」を処理する(指数表現には未対応)
double number( void ){ 
  double result=0.0;
  double flag = 1.0; //整数部か小数部か
  while( ('0'<=input[point] && input[point]<='9') || input[point]=='.' ){
    if( input[point]=='.' ){ // 小数点を見つけた
      flag = 0.1;
      point++;
    } else { // 数字
      if( flag>=1.0 ){ // 整数部
	result = 10*result + input[point]-'0';
      } else {
	result = result + (input[point]-'0')*flag;
	flag /= 10.0;
      }
      point++;
    }
  }
  return( result );
}


// 「要素」を処理する
double factor( void ){
  double result;
  if( input[point]=='(' ){
    point++;
    result = expression();
    if( input[point]==')' ){
      point++;
      return result;
    } else {
      printf( "Error\n" );
      exit(1);
    }
  } else if( '0'<=input[point] && input[point]<='9' ){
    return( number() );
  } else {
    // 変数名、関数名などの処理はここで行う
    printf( "変数名、関数名など\n" );
    return(0.0);
  }
}


// 「項」を処理する
double term( void ){
  double result;
  double F1 = factor(); // 要素1を処理
  double F2;
  char flag; // 乗算か除算かのフラグ
  result = F1;
  while( input[point]=='*' || input[point]=='/' ){
    switch( input[point] ){
    case '*': flag = 1;
      point++;
      break;
    case '/': flag = 0;
      point++;
      break;
    }
    F2 = term();  // 項2を処理
    if( flag == 1 ){
      result = result * F2;
    } else {
      result = result / F2;
    }
  }
  return( result );
}  


// 「式」を処理する
double expression( void ){
  double result;
  double T1 = 0.0;
  double T2;
  char flag;			// 加算か減算かのフラグ

  if( input[point]!='+' && input[point]!='-' ){ // 符号で始まらない？
    T1 = term();				// 項1を処理
  }
  result = T1;
  while( input[point]=='+' || input[point]=='-' ){
    switch( input[point] ){
    case '+': flag = 1;
      point++;
      break;
    case '-': flag = 0;
      point++;
      break;
    }
    T2 = term();		// 項2を処理
    if( flag == 1 ){
      result = result + T2;
    } else {
      result = result - T2;
    }
  }
  return( result );
}  


// メイン
int main( int argc, char* argv[] ){
    input = argv[1];
    point = 0;
    if( argc==1 ){ 
      printf( "数式を引数として入れてください\n" );
      exit(1);
    }

    double result = expression(); // 処理の本体

    printf( "Result = %f\n", result );

}
