📄 gen_maple.cc
字号:
//// *********************************************************************// *// * Author : Gerald Carter// * cartegw@eng.auburn.edu// * Filename : gen_maple.cc// * Date Created : 960320// *// * Description // * -----------// * This function parses a Pascal syntax tree passed // * in as a parameter and output the generated maple// * expression tree.// * // * The general idea is to generate the tree from the// * bottom-up in the same way that bison parses the // * original source code. A stack is provided to keep// * track of the allocated mapleNode.// *// * ---------------------// * Modifications :// * ---------------------// * 961205 cartegw@humsci.auburn.edu Gerald Carter// * Added capability to handle function calls ( recursive // * as well ).// * 970119 cartegw@humsci.auburn.edu Gerald Carter// * Add assumption that the IF branch if always taken// * in an IF as well as IF..ELSE statement// * 970209 cartegw@humsci.auburn.edu Gerald Carter// * Fixed maple expression generated to handle the "expressions"// * member of the grammar. This only applies to the references// * to elements in multiple dimensioned arrays.// *// *********************************************************************//// INCLUDE FILES#include <fstream.h>#include "syntax.h"#include "maple.h"#include "stack.h"#include "labels.h"#include "symbol.h"#include "pas.h"#include "logic.h"#include "stringcl.h"// MACROS#define MAX_MAPLE_CHILDREN 5// ####################################################################// ## Functions local to this file// ##void ConfigureNode ( syntaxNode*, int&, int&, int& );int SetFunctionCall ( mapleNode*, syntaxNode* );int SetFunctionDeclaration ( mapleNode* );int FactorLabel ( int&, int&, syntaxNode* );int TermLabel ( int&, int&, syntaxNode* );int SimpleExprLabel ( int&, int&, syntaxNode* );int ExpressionLabel ( int&, int&, syntaxNode* );int AssignmentLabel ( int&, int&, syntaxNode* );int StatementLabel ( int&, int&, syntaxNode* );int StatementsLabel ( int&, int&, syntaxNode* );int CompoundStmtLabel ( int&, int&, syntaxNode* );int StatementPartLabel ( int&, int&, syntaxNode* );int IdentLabel ( int&, int&, syntaxNode* );int ProcOrFuncLabel ( int&, int&, syntaxNode* );int BodyLabel ( int&, int&, syntaxNode* );int BlockLabel ( int&, int&, syntaxNode* );int ActualParamsLabel ( int&, int&, syntaxNode* );int ActualsListLabel ( int&, int&, syntaxNode* );int ActualParamLabel ( int&, int&, syntaxNode* );int ColonThingsLabel ( int&, int&, syntaxNode* );int VariableLabel ( int&, int&, syntaxNode* );int ExpressionsLabel ( int&, int&, syntaxNode* );// ####################################################################// ## Global variables// ##stack<char*> procStack; // will hold current procedure or // function nameboolean push_node = TRUE; // Do we push the node onto the stack?// ####################################################################// ## GenerateMapleExpression ()// ##int GenerateMapleExpression (syntaxNode *sourceTree, stack<mapleNode*> &mapleStack){ // local variable mapleNode *mapleChild = 0; syntaxNode *orphans[MAX_MAPLE_CHILDREN] = { 0, 0, 0, 0, 0}; int node_label = 0, value = 0, num_children = 0; int i; syntaxNode **syntax_children = 0; char label_string[100]; // Get the children from the current syntaxNode and generate their // maple expression first. If the current node has no children, // then the following loop is bypassed. syntax_children = sourceTree->GetChildren (); if (syntax_children != 0) for (i = 0; i < sourceTree->SizeOfFamily(); i++) GenerateMapleExpression ( *(syntax_children+i), mapleStack ); // Initialization push_node = TRUE; // If the node has no children then allocate the mapleNode and push // it onto the stack. Otherwise do the children first and then yourself // along the same principle. ConfigureNode ( sourceTree, node_label, num_children, value ); if ( ( node_label == 0 ) && ( num_children != -1 ) ) { cout << "Node label is 0!!! " << sourceTree->label2string ( sourceTree->GetChildLabel(), label_string ) << "\n"; } switch ( num_children ) { // If the num_children == -1 then we skip this one altogether case -1 : // do nothing break; // Deal with node with no children case 0 : // Allocate space for the new maple node mapleChild = new mapleNode; if ( mapleChild == 0 ) { cerr << "Unable to allocate memory for maple expression node.\n"; exit (-2); } // Set the node label and child label fields mapleChild->SetLabel ( node_label ); mapleChild->AdoptChildren ( 0, 0, orphans ); mapleChild->SetValue ( value ); // Check for specific statements switch ( node_label ) { case FUNCTION_CALL : case PROCEDURE_CALL : // Here we need to insert a pointer to the associated // maple function name. if ( SetFunctionCall ( mapleChild, sourceTree ) != 0 ) { cerr << "Error mapping the maple expression function " << "to the function call." << endl; return ( -1 ); } // Here we should pop off one mapleNode* from the mapleStack. // It should be the "Actuals List" in the case of a function // call or "Actual Params" in the case of a procedure call. // // Probably should include the time to evaluate the // parameters in the function call complexity. Should // be the sum of the expressions' complexities and the // function's complexity. Will come back to that later. if ( NOT mapleStack.IsEmpty() ) { mapleNode *ptr; ptr = mapleStack.Pop (); delete ptr; // be environmentally concerned // Plug memory leaks... // cout << "Procedure Call..." << endl; } else { cerr << "Attempting to pop from an empty stack " << "after Proc / Func call!" << endl; return ( -1 ); } break; default : // Everything else just passes through. break; } // Push the new maple node's address onto the stack if ( push_node ) mapleStack.Push ( mapleChild ); break; default : // Allocate space for the new maple node mapleChild = new mapleNode; if ( mapleChild == 0 ) { cerr << "Unable to allocate memory for maple expression node.\n"; exit (-2); } // Set the node label and child label fields. Note that the // childrens' addresses are currently on the stack mapleChild->SetLabel ( node_label ); for (i = num_children-1; i >= 0; i--) if ( NOT mapleStack.IsEmpty() ) orphans[i] = mapleStack.Pop (); else { cerr << "Attempting to pop from an empty stack!\n"; return ( -1 ); } mapleChild->AdoptChildren ( num_children, 0, orphans ); mapleChild->SetValue ( value ); // Check for specific statements switch ( node_label ) { // FOR statement case FOR_STATEMENT : { syntaxNode** children = 0; children = sourceTree->GetChildren (); mapleChild->NumberOfSyntaxTrees ( 3 ); mapleChild->SetSyntaxTree ( *( children+0 ), 0 ); mapleChild->SetSyntaxTree ( *( children+1 ), 1 ); mapleChild->SetSyntaxTree ( *( children+3 ), 2 ); } break; // Procedure or Function Declaration case PROC_OR_FUNC : // Next we should set the entry in the symbol table to // contain the maple expression string for the procedure / // function body. if ( SetFunctionDeclaration ( mapleChild ) != 0 ) { cerr << "Error when initializing the function's maple " << "function name." << endl; return ( -1 ); } break; case IF_ELSE_STATEMENT : { // We will pop one pointer off of the mapleStack because // we are assuming that the IF branch is always taken. // Therefore we can throw away the ELSE branch. mapleNode *ptr; if ( NOT mapleStack.IsEmpty() ) { ptr = mapleStack.Pop (); delete ptr; } else cerr << "Attempting to pop from an empty stack for IF..ELSE statement!\n"; } break; default : // Everything else just passes through break; } // Push the new maple node's address onto the stack if ( push_node ) mapleStack.Push ( mapleChild ); break; } // return the resulting generated maple expression tree return ( 0 );}; // end of GenerateMapleExpression ()// ********************************************************************// *// * ConfigureNode ()// *// * Description : This function sets the mapleNode labels and number// * of children for the mapleExpressionTree based// * on the values in the syntaxTreeRoot// *void ConfigureNode (syntaxNode* tree, int &maple_label, int &num_children, int &maple_val){ // local variables int ret_val = 0; // The mapleNode's labels and number of children are determined // by the current values of the corrsponding fields in the // syntaxTreeRoot. switch ( tree->GetLabel() ) { case FACTOR_LABEL : maple_val = FactorLabel ( maple_label, num_children, tree ); break; case TERM_LABEL : maple_val = TermLabel ( maple_label, num_children, tree );; break; case SIMPLE_EXPR_LABEL : maple_val = SimpleExprLabel ( maple_label, num_children, tree ); break; case EXPRESSION_LABEL : maple_val = ExpressionLabel ( maple_label, num_children, tree ); break; case EXPRESSIONS_LABEL : maple_val = ExpressionsLabel ( maple_label, num_children, tree ); break; case ASSIGNMENT_LABEL : maple_val = AssignmentLabel ( maple_label, num_children, tree ); break; case STATEMENT_LABEL : maple_val = StatementLabel ( maple_label, num_children, tree ); break; case STATEMENTS_LABEL : maple_val = StatementsLabel ( maple_label, num_children, tree ); break; case COMPOUND_STMT_LABEL : maple_val = CompoundStmtLabel ( maple_label, num_children, tree ); break; case STATEMENT_PART_LABEL : maple_val = StatementPartLabel ( maple_label, num_children, tree ); break; case BLOCK_LABEL : maple_val = BlockLabel ( maple_label, num_children, tree ); break; case BODY_LABEL : maple_val = BodyLabel ( maple_label, num_children, tree ); break; case PROC_OR_FUNC_LABEL : maple_val = ProcOrFuncLabel ( maple_label, num_children, tree ); break; case ACTUAL_PARAMS_LABEL : maple_val = ActualParamsLabel ( maple_label, num_children, tree ); break; case ACTUALS_LIST_LABEL : maple_val = ActualsListLabel ( maple_label, num_children, tree ); break; case ACTUAL_PARAM_LABEL : maple_val = ActualParamLabel ( maple_label, num_children, tree ); break; case COLON_THINGS_LABEL : maple_val = ColonThingsLabel ( maple_label, num_children, tree ); break; case VARIABLE_LABEL : maple_val = VariableLabel ( maple_label, num_children, tree ); break; // We really don't want to process this for the maple expression // but we will remember the function / procedure name for later // lookup in the symbol table. Use of stack enables us to // deal with procedure calls inside of procedure definitions // as well as local functions. case PROC_HEADING_LABEL : case FUNC_HEADING_LABEL : { syntaxNode **children = 0; syntaxNode *ident_root = 0; char *symbol_name; // initialize children = tree -> GetChildren (); ident_root = *(children+0); // we must traverse down the tree ( although we know // it is straight down due to the grammar...away we go ). while ( ident_root -> SizeOfFamily() != 0 ) { children = ident_root -> GetChildren (); ident_root = *(children+0); } // at this point ident_root should be pointing to the // node holding the lexeme for the procedure / function symbol_name = strdup ( (ident_root -> GetLexeme ()) -> GetSymbolName () ); procStack.Push ( symbol_name ); } // This is just to keep from pushing a node onto the stack maple_label = 0; num_children = -1; maple_val = 0; break; default : // The default case is that we want to skip the syntax node maple_label = 0; num_children = -1; maple_val = 0; break; }}// ********************************************************************// *// * FactorLabel ()// * // * Description : This function sets the mapleNode labels and number// * of children for the mapleExpressionTree based// * on the values in the occurrence of a FACTOR_LABEL// * syntaxNode label// *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -