void alg_alter_tree_structure(ASTNode_t **node_p, ASTNode_t *parent, int child_order) { ASTNode_t *node, *left, *right; ASTNode_t *times_node, *one_node; node = *node_p; if((left=ASTNode_getLeftChild(node)) != NULL) { alg_alter_tree_structure(&left, node, 0); } if((right=ASTNode_getRightChild(node)) != NULL) { alg_alter_tree_structure(&right, node, 1); } if(ASTNode_getType(node) == AST_NAME) { times_node = ASTNode_createWithType(AST_TIMES); one_node = ASTNode_createWithType(AST_INTEGER); ASTNode_setInteger(one_node, 1); ASTNode_addChild(times_node, one_node); ASTNode_addChild(times_node, node); if(parent != NULL) { ASTNode_replaceChild(parent, child_order, times_node); } else { *node_p = times_node; } } return; }
void _prepare_reversible_fast_reaction(Model_t *m, myASTNode *myNode, myReaction *re, mySpecies *sp[], myParameter *param[], myCompartment *comp[], myReaction *re_whole[], double sim_time, double dt, double *time, myInitialAssignment *initAssign[], char *time_variant_target_id[], unsigned int num_of_time_variant_targets, timeVariantAssignments *timeVarAssign, char *target_id, int p_or_r, allocated_memory *mem){ ASTNode_t *minus_node, *zero_node, *final_eq_node; myASTNode *eq_root_node; int minus_sign; if(myNode->left != NULL){ _prepare_reversible_fast_reaction(m, myNode->left, re, sp, param, comp, re_whole, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, target_id, p_or_r, mem); } if(myNode->right != NULL){ _prepare_reversible_fast_reaction(m, myNode->right, re, sp, param, comp, re_whole, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, target_id, p_or_r, mem); } if(ASTNode_getType(myNode->origin) == AST_NAME){ if(strcmp(ASTNode_getName(myNode->origin), target_id) == 0){ ASTNode_setType(myNode->origin, AST_INTEGER); ASTNode_setInteger(myNode->origin, 1); eq_root_node = myNode; minus_sign = 1; while(eq_root_node->parent != NULL){ if(ASTNode_getType(eq_root_node->parent->origin) != AST_TIMES && ASTNode_getType(eq_root_node->parent->origin) != AST_DIVIDE){ if(ASTNode_getType(eq_root_node->parent->origin) == AST_MINUS && eq_root_node->parent->right == eq_root_node){ minus_sign *= -1; } if(eq_root_node->parent->parent != NULL){ if(eq_root_node->parent->parent->left == eq_root_node->parent){ eq_root_node->parent->parent->left = eq_root_node; }else{ eq_root_node->parent->parent->right = eq_root_node; } eq_root_node->parent = eq_root_node->parent->parent; }else{ eq_root_node->parent = NULL; break; } }else{ eq_root_node = eq_root_node->parent; } } final_eq_node = eq_root_node->origin; TRACE(("myASTNode is\n")); check_myAST(eq_root_node); ASTNode_recreate(eq_root_node, final_eq_node); if(minus_sign == -1){ minus_node = ASTNode_createWithType(AST_MINUS); zero_node = ASTNode_createWithType(AST_INTEGER); ASTNode_setInteger(zero_node, 0); ASTNode_addChild(minus_node, zero_node); ASTNode_addChild(minus_node, final_eq_node); final_eq_node = minus_node; } if(p_or_r == 0){/* products coefficient */ TRACE(("AST of product numerator is\n")); check_AST(final_eq_node, NULL); re->products_equili_numerator->math_length = get_equation(m, re->products_equili_numerator, sp, param, comp, re_whole, final_eq_node, 0, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, mem); }else{/* reactants coefficient */ minus_node = ASTNode_createWithType(AST_MINUS); zero_node = ASTNode_createWithType(AST_INTEGER); ASTNode_setInteger(zero_node, 0); ASTNode_addChild(minus_node, zero_node); ASTNode_addChild(minus_node, final_eq_node); final_eq_node = minus_node; TRACE(("AST of reactant numerator is\n")); check_AST(final_eq_node, NULL); re->reactants_equili_numerator->math_length = get_equation(m, re->reactants_equili_numerator, sp, param, comp, re_whole, final_eq_node, 0, sim_time, dt, time, initAssign, time_variant_target_id, num_of_time_variant_targets, timeVarAssign, mem); } } } }
/** * Reduces the given stack (containing SLR parser states and ASTNodes) by * the given grammar rule. */ ASTNode_t * FormulaParser_reduceStackByRule (Stack_t *stack, long rule) { ASTNode_t *result = NULL; ASTNode_t *lexpr, *rexpr, *operator; /** * Rule 1: Stmt -> Expr * Rule 9: Expr -> NUMBER * Rule 10: Expr -> NAME * Rule 13: OptArgs -> Args */ if (rule == 1 || rule == 9 || rule == 10 || rule == 13) { Stack_pop(stack); result = Stack_pop(stack); if (rule == 10) { /** * Convert result to a recognized L2 function constant (if * applicable). */ ASTNode_canonicalize(result); } } /** * Rule 2: Expr -> Expr PLUS Expr * Rule 3: Expr -> Expr MINUS Expr * Rule 4: Expr -> Expr TIMES Expr * Rule 5: Expr -> Expr DIVIDE Expr * Rule 6: Expr -> Expr POWER Expr */ else if (rule >= 2 && rule <= 6) { Stack_pop(stack); rexpr = Stack_pop(stack); Stack_pop(stack); operator = Stack_pop(stack); Stack_pop(stack); lexpr = Stack_pop(stack); ASTNode_addChild(operator, lexpr); ASTNode_addChild(operator, rexpr); result = operator; } /** * Rule 7: Expr -> MINUS Expr */ else if (rule == 7) { Stack_pop(stack); lexpr = Stack_pop(stack); Stack_pop(stack); operator = Stack_pop(stack); /** * Perform a simple tree reduction, if possible. * * If Expr is an AST_INTEGER or AST_REAL (or AST_REAL_E), simply negate * the numeric value. Otheriwse, a (unary) AST_MINUS node should be * returned. */ if (ASTNode_getType(lexpr) == AST_INTEGER) { ASTNode_setInteger(lexpr, - ASTNode_getInteger(lexpr)); ASTNode_free(operator); result = lexpr; } else if ( ASTNode_getType(lexpr) == AST_REAL) { ASTNode_setReal(lexpr, - ASTNode_getReal(lexpr)); ASTNode_free(operator); result = lexpr; } else if (ASTNode_getType(lexpr) == AST_REAL_E) { ASTNode_setRealWithExponent( lexpr, - ASTNode_getMantissa(lexpr), ASTNode_getExponent(lexpr) ); ASTNode_free(operator); result = lexpr; } else { ASTNode_addChild(operator, lexpr); result = operator; } } /** * Rule 8: Expr -> LPAREN Expr RPAREN */ else if (rule == 8) { Stack_pop(stack); ASTNode_free( Stack_pop(stack) ); Stack_pop(stack); result = Stack_pop(stack); Stack_pop(stack); ASTNode_free( Stack_pop(stack) ); } /** * Rule 11: Expr -> NAME LPAREN OptArgs RPAREN */ else if (rule == 11) { Stack_pop(stack); ASTNode_free( Stack_pop(stack) ); Stack_pop(stack); lexpr = Stack_pop(stack); Stack_pop(stack); ASTNode_free( Stack_pop(stack) ); Stack_pop(stack); result = Stack_pop(stack); ASTNode_setType(result, AST_FUNCTION); if (lexpr != NULL) { /** * Swap child pointers. In effect the NAME / AST_FUNCTION * represented by result (which has no children) will "adopt" the * children of OptArgs which are the arguments to the AST_FUNCTION. * * After this, OptArgs (lexpr) is no longer needed. */ ASTNode_swapChildren(lexpr, result); ASTNode_free(lexpr); } /** * Convert result to a recognized L2 function constant (if applicable). */ ASTNode_canonicalize(result); } /** * Rule 12: OptArgs -> [empty] */ else if (rule == 12) { result = NULL; } /** * Rule 14: Args -> Expr */ else if (rule == 14) { Stack_pop(stack); lexpr = Stack_pop(stack); result = ASTNode_create(); ASTNode_addChild(result, lexpr); } /** * Rule 15: Args -> Args COMMA Expr */ else if (rule == 15) { Stack_pop(stack); lexpr = Stack_pop(stack); Stack_pop(stack); ASTNode_free( Stack_pop(stack) ); Stack_pop(stack); result = Stack_pop(stack); ASTNode_addChild(result, lexpr); } return result; }