c语言编译时的符号表,简化c语言编译器(符号表) - xt_syj的日志 - 网易博客

/*

*改造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();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值