斑竹网络专注为中小企业客户提供以管理服务为核心的IT全方位服务 https://www.sysadm.cn
分类: 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.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)
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
for(j=0;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;
}