ichirin2501's diary

いっちりーん。

式の解析

数日前に、式の構文解析でも書いてみようかなーと、書き殴ったコード。
割り算は対応してない。
どうしてこうなった、ってぐらい酷い出来になっている。

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

#define multi(x,y) ((x)*(y))
#define add(x,y)   ((x)+(y))
#define sum(x,y)   ((x)-(y))
#define inverse(x) (-(x))

int parse(char *s,char *ind,int f)
{
  char sign;
  char *p;
  int flag=0,x;
  for(p=s,x=0;p!=ind;p++){
    if(*p=='(')x++;
    if(*p==')')x--;
    if( x==0 && (*p=='+' || *p=='-') && p!=s && !(*(p-1)=='*'||*(p-1)=='/'))sign=*p,flag=1;
    if(x==0 && flag)break;
  }
  if(p!=ind){
    if(f){
      if( sign=='+')
        return add(parse(s,p,f),parse(p+1,ind,f));
      else{
        if(*(p+1)=='(')
          return sum(parse(s,p,f),parse(p+1,ind,f));
        else
          return sum(parse(s,p,f),parse(p+1,ind,!f));
      }
    }else{
      if( sign=='+'){
        return sum(parse(s,p,!f),parse(p+1,ind,!f));
      }
      else{
        if(*(p+1)=='(')
          return add(parse(s,p,!f),parse(p+1,ind,!f));
        else
          return add(parse(s,p,f),parse(p+1,ind,f));
      }
    }
  }else{
    flag=0;
    for(p=s,x=0;p!=ind;p++){
      if(*p=='(')x++;
      if(*p==')')x--;
      if( x==0 && (*p=='*' || *p=='/') )sign=*p,flag=1;
      if(x==0 && flag)break;
    }
    if(p!=ind){
      if(sign=='*') return multi(parse(s,p,f),parse(p+1,ind,f));
      
    }else{
      if( isdigit(*s) ){
        return atoi(s);
      }else if( *s=='(' ){
        return parse(s+1,ind,f);
      }else if( *s=='-' ){
        return inverse(parse(s+1,ind,f));
      }else{
        printf("input miss!!!!!\n"); exit(1);
      }
    }
  }
}

int main()
{
  char s[1<<10];
  while(gets(s))
    printf("%d\n",parse(s,&s[strlen(s)],1));
  return 0;
}


>1+2+3+4+(5-5*(-1))
>20
>(-2*(1+2+3-1*-1)-5)
>-19
>-1-2-3-4-(-1-2-3-4)
>0
>(((1-1-1)-(-1)))
>0

ここ掘れわんわんで蟲が大量に沸くはずです。
G氏は言いました。「これは…蟲の仕業です」と。
perlだと、eval先生を呼べば評価してくれるのにw。