I want to make a AST from a formula by bison with node-tree:
Here are the functions to make nodes and the struct of "Node":
typedef enum
{null, opera, var, val} NodeType;
typedef struct Node {
float val;
char * name; // val_name
char * opr; // operator
NodeType node_type;
struct Node * left;
struct Node * right;
} Node;
Node create_op_node(char * op){
Node node;
node.opr = op;
node.node_type = opera;
return node;
}
Node create_var_node(char * op){
Node node;
node.name = op;
node.node_type = var;
return node;
}
Node create_val_node(float value){
Node node;
node.val = value;
node.node_type = val;
return node;
}
the function to run through the tree:
void run_through_tree (Node *node){
switch (node->node_type){
case var:
printf("varable name:%s\n",node->name);
break;
case val:
printf("num value:%f\n",node->val);
break;
case opera:
printf("\noperator:%s\n",node->opr);
printf("LFS\n");
run_through_tree(node->left);
printf("RHS\n");
run_through_tree(node->right);
}
}
and the grammar rules and the way to create and connects is as the following codes:
S : S E T_NEWLINE { main_node = $2;run_through_tree(main_node);} // run through the node tree | {} ;
E : E T_ADD E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("+"); connect_node(op_node,$1,$3);$$ = op_node;}
| E T_SUB E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("-"); connect_node(op_node,$1,$3);$$ = op_node;}
| E T_MUL E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("*"); connect_node(op_node,$1,$3);$$ = op_node;}
| E T_DIV E {Node * op_node = (Node *) malloc(sizeof(Node));*op_node = create_op_node("/"); connect_node(op_node,$1,$3);$$ = op_node;}
| T_SUB E %prec NEG {
Node * op_node = (Node *) malloc(sizeof(Node));
Node * zero_node = (Node *) malloc(sizeof(Node));
* zero_node = create_val_node(0.0);
* op_node = create_op_node("-");
connect_node(op_node,zero_node,$2);
$$ = op_node;}
| T_NUM {Node * val_node = (Node *) malloc(sizeof(Node));* val_node = create_val_node($1); $$ = val_node;}
| T_VAR {Node * var_node = (Node *) malloc(sizeof(Node));* var_node = create_var_node($1); $$ = var_node;}
| T_LPATH E T_RPATH {$$ = $2;}
;
the result of parsing the formula without variables is as expected: 2 * ( 3 + 2)
operator:*
LFS
num value:2.000000
RHS
operator:+
LFS
num value:3.000000
RHS
num value:2.000000
However, the parsing of the formulas with variables is not correct:
2 * a - a + 7 operator:+ LFS
operator:-
LFS
operator:*
LFS
num value:2.000000
RHS
varable name:a - a + 7
RHS
varable name:a + 7
RHS
num value:7.000000
It should be:
2 * a - a + 7 operator:+ LFS
operator:-
LFS
operator:*
LFS
num value:2.000000
RHS
varable name:a
RHS
varable name:a
RHS
num value:7.000000
How could I solve the problem?