2015-05-10 39 views
5

Tôi có một cây cú pháp trừu tượng mà tôi đã thực hiện từ một biểu thức đánh bóng ngược. Các nút của cây là tất cả các chuỗi.Đánh giá biểu thức từ cây cú pháp trừu tượng

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

struct snode 
{ 
    char *datum; 
    struct snode* bottom; 
}; 

struct tnode 
{ 
    char *datum; 
    struct tnode* left; 
    struct tnode*right; 
}; 

struct snode* 
push(struct snode* stack, char *x) { 
    struct snode *S = (struct snode*)malloc(sizeof(struct snode)); 
    S->datum = (char *)malloc(strlen(x) + 1); 
    strcpy(S->datum, x); 
    S->bottom = stack; 
    return S; 
} 

void 
pop(struct snode **stack) { 
    struct snode *S; 
    if (*stack == NULL) 
    return; 

    S = (*stack)->bottom; 
    free(*stack); 
    *stack = S; 
} 

char * 
peek(struct snode* stack){ 
    return stack->datum; 
} 


struct tnode* 
create_node(char *x){ 
    struct tnode* tmp = (struct tnode*)malloc(sizeof(struct tnode)); 
    tmp->datum = (char *)malloc(strlen(x) + 1); 
    strcpy(tmp->datum, x); 
    tmp->right = NULL; 
    tmp->left = NULL; 
    return tmp; 
} 

void 
print_table(struct tnode *AST){ 
    if(AST !=NULL){ 
    printf("("); 
    print_table(AST->left); 
    printf("%s", AST->datum); 
    print_table(AST->right); 
    printf(")"); 
    } 
} 

int 
is_operator(char *tok) 
{ 
    return !strcmp(tok, "A") || !strcmp(tok, "S") || !strcmp(tok, "X") || !strcmp(tok, "D") || !strcmp(tok, "M"); 
} 


struct tnode* 
build_tree(struct snode **S) 
{ 

    struct tnode* root; 
    if (*S == NULL) 
    return NULL; 

    char *top = peek(*S); 

    if (is_operator(top)) 
    { 
     root = create_node(top); 
     pop(S); 
     root->right = build_tree(S); 
     pop(S); 
     root->left = build_tree(S); 
     return root; 
    } 

    root = create_node(top); 

    return root; 
} 


int 
isoperator(struct tnode *AST) 
{ 
    return !strcmp(AST->datum, "A") || !strcmp(AST->datum, "S") || !strcmp(AST->datum, "X") || !strcmp(AST->datum, "D") || !strcmp(AST->datum, "M"); 
} 


int 
main(int argc, char *argv[]) 
{ 

    int i = 1; 
    struct tnode *tree = NULL; 
    struct snode *stack = NULL; 

    char *value; 
    while (argv[i]!= NULL) 
    { 
     value = argv[i]; 
     stack = push(stack, value); 
     i++; 
    } 


    tree = build_tree(&stack); 
    print_table(tree); 
    printf("\n"); 

    return EXIT_SUCCESS; 
} 

Đây là mã tôi có cho đến nay. Đối với hàm đánh giá, tôi đã nghĩ về việc sử dụng hàm này:

int evaluate(struct tnode* AST) 
{ 
    int x, y, z; 
    if (AST != NULL){ 
    if (isoperator(AST->datum)){ 
      x = evaluate(AST->left); 
      y = evaluate(AST->right); 
      switch (AST->datum) 
      { 
      case 'A': 
       z = x + y; 
       break; 
      case 'S': 
       z = x - y; 
       break; 
      case 'X': 
       z = x * y; 
       break; 
      case 'D': 
       z = x/y; 
       break; 
      case 'M': 
       z = x % y; 
       break; 
      } 
      return z; 
     } 

    return AST->datum; 
    } 
} 

nhưng tôi không nghĩ điều này sẽ hiệu quả vì tôi đang sử dụng chuỗi thay vì int. những gì tôi có thể thay đổi về chức năng đánh giá của tôi?

EDIT: Tôi đã nhận thấy mã tôi đăng đã hơi lộn xộn. Tôi đã làm sạch nó để nó trông tốt hơn một chút.

EDIT2:

int evaluate(struct tnode* AST) 
{ 
    int x, y, z; 
    if (AST != NULL){ 
    if (isoperator(AST->datum)){ 
     x = evaluate(AST->left); 
     y = evaluate(AST->right); 
     if(strcmp(AST->datum,"A")==0){ 
     z = x + y; 
     }else if(strcmp(AST->datum,"S")==0){ 
     z = x - y; 
     }else if(strcmp(AST->datum,"X")==0){ 
     z = x * y; 
     }else if(strcmp(AST->datum,"D")==0){ 
     z = x/y; 
     }else if(strcmp(AST->datum,"M")==0){ 
     z = x % y; 
     } 
     return z; 
    } 
    return atoi(AST->datum); 
    } 
    return 0; 
} 

Tôi đã cố gắng loại bỏ các câu lệnh switch nhưng bây giờ tôi nhận được một bãi chứa lõi. Đây chỉ là điều tôi muốn thử. Tôi muốn sửa chức năng đánh giá trước đây của tôi

+0

Bạn có thể làm 'char c = 'A'; int ix = c - 'A''. Hoặc đơn giản là 'c + 0' nếu bạn không nhớ rằng việc đánh số không bắt đầu bằng 0. – ShellFish

+2

Vui lòng không sử dụng nút" đoạn mã "cho mã C. Nó chỉ dành cho các công cụ web runnable (html/JS). Sử dụng nút mã thông thường '{}'. – Mat

+1

Có vẻ như bạn chỉ có số và toán tử. Vì vậy, trong trường hợp nút hiện tại của bạn không có toán tử, chỉ cần trả về 'atoi (AST-> datum)' nên thực hiện công việc (giả sử rằng 'AST-> datum' là zero-terminated). Một điều khác: Mã cho toán tử ''S'' (= trừ?) Của hàm' assessment' có vẻ không chính xác ... –

Trả lời

0

Xin lỗi tôi không có đủ danh tiếng để nhận xét vì vậy tôi sẽ đặt một lỗi mà tôi nhận thấy, coredump có lẽ là do lỗi này.

chức năng isoperator của bạn cần một con trỏ đến struct tnode

int isoperator(struct tnode *AST); 

Nhưng bạn cho nó AST-> dữ kiện mà là một char * trong chức năng đánh giá của bạn:

if (isoperator(AST->datum)) 

Nếu bạn correcte bạn điều kiện này:

if (isoperator(AST)) 

Nó có thể hoạt động tốt hơn.

Các vấn đề liên quan