c expression Evaluator

前端 未结 7 708
梦如初夏
梦如初夏 2020-12-01 09:50

Okay lets say I have a string such as this in a text file:

((( var1 AND var2 AND var3) OR var4) AND ((var5 OR var6) AND var7))

after parsin

7条回答
  •  天命终不由人
    2020-12-01 10:39

    I tried to write the most compact C code for this bool expression evaluation problem. Here is my final code:

    EDIT: deleted

    Here is the added negation handling:

    EDIT: test code added

    char *eval( char *expr, int *res ){
      enum { LEFT, OP1, MID, OP2, RIGHT } state = LEFT;
      enum { AND, OR } op;
      int mid=0, tmp=0, NEG=0;
    
      for( ; ; expr++, state++, NEG=0 ){
        for( ;; expr++ )
             if( *expr == '!'     ) NEG = !NEG;
        else if( *expr != ' '     ) break;
    
             if( *expr == '0'     ){ tmp  =  NEG; }
        else if( *expr == '1'     ){ tmp  = !NEG; }
        else if( *expr == 'A'     ){ op   = AND; expr+=2; }
        else if( *expr == '&'     ){ op   = AND; expr+=1; }
        else if( *expr == 'O'     ){ op   = OR;  expr+=1; }
        else if( *expr == '|'     ){ op   = OR;  expr+=1; }
        else if( *expr == '('     ){ expr = eval( expr+1, &tmp ); if(NEG) tmp=!tmp; }
        else if( *expr == '\0' ||
                 *expr == ')'     ){ if(state == OP2) *res |= mid; return expr; }
    
             if( state == LEFT               ){ *res  = tmp;               }
        else if( state == MID   && op == OR  ){  mid  = tmp;               }
        else if( state == MID   && op == AND ){ *res &= tmp; state = LEFT; }
        else if( state == OP2   && op == OR  ){ *res |= mid; state = OP1;  }
        else if( state == RIGHT              ){  mid &= tmp; state = MID;  }
      }
    }
    

    Testing:

    #include  
    
    void test( char *expr, int exprval ){
      int result;
      eval( expr, &result );
      printf("expr: '%s' result: %i  %s\n",expr,result,result==exprval?"OK":"FAILED");
    }
    #define TEST(x)   test( #x, x ) 
    
    #define AND       && 
    #define OR        || 
    
    int main(void){
      TEST( ((( 1 AND 0 AND 0) OR 1) AND ((0 OR 1) AND 1)) );
      TEST( !(0 OR (1 AND 0)) OR !1 AND 0 );
    }
    

提交回复
热议问题