/*
*改造parser()成功
*专心处理函数Createtab()来生成语法树。
*/
/*2008-6-25
*处理函数时,local_size的值没变化
*运行时就没有进入全局变量处理的区域。
*/
/*2008-6-27
*符号表成功完成,后继步骤为静态语义检查和中间代码生成。
*有两个疑问,
*(1).一个是函数输出时 entryAddr="0",留着后面处理,留下了悬念
*(2).
*中的arraySize = "1",表示其为一维数组。 还是什么?
*
*
*/
//在函数定义中,当无参时,第一孩子为空,但第二孩子不空,不能使用if(T->child[0] == NULL) 为判空条件
//我们这里假设第一、第二为空则孩子节点为空 ,应该if(T->child[0] == NULL && T->child[1] == NULL)
#include
#include
#include
using namespace std;
//typedef string NodeType ;
typedef string TokenType;
const int Max = 500;
const int Tab_length = 100; //表的长度
class Tree;
class Token;
class Tree;
ifstream inFile;
ofstream outFile;
ofstream fout;
int blanks = 4;
//-------------------------------------class Token-------------------------------------------------------
class Token //用来读词法分析生成的东西
{
public:
string str; //单词字符串
TokenType ttype; //单词的类型
int line; //所在的行数
public:
Token();
~Token();
};
Token::Token()
{
str = "";
ttype = "";
line = -1;
}
Token::~Token()
{}
//-----------------------------------class TreeNode------------------------------------------------------
class TreeNode
{
private:
friend class Tree;
int lineno;
TreeNode *child[5];
TreeNode *sibling; //兄弟节点
string ntype; //节点类型 FunDecl .VarDel,
string nodestr; //保存标识符的名称,便于在语法树中显示
string vartype; //用于标明变量类型int char float
string rettype; //函数返回类型void int char float
int isarray;
public:
TreeNode();
~TreeNode(){};
};
TreeNode::TreeNode()
{
lineno = -1;
child[0] = NULL;
child[1] = NULL;
child[2] = NULL;
child[3] = NULL;
child[4] = NULL;
sibling = NULL;
ntype = "";
nodestr = "";
vartype = "";
rettype = "";
isarray = -1;
}
Token TokenArray[Max];
Token token;
int totalline = 0;
int varline = 0;
//--------------------------------------class Tree----------------------------------------------------------
class Tree
{
private:
TreeNode* root;
public:
Tree(){root = NULL;};
void parser();
void match(TokenType);
Token getNextToken();
Token Restore(int) ; //输入curline = varline,修改varline值用于回退(恢复现场),并返回一个Token对象
int getFirstSpecifier(int pos); //如果返回1,表示为函数申明,找第一个界符
void ParserError(string ,int);
TreeNode* program(); //建立和返回一棵语法树
TreeNode* fun_decl();
TreeNode* var_decl();
TreeNode* param_list();
TreeNode* compound_stmt();
TreeNode* statement();
TreeNode* if_stmt();
TreeNode* while_stmt();
TreeNode* return_stmt();
TreeNode* exp_stmt();
TreeNode* expression();
TreeNode* var();
TreeNode* assign_exp();
TreeNode* simple_exp();
TreeNode* additive_exp();
TreeNode* term();
TreeNode* factor();
TreeNode* assign_exp(TreeNode*);
TreeNode* funcall(TreeNode*);
TreeNode* arg_list();
void printNodeInfo(TreeNode *);
void DispTree(TreeNode *);
//*************************************************************************************
void CreateTab();
void processVar(TreeNode* );
void processFun(TreeNode* );
void PrintTable();
void DestroyTree(TreeNode *);
void Final(); //调用DestroyTree()。
void blanksPlus(); //用来设置xml 格式,加空格
void blanksMinus(); //减空格
void blanksPrint();
~Tree(){};
};
//*****************************************************************************************
class Vartable //变量符号表
{
public:
string var_name ; //变量名
string var_type; //变量类型
int isarray; //数组标拭
int array_size; //数组大小
int rva; //偏移量,相对于前面的变量而言
};
class Funtable //函数符号表
{
public:
int fun_id; //函数标拭符
string fun_name; //函数名
string rt_type; //函数返回类型
int para_size; //函数中参数的占的空间大小
int local_size; //函数中变量占的空间
int entry_address; //函数入口的地址
int para_list; //参数的入口地址
int local_list; //变量的入口地址
};
Vartable vartable[Tab_length];
Vartable grobalvartable[Tab_length];
Funtable funtable[Tab_length];
int funlen = 0; //函数表的长度
int varlen = 0; //local变量表的长度
int gvarlen = 0; //grobal变量表的长度
int globa_num = 0;//全局变量的个数
int para_num = 0; //函数参数的个数
int var_num; //函数局部变量的个数
int para_address = -1; //参数的入口地址
int var_address = -1; //变量的入口地址
//-----------------------------groble variable---------------------------------------------
//------------------------------------main()-----------------------------------------------------
int main()
{
inFile.open("scanner.txt");
if(!inFile.is_open())
{
cout<
cin.get();
exit(EXIT_FAILURE);
}
outFile.open("parser.xml");
int ltemp = 0;
TokenType ttemp = "";
string ntemp = "";
//---------------------------Token op--------------------------
int i = 0;
inFile>>ltemp>>ttemp>>ntemp;
while(!inFile.eof())
{
TokenArray[i].line = ltemp;
TokenArray[i].ttype = ttemp;
TokenArray[i].str = ntemp;
i ++;
inFile>>ltemp>>ttemp>>ntemp;
}
totalline = i ;
//---------------------------construct tree--------------------------
Tree tree;
tree.parser();
tree.CreateTab();
tree.Final();
system("pause");
return 0;
}
void Tree::ParserError(string errinfo,int lineno)
{
outFile<< errinfo <
cin.get();
exit(0);
}
void Tree::match(TokenType expected)
{
if(token.ttype == expected)
token = getNextToken();
else
ParserError((expected +" expected"),token.line);
}
Token Tree::getNextToken()
{//此处不设定结束条件,varline < totalline + 1 调用处设定
int i = varline;
varline ++;
return TokenArray[i];
}
Token Tree::Restore(int curline) //记住当前位置,用于恢复现场
{
varline = curline;
return TokenArray[varline - 1];
}
int Tree::getFirstSpecifier(int pos)
{
int j = pos ;
while(j < totalline)
{
if(TokenArray[j].ttype == "LPAREN")
return 1;
else if(TokenArray[j].ttype == "SEMI" || TokenArray[j].ttype == "COMMA")
return 0;
else if(TokenArray[j].ttype == "LSQUAR" || TokenArray[j].ttype == "RSQUAR")
return 0;
else if(TokenArray[j].ttype == "LBRACE" || TokenArray[j].ttype == "RBRACE")
return 0;
else if(TokenArray[j].ttype == "PLUS" || TokenArray[j].ttype == "MINUS")
return 0;
else if(TokenArray[j].ttype == "STAR" || TokenArray[j].ttype == "DIV")
return 0;
else if(TokenArray[j].ttype == "ASSIGN" || TokenArray[j].ttype == "EQ")
return 0;
else if(TokenArray[j].ttype == "LT" || TokenArray[j].ttype == "GT")
return 0;
else if(TokenArray[j].ttype == "LTEQ" || TokenArray[j].ttype == "GTEQ")
return 0;
j++;
}
return 0;
}
void Tree::parser()
{ outFile<"<
outFile<"<
token = getNextToken();
root = program();
DispTree(root);
outFile<"<
}
//1) program → { var-declaration | fun-declaration }
/*从program()开始,进行语法分析,构建语法树。一个program是由多个全局变量声明或者普通函数定义或者类定义构成的;
* 分别将一个全局变量、一个函数定义构造为一棵语法树。
* 结构如下: 全局变量声明 --> 子函数1 --> 主函数
* var-declaration → int [ID-list | array-list] ;
* fun-declaration → type-specifier ID( params ) compound-stmt
* type-specifier → int | void
*/
TreeNode* Tree::program() //建立和返回一棵语法树
{
TreeNode *root ;
TreeNode *p ;
TreeNode *q ;
if(varline < totalline + 1) //结束条件为varline < total + 1,原因可以看我笔记本上的讲解
{
if(getFirstSpecifier(varline - 1) == 1) //减1的原因与varline 有关,理由同上
root = fun_decl(); //函数定义
else
root = var_decl(); //全局变量的声明
p = root; //记录根节点
while(p->sibling != NULL)
p = p->sibling;
while(varline < totalline + 1) //可能由多个部分组成;文件末尾由varline = totalline + 1标志,原因可以看我笔记本上的讲解
{
if(getFirstSpecifier(varline - 1) == 1) //函数声明
q = fun_decl(); //函数定义
else
q = var_decl(); //全局变量的声明
p->sibling = q; //设置兄弟节点;从这里可以表明全局变量与函数定义之间是同级关系
while(p->sibling != NULL)
p=p->sibling;
}
}
return root;
}
/*4) var-declaration→int ID-list;| int array-list;
/*10) ID-list → ID, | ID-list ID | empty //可以声明多个变量
11) array-list → ID[NUM] | array-list[NUM] //多维数组
* 变量声明可能为简单变量或者数组变量;构建语法节点:
* 简单变量的属性信息有数据类型、类型修饰符、变量名、是否数组;
* 对于数组变量,可以将数组大小表示为节点的属性信息,也可以用子节点来表示;这里采用第二种方法。
* 后面的语义判断时,如果判断到node.IsArray=0,表明不是数组变量;node.IsArray=1,表明是数组变量,其数组大小由node.child[0]指示;
*/
//实现了 多个变量的声明; 多维数组尚未实现
TreeNode* Tree::var_decl()
{
TreeNode *vardeclNode = NULL;
TreeNode *nextNode = NULL;
TreeNode *curNode = NULL;
string tmpvartype = ""; //仅用来存 int
//用while循环来依次构造下一个变量;首先遇到int,然后遇到ID时进行构造变量节点,遇到‘,’表明是多个变量声明,记录前面的属性信息,直接用于下一个类型节点的构造;
//返回的变量节点的第一个节点,后可能跟多个兄弟节点
while(token.ttype != "SEMI")
{
if(token.ttype == "INT")
{
tmpvartype = token.str;
match(token.ttype);
}
else if(token.ttype == "ID") //遇到变量,创建节点
{
nextNode = new TreeNode;
nextNode->ntype = "VarDecl";
nextNode->nodestr = token.str;
nextNode->lineno = token.line;
nextNode->vartype = tmpvartype;
nextNode->isarray =0;
nextNode->sibling = NULL;
if(vardeclNode == NULL)
vardeclNode = nextNode;
else
curNode->sibling = nextNode;
curNode=nextNode;
match(token.ttype);
}
else if(token.ttype == "LSQUAR") //数组变量
{
match("LSQUAR");
curNode->isarray = 1;
if(token.ttype == "NUM") //需要扩展为是表达式的情况
{
TreeNode* sizeNode = new TreeNode();
sizeNode->ntype = "ConstID";
sizeNode->nodestr = token.str;
sizeNode->lineno = token.line;
curNode->child[0] = sizeNode;
match("NUM");
}
else
ParserError("Array var Declaration error",token.line);
match("RSQUAR");
}
else if(token.ttype == "COMMA") //匹配“,”,用来构成ID-list → ID, | ID-list ID | empty
match(token.ttype); // array-list → ID[NUM] | array-list[NUM]
else
ParserError("uninterpreted token",token.line);
}
match("SEMI");
return vardeclNode;
}
/*5) fun-declaration→ type-specifier ID( params ) compound-stmt
type-specifier → int| void
18) params → param-list | void
19) param-list→ param{,param}
20) param→ int ID |int ID[ ]
21) compound-stmt→ { local-declarations statement-list }
22) local-declarations→ var-declaration |empty
23) statement-list→ statement∣empty
24) statement→ expression-stmt∣compound-stmt∣selection-stmt∣iteration-stmt | return-stmt
*/ /* 函数定义节点,属性信息包括返回类型,函数名,它的第一个子节点指向参数列表,第二个子节点指向函数体
*/
TreeNode* Tree::fun_decl()
{
TreeNode* fundeclNode = new TreeNode();
fundeclNode->ntype = "FunDecl";
while(token.ttype != "LPAREN")
{
if(token.ttype == "INT" ||token.ttype == "VOID")
{
fundeclNode->rettype = token.str;
match(token.ttype);
}
else if( token.ttype == "ID")
{
fundeclNode->nodestr = token.str;
fundeclNode->lineno = token.line;
match(token.ttype);
}
else
ParserError("uninterpreted token",token.line);
}
match("LPAREN");
if(token.ttype != "RPAREN") //匹配参数列表,构造第一个子节点
{
TreeNode* paramsNode = param_list();
fundeclNode->child[0] = paramsNode;
}
match("RPAREN");
TreeNode* stmtNode = compound_stmt(); //函数体,第二个子节点
fundeclNode->child[1] = stmtNode;
return fundeclNode;
}
// params → param { , param } | void
// param →int ID [ [ ] ]
TreeNode* Tree::param_list()
{
if(token.ttype == "VOID")
{
match("VOID");
return NULL;
}
TreeNode* paramNode = NULL;
TreeNode* curNode = NULL;
TreeNode* tmpNode = NULL;
while(token.ttype != "RPAREN") //参数列表中不要出现函数调用的情况;不然可能会出错
{
if(token.ttype == "INT")
{
curNode = new TreeNode();
curNode->ntype = "Para";
curNode->vartype = token.str;
match(token.ttype);
}
if(token.ttype == "ID")
{
if(curNode == NULL) //当前节点为空,表示该id是类型 for example :fun()
{
curNode = new TreeNode();
curNode->ntype = "Para";
curNode->vartype = token.str; //这里表明该id是类型
}
else //否则,是参数变量名 for example :fun(int a)
{
curNode->nodestr = token.str;
curNode->lineno = token.line;
curNode->isarray = 0;
}
match("ID");
}
else if(token.ttype == "LSQUAR") //函数定义中参数列表,参数是数组的情况在这里处理;
{ match("LSQUAR");
curNode->isarray = 1;
//数组大小为空,表示参数为数组类型,其大小由传进参数确定
if(token.ttype != "RSQUAR")
ParserError("fun para array error, should not appoint the size of array when in para",token.line);
match("RSQUAR");
}
else if(token.ttype == "COMMA") //表明多个参数
{
if(curNode == NULL)
ParserError("function para error",token.line);
if(paramNode == NULL)
paramNode = curNode;
else
tmpNode->sibling = curNode;
tmpNode = curNode;
match("COMMA");
}
else
ParserError("para error",token.line);
}
if(paramNode == NULL)
paramNode = curNode;
else
tmpNode->sibling = curNode;
return paramNode;
}
// 14) compound-stmt→ { local-declarations statement-list }
// 16) local-declarations → { var-declaration }
// 18) statement-list → { statement }
/* 复合语句,将为每一条语句构建一个语法节点,不论该语句是用于局部变量声明还是程序语句;
* 这样,返回第一条语句的节点指针,其它语句依次作为兄弟节点链接起来。
* 注意:这里的实现中,将多个局部变量声明语句的处理放到了local_declar()函数中,
* 而将多条程序执行语句关系的处理放在函数compound_stmt()中;statement()只是用来处理单条程序语句。
*/
TreeNode* Tree::compound_stmt()
{
TreeNode* stmtNode = NULL, *tmpNode = NULL, *curNode = NULL;
match("LBRACE");
while(token.ttype != "RBRACE")
{
if(token.ttype == "INT")
tmpNode = var_decl();
else
tmpNode = statement();
if(stmtNode == NULL)
{
stmtNode = tmpNode;
curNode = tmpNode;
}
else
curNode->sibling = tmpNode;
while( curNode->sibling != NULL )
curNode = curNode->sibling;
}
match("RBRACE");
return stmtNode;
}
// 19) statement→ expression-stmt∣compound-stmt∣selection-stmt∣iteration-stmt∣return-stmt
TreeNode* Tree::statement()
{
TreeNode* stmtNode = NULL;
if(token.ttype == "LBRACE")
stmtNode = compound_stmt();
else if(token.ttype == "IF")
stmtNode = if_stmt();
else if(token.ttype == "WHILE")
stmtNode = while_stmt();
else if(token.ttype == "RETURN")
stmtNode = return_stmt();
else
stmtNode = exp_stmt();
return stmtNode;
}
// 23) selection-stmt → if ( expression ) statement [ else statement ]
/* 对于if语句,根节点是if,第一个孩子节点表示条件,第二个孩子节点是条件为真的时候的执行语句,
* 第三个孩子节点是else部分的执行语句(如果有的话)
*/
TreeNode* Tree::if_stmt()
{
TreeNode* ifNode = new TreeNode();
ifNode->nodestr = "if";
ifNode->lineno = token.line;
match("IF"); //if
match("LPAREN"); //(
ifNode->child[0] = expression(); //判断条件
match("RPAREN"); //)
if(token.ttype == "LBRACE")
ifNode->child[1] = compound_stmt(); //条件为真的时候的执行语句,这里应该可能有多条语句
else
ifNode->child[1] = statement();
if(token.ttype == "ELSE")
{
match(token.ttype); //else
ifNode->ntype = "IfElseStm";
if(token.ttype == "LBRACE")
ifNode->child[2] = compound_stmt(); //条件为真的时候的执行语句,这里应该可能有多条语句
else
ifNode->child[2] = statement();
}
else
ifNode->ntype = "IfStm";
return ifNode;
}
// 24) iteration-stmt→ while( expression ) statement
TreeNode* Tree::while_stmt()
{
TreeNode* whileNode = new TreeNode();
whileNode->ntype = "WhileStm";
whileNode->nodestr = "while";
whileNode->lineno = token.line;
match("WHILE"); //while
match("LPAREN"); //(
whileNode->child[0] = expression();
match("RPAREN"); //)
whileNode->child[1] = statement();
return whileNode;
}
// 27) return-stmt → return [expression] ;
/* return语句,如果有返回值,则将返回值作为return节点的第一个孩子节点 */
TreeNode* Tree::return_stmt()
{
TreeNode* returnNode = new TreeNode();
returnNode->ntype = "ReturnStm";
returnNode->nodestr = "return";
returnNode->lineno = token.line;
match("RETURN"); //return
if(token.ttype != "SEMI")
returnNode->child[0] = expression();
match("SEMI");
return returnNode;
}
// 21) expression-stmt → [ expression ] ;
TreeNode* Tree::exp_stmt()
{
TreeNode* expNode = NULL;
if(token.ttype != "SEMI")
{
expNode = expression();
}
match("SEMI");
return expNode;
}
// 28) expression→ var = expression | simple-expression
/* 表达式分两种情况:赋值表达式or简单表达式;两种情况都由可能是以var开头;
* 我们需要进行前向搜索以决定是哪一种表达式。
* head(assign-exp) --> head(var)
* head(simple-exp) --> head(additive-exp) --> head(term)
* --> head(factor) --> head(var)
* 其中:head(var) --> ID 以及 head(call) --> ID
*/
TreeNode* Tree::expression()
{
TreeNode* varNode = NULL;
TreeNode* expNode = NULL;
if(token.ttype == "ID")
{
int curline;
curline = varline;
varNode = var();
if(token.ttype == "ASSIGN")
expNode = assign_exp(varNode);
else
{
token = Restore(curline); //恢复现场
expNode = simple_exp();
}
}
else
expNode = simple_exp();
return expNode;
}
/*17) var→ID | ID[expression] */
TreeNode* Tree::var()
{
TreeNode* varNode = NULL;
varNode = new TreeNode();
varNode->nodestr = token.str;
varNode->lineno = token.line;
match("ID");
varNode->ntype = "VarID";
if(token.ttype == "LSQUAR") //数组的情况
{
match("LSQUAR");
if(token.ttype != "RSQUAR")
{
varNode->child[0] = expression();
varNode->isarray = 1;
}
match("RSQUAR");
}
else
varNode->isarray = 0;
return varNode;
}
// 34) simple-expression→ additive-expression [ relop additive-expression]
// 35) relop→ < | <= | > | >= | == | !=
/* 对于简单表达式,根节点是关系操作符,左边的表达式构成第一个孩子节点,
* 右边的表达式构成第二个孩子节点(如果存在的话)
*/
TreeNode* Tree::simple_exp()
{
TreeNode* simpleExpNode = NULL;
TreeNode* additiveExpNode = NULL;
additiveExpNode = additive_exp();
if(token.ttype == "LT" || token.ttype == "LTEQ"||token.ttype == "GT"
||token.ttype =="GTEQ" || token.ttype == "NEQ" || token.ttype =="EQ")
{
simpleExpNode = new TreeNode();
if(token.ttype == "LT")
simpleExpNode->ntype = "RLT" ;
else if(token.ttype == "LTEQ")
simpleExpNode->ntype = "RNGT";
else if(token.ttype == "GT")
simpleExpNode->ntype = "RGT";
else if(token.ttype =="GTEQ")
simpleExpNode->ntype = "RNLT";
else if(token.ttype == "EQ")
simpleExpNode->ntype = "REQ";
else if(token.ttype == "NEQ")
simpleExpNode->ntype = "RNEQ";
else
simpleExpNode->ntype = "ERROR";
simpleExpNode->nodestr = token.str;
simpleExpNode->lineno = token.line;
simpleExpNode->child[0] = additiveExpNode;
match(token.ttype);
simpleExpNode->child[1] = additive_exp();
}
else
simpleExpNode = additiveExpNode;
return simpleExpNode;
}
/*assign-exp → var = expression | var = new ID ( args )
* 赋值语句的语法节点构造:根节点为赋值号,第一个子节点为赋值号左边的表达式,
* 第二个子节点直线赋值号右边的表达式
*/
TreeNode* Tree::assign_exp(TreeNode* varNode)
{
TreeNode* assignNode = new TreeNode();
assignNode->ntype = "AssignStm";
assignNode->nodestr = "=";
assignNode->lineno = token.line;
match("ASSIGN");
assignNode->child[0] = varNode;
assignNode->child[1] = expression();
return assignNode;
}
// 39) additive-expression → term { ( + | - ) term }
TreeNode* Tree::additive_exp()
{
TreeNode* additiveExpNode = NULL;
additiveExpNode = term();
while(token.ttype == "PLUS" || token.ttype == "MINUS")
{
TreeNode* tempNode = new TreeNode();
if(token.ttype == "PLUS")
tempNode->ntype = "ADD";
else if(token.ttype == "MINUS")
tempNode->ntype = "SUB";
else
tempNode->ntype = "ERROR";
tempNode->nodestr = token.str;
tempNode->lineno = token.line;
tempNode->child[0] = additiveExpNode;
match(token.ttype);
tempNode->child[1] = term();
additiveExpNode = tempNode;
}
return additiveExpNode;
}
// 43) term → factor { ( * | / ) factor }
TreeNode* Tree::term()
{
TreeNode* termNode = NULL;
termNode = factor();
while(token.ttype == "STAR" || token.ttype == "SLASH")
{
TreeNode* tempNode = new TreeNode();
if(token.ttype == "STAR")
tempNode->ntype = "MUL";
else if(token.ttype == "SLASH")
tempNode->ntype = "DIV";
else
tempNode->ntype = "ERROR";
tempNode->nodestr = token.str;
tempNode->lineno = token.line;
tempNode->child[0] = termNode;
match(token.ttype);
tempNode->child[1] = factor();
termNode = tempNode;
}
return termNode;
}
// 44) factor→ ( expression )| var | call | NUM
TreeNode* Tree::factor()
{
TreeNode* factorNode = NULL;
if(token.ttype == "LPAREN")
{
match("LPAREN");
factorNode = expression();
match("RPAREN");
}
else if(token.ttype == "NUM")
{
factorNode = new TreeNode();
factorNode->ntype = "ConstID";
factorNode->nodestr = token.str;
factorNode->lineno = token.line;
match(token.ttype);
}
else if(token.ttype == "ID")
{
TreeNode* varNode = var();
if(token.ttype == "LPAREN")
{
factorNode = funcall(varNode);
}
else
factorNode = varNode;
}
return factorNode;
}
//45) call→ ID( arg_list )
TreeNode* Tree::funcall(TreeNode* varNode)
{
TreeNode* funCallNode = varNode;
if(varNode->child[0] != NULL)
varNode = varNode->child[0];
varNode->ntype = "FunCall";
varNode->isarray = -1;
match("LPAREN");
varNode->child[0] = arg_list();
match("RPAREN");
return funCallNode;
}
// 46) args→ arg-list | empty
// 47) arg-list → expression arg-list’
// 48) arg-list’→ , expression arg-list’| null
// 49) args → [ expression { , expression } ]
TreeNode* Tree::arg_list()
{
if(token.ttype == "RPAREN") //参数为空的情况
return NULL;
TreeNode* argNode = expression();
TreeNode* tempNode = argNode;
while(token.ttype == "COMMA")
{
match("COMMA");
if(tempNode != NULL)
{
tempNode->sibling = expression();
tempNode = tempNode->sibling;
}
}
return argNode;
}
void Tree::printNodeInfo(TreeNode* T)
{
if(T != NULL)
{
outFile<lineno<ntype<nodestr<
if(T->vartype != "")
outFile<vartype<
if(T->rettype != "")
outFile<rettype<
if(T->isarray == 0 || T->isarray == 1)
outFile<isarray<
}
}
void Tree::DispTree(TreeNode * T)
{
if(T != NULL)
{
blanksPrint();
printNodeInfo(T);
if(T->child[0] == NULL && T->child[1] == NULL) 在函数定义中,当无参时,第一孩子为空,但第二孩子不空,我们这里假设第一、第二为空则孩子节点为空
outFile<"<
else
outFile<'<
for(int i = 0;i < 5;i ++)
if(T->child[i] != NULL)
{ blanksPlus();/-----------------------------------
blanksPrint();
outFile<"<
blanksPlus();//*****************************************************
DispTree(T->child[i]);
blanksMinus();//**************************************************
blanksPrint();
outFile<"<
blanksMinus();//------------------------------------
}
if(T->child[0] != NULL || T->child[1] != NULL)
{
blanksPrint();
outFile<"<
}
DispTree(T->sibling);
}
}
void Tree::DestroyTree(TreeNode *T)
{
if(T != NULL)
{
DestroyTree(T->sibling);
for(int i = 0;i < 5; i ++)
if(T->child[i] != NULL )
{
DestroyTree(T->child[i]);
}
delete T;
}
}
void Tree::Final()
{
DestroyTree(root);
}
void Tree::blanksPlus() //用来设置xml 格式,加空格
{
blanks = blanks + 4;
}
void Tree::blanksMinus()
{
blanks = blanks - 4;
}
void Tree::blanksPrint()
{
for(int i = 0;i < blanks;i ++)
outFile<
}
//********************************************************************
void Tree::CreateTab()
{
TreeNode* T = NULL;
T = root;
while(T != NULL)
{
if (T->ntype == "VarDecl")
{//全局变量申明
processVar(T);
}
else if (T->ntype == "FunDecl")
{//函数申明
processFun(T);
}
else
{
cout<
break;
}
T = T->sibling;
}
PrintTable();
}
void Tree::processVar(TreeNode* T)
{
if(T->isarray)
grobalvartable[gvarlen].isarray = 1;
else
grobalvartable[gvarlen].isarray = 0;
grobalvartable[gvarlen].array_size = T->isarray;
grobalvartable[gvarlen].var_name = T->nodestr;
grobalvartable[gvarlen].var_type = T->vartype;
grobalvartable[gvarlen].rva = gvarlen; //偏移地址为变量的个数
gvarlen++;
}
void Tree::processFun(TreeNode* T)
{
funtable[funlen].fun_id = funlen;
funtable[funlen].fun_name = T->nodestr;
funtable[funlen].rt_type = T->rettype;
funtable[funlen].entry_address=0; //函数入口地址,代码产生时再分配???????????????????
//对参数进行处理,处理的是变量表,某些信息保留到最后放入函数中
TreeNode* tmpNode = T->child[0];
while (tmpNode != NULL && tmpNode->ntype == "Para")
{
if(para_address == -1)
para_address = varlen; //第一个参数在符号表中的位置
if(tmpNode->isarray)
vartable[varlen].isarray = 1;
else
vartable[varlen].isarray = 0;
vartable[varlen].array_size = tmpNode->isarray;
vartable[varlen].var_name = tmpNode->nodestr;
vartable[varlen].var_type = tmpNode->vartype;
vartable[varlen].rva = para_num; //偏移地址为参数的个数
varlen++;
para_num++; //
tmpNode = tmpNode->sibling;
}
//处理局部变量
TreeNode* tmpvarNode = T->child[1];
while (tmpvarNode != NULL && tmpvarNode->ntype == "VarDecl")
{
//cout<
if(var_address == -1)
var_address = varlen; //第一个变量在符号表中的位置
if(tmpvarNode->isarray)
vartable[varlen].isarray = 1;
else
vartable[varlen].isarray = 0;
vartable[varlen].array_size=tmpvarNode->isarray;
vartable[varlen].var_name = tmpvarNode->nodestr;
vartable[varlen].var_type = tmpvarNode->vartype;
vartable[varlen].rva = var_num; //偏移地址为变量的个数
varlen++;
var_num++; //变量个数加一
tmpvarNode = tmpvarNode->sibling;
}
//把某些参数回填到函数符号表中
funtable[funlen].para_list = para_address;
funtable[funlen].para_size = para_num; //参数的个数
funtable[funlen].local_list = var_address;
funtable[funlen].local_size = var_num; //变量的个数
para_address = -1;
var_address = -1;
para_num = 0;
var_num = 0;
funlen++;
}
void Tree::PrintTable()
{
fout.open("SymbolTable.xml");
fout<"<
fout<"<
//输出全局变量
fout<"<
for (int i = 0;i < gvarlen;i ++)
{
//输出参数成分
/*
*
*
*
*/
fout<
fout<
fout<
fout<
fout<";
fout<
}
fout<"<
//输出函数部分
for (int i = 0;i < funlen;i ++)
{
//
fout<
fout<
fout<
fout<
fout<
fout<';
fout<
//输出参数成分
/*
*
*
*
*/
if (funtable[i].para_size != 0)
{
fout<"<
for(int j = funtable[i].para_list;j < funtable[i].para_list + funtable[i].para_size;j ++)
{
fout<
fout<
fout<
fout<
fout<";
fout<
}
fout<"<
}
//输出local成分
//
if (funtable[i].local_size != 0)
{
fout<"<
for (int j = funtable[i].local_list;j < funtable[i].local_list + funtable[i].local_size;j ++ )
{
fout<
fout<
fout<
fout<
fout<"<
}
fout<"<
}
fout<"<
}
fout<"<
fout.close();
}