Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1426212
  • 博文数量: 122
  • 博客积分: 340
  • 博客等级: 一等列兵
  • 技术积分: 2967
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-01 11:50
个人简介

说点什么呢

文章分类

全部博文(122)

文章存档

2018年(2)

2017年(1)

2015年(2)

2014年(30)

2013年(81)

2011年(5)

2009年(1)

分类: C/C++

2018-08-22 14:42:19

int build_rpn_exprss(char *express,rpn_element_list_t **list){
    rpn_stack_t             *rpn_stack;
    char                    *p,*pn,*start,*tmp_data,c;
    int                     num_flag,field_flag,ret;
    rpn_str_t               var;
    rpn_element_list_t      *head,*tail,*node;
    float                   value;
    rpn_element_t           e,*ep;
   
    head = tail = NULL;
    rpn_init(&rpn_stack);
    p = express;
    field_flag = num_flag = 0;
    var.data = malloc(sizeof(char)*MAX_LEN);
    ep = malloc(sizeof(rpn_element_t));
    if(ep == NULL){
        return 1;
    }
    if(var.data == NULL){
        goto free_ep;
    }

while(*p != '\0' && *p != '='){
        pn = p;
        pn++;
        node = NULL;
               
        if((('0' <= *p && '9' >= *p) && (field_flag == 0)) || ('.' == *p && num_flag == 1)){
            if(num_flag  == 0){
                num_flag = 1;
                memcpy(var.data,p,sizeof(char));
                var.len = 1;
            }
            else{
                tmp_data = &var.data[var.len];
                memcpy(tmp_data,p,sizeof(char));
                var.len++;
            }
            if(*pn != '='){
                p++;
                continue;
            }
        }
       
        if(num_flag == 1){
            num_flag = 0;
            node = malloc(sizeof(rpn_element_list_t));
            if(node == NULL){
                goto free_list;
            }
            if(tail == NULL){
                head = tail = node;

            }
            else{
                tail->next = node;
                tail = node;
            }
            tmp_data = &(var.data[var.len]);
            *tmp_data = '\0';
            node->value.value = strtof(var.data,NULL);    
            if(node->value.value == 0){
                goto free_list;
            }
            node->type = ELEMENT_TYPE_VALUE;
            node->next = NULL;
        }
       
        if( (('A' <= *p  && 'Z' >= *p) || ('a' <= *p  && 'z' >= *p)) || ((('.' == *p) || ('_' == *p) 
            || ('0' <= *p && '9' >= *p)) && field_flag == 1)){
           
            if(field_flag  == 0){
                field_flag = 1;
                memcpy(var.data,p,sizeof(char));
                var.len = 1;
            }
            else{

                tmp_data = &var.data[var.len];
                memcpy(tmp_data,p,sizeof(char));
                var.len++;
            }
            if(*pn != '='){
                p++;
                continue;
            }
        }
       
        if(field_flag == 1){
            field_flag = 0;
            node = malloc(sizeof(rpn_element_list_t));
            if(node == NULL){
                goto free_list;
            }
            if(tail == NULL){
                head = tail = node;
            }
            else{
                tail->next = node;
                tail = node;
            }
            tmp_data = &(var.data[var.len]);
            *tmp_data = '\0';
            ret = npr_getvalue(&var,&value);
            if(ret){

                goto free_list;
            }
            node->value.value = value;
            node->type = ELEMENT_TYPE_VALUE;
            node->next = NULL;
        }
       
        if('(' == *p){
            e.type = ELEMENT_TYPE_OP;
            e.value.op = '(';
            rpn_push(&rpn_stack, &e);
        }
       
        if(')' == *p){
            for(;;){
                rpn_pop(&rpn_stack, &ep);
                if(ep->type != ELEMENT_TYPE_OP){
                    goto free_list;
                }
                c = ep->value.op;
                if('(' == c)  break;
                node = malloc(sizeof(rpn_element_list_t));
                if(node == NULL){
                    goto free_list;
                }
                if(tail == NULL){
                    head = tail = node;

                }
                else{
                    tail->next = node;
                    tail = node;
                }
                node->value.op = c;
                node->type = ELEMENT_TYPE_OP;
                node->next = NULL;
            }
        }
       
        if('+' == *p || '-' == *p || '*' == *p || '/' == *p){
            if(rpn_getoplevel(rpn_stack->value.op)                 e.type = ELEMENT_TYPE_OP;
                e.value.op = *p;
                rpn_push(&rpn_stack, &e);
            }
            else{
                for( ;; ){
                    rpn_pop(&rpn_stack, &ep);
                    if(ep->type != ELEMENT_TYPE_OP){
                        goto free_list;
                    }
                    c = ep->value.op;
                    if(rpn_getoplevel(c)                         if(c != STACK_END_FLAG){

                            e.type = ELEMENT_TYPE_OP;
                            e.value.op = c;
                            rpn_push(&rpn_stack, &e);
                        }
                        e.type = ELEMENT_TYPE_OP;
                        e.value.op = *p;
                        rpn_push(&rpn_stack, &e);
                        break;
                    }
                    node = malloc(sizeof(rpn_element_list_t));
                    if(node == NULL){
                        goto free_list;
                    }
                    if(tail == NULL){
                        head = tail = node;
                    }
                    else{
                        tail->next = node;
                        tail = node;
                    }
                    node->value.op = c;
                    node->type = ELEMENT_TYPE_OP;
                    node->next = NULL;
                }
            }
        }

       
        p++;
    };      
   
    for( ;; ){
        rpn_pop(&rpn_stack, &ep);
        if(ep->type == ELEMENT_TYPE_OP ){
            c = ep->value.op;
            if(c == STACK_END_FLAG)  break;
        }
        node = malloc(sizeof(rpn_element_list_t));
        if(node == NULL){
            goto free_list;
        }
        if(tail == NULL){
            head = tail = node;
        }
        else{
            tail->next = node;
            tail = node;
        }
        if(ep->type == ELEMENT_TYPE_OP){
            node->value.op = ep->value.op;
            node->type = ELEMENT_TYPE_OP;
        }


        else{
            node->value.value = ep->value.value;
            node->type = ELEMENT_TYPE_VALUE;
        }
        node->next = NULL;
    }
   
    *list = head;
   
    return 0;
   
free_list:
    if(head != NULL){
        rpn_free_list(head);
    }
   
end:
    free(var.data);
free_ep:
    free(ep);
    return 1;
}



void rpn_init(rpn_stack_t **s){
    rpn_stack_t                 *p;
   
    p = (rpn_stack_t *)malloc(sizeof(rpn_stack_t));
    p->value.op = STACK_END_FLAG;
    p->type = ELEMENT_TYPE_OP;
    p->next=NULL;
   
    *s = p;
    return;
}



void rpn_push(rpn_stack_t **s,rpn_element_t *e){
    rpn_stack_t                 *p;
   
    p = (rpn_stack_t *)malloc(sizeof(rpn_stack_t));
    if(e->type == ELEMENT_TYPE_OP ){
        p->type = ELEMENT_TYPE_OP;
        p->value.op = e->value.op;
    }
    else{
        p->type = ELEMENT_TYPE_VALUE;
        p->value.value = e->value.value;
    }
    p->next=*s;
    *s=p;
   
    return;
}


void rpn_pop(rpn_stack_t **s, rpn_element_t **e){
    rpn_stack_t                     *p;
   
    if((*s)->next){
        p = *s;
        if((*s)->type == ELEMENT_TYPE_OP){
            (*e)->type = ELEMENT_TYPE_OP;
            (*e)->value.op = (*s)->value.op;
        }
        else{
            (*e)->type = ELEMENT_TYPE_VALUE;
            (*e)->value.value = (*s)->value.value;
        }
        *s = (*s)->next;
        free(p);
        p=NULL;
    }
    else
    {
        (*e)->type = ELEMENT_TYPE_OP;
        (*e)->value.op = STACK_END_FLAG;
    }
}


int  rpn_getoplevel(char op){
    if(op=='+' || op=='-')
        return 1;
    if(op=='*' || op=='/')
        return 2;
    return 0;
}

void rpn_free_list(rpn_element_list_t *node){
    rpn_element_list_t           *next;
   
    next = node->next;
    if(next != NULL){
        rpn_free_list(next);
    }
    free(node);
    return;
}


int npr_getvalue(rpn_str_t *str, float *value){
    char                            *name;
    int                             i,j,num;
   
    num =  sizeof(vars)/sizeof(rpn_var_t);
    for(i=0;i         name = vars[i].name;
        for(j=0;jlen;j++){
            if(name[j] != str->data[j]){
                break;
            }
        }
        if(j == str->len){
            *value = vars[i].value;
            return 0;
        }
    }
   
    return 1;
}



void rpn_print_list(rpn_element_list_t *node){
   
    while(node != NULL){
        if(node->type == ELEMENT_TYPE_OP){
            printf(" %c",node->value.op);
        }
        else{
            printf(" %f",node->value.value);
        }
        node = node->next;
    }
   
    return;
}

int rpn_cac_express(rpn_element_list_t *node,float *ret){
    rpn_stack_t             *rpn_stack;
    rpn_element_t           e,*ep;
    float                   x,y;
    char                    *p;
   
    ep = malloc(sizeof(rpn_element_t));
    if(ep == NULL){
        return 1;
    }
    rpn_init(&rpn_stack);
   
    while(node != NULL){
        if(node->type == ELEMENT_TYPE_VALUE){
            e.type = ELEMENT_TYPE_VALUE;
            e.value.value = node->value.value;
            rpn_push(&rpn_stack,&e);
        }
        else{
            p = &(node->value.op);
            rpn_pop(&rpn_stack,&ep);
            x = ep->value.value;
            rpn_pop(&rpn_stack,&ep);
            y = ep->value.value;
            switch(*p){
                case '+':
                    e.type = ELEMENT_TYPE_VALUE;
                    e.value.value = y + x;

                    rpn_push(&rpn_stack,&e);
                    break;
                case '-':
                    e.type = ELEMENT_TYPE_VALUE;
                    e.value.value = y - x;
                    rpn_push(&rpn_stack,&e);
                    break;
                case '*':
                    e.type = ELEMENT_TYPE_VALUE;
                    e.value.value = y * x;
                    rpn_push(&rpn_stack,&e);
                    break;
                case '/':
                    e.type = ELEMENT_TYPE_VALUE;
                    e.value.value = y/x;
                    rpn_push(&rpn_stack,&e);
                    break;
            }
        }
        node = node->next;
    }
   
    rpn_pop(&rpn_stack,&ep);
    *ret = ep->value.value;

   
    free(ep);
    return 0;
}


阅读(3124) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~