分享

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

 yelin21 2010-09-19

简化c语言编译器(符号表)

c++学习 2008-11-12 10:39:40 阅读285 评论0   字号: 订阅

/*
*改造parser()成功
*专心处理函数Createtab()来生成语法树。
*/
/*2008-6-25
*处理函数时,local_size的值没变化
*运行时就没有进入全局变量处理的区域。
*/

/*2008-6-27
 *符号表成功完成,后继步骤为静态语义检查和中间代码生成。
 *有两个疑问,
 *(1).一个是函数输出时 entryAddr="0",留着后面处理,留下了悬念
 *(2).<child varName="eee" varType="int" isArray="1" arraySize="1" Rva="4" />
 *中的arraySize = "1",表示其为一维数组。 还是什么?
 *
 *
*/

//在函数定义中,当无参时,第一孩子为空,但第二孩子不空,不能使用if(T->child[0] == NULL) 为判空条件
//我们这里假设第一、第二为空则孩子节点为空 ,应该if(T->child[0] == NULL && T->child[1] == NULL)

#include<iostream>
#include<string>
#include<fstream>
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<<"Can't open the input file!"<<endl;
  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 <<" at line "<<lineno<<endl;
 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<<"<?xml version=\"1.0\"?>"<<endl;
outFile<<"<root>"<<endl;
token = getNextToken();
root = program();
DispTree(root);

outFile<<"</root>"<<endl;
}

 

//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<<"<tree line =\""<<T->lineno<<"\" nodetype =\""<<T->ntype<<"\" nodestring=\""<<T->nodestr<<"\"";
  if(T->vartype != "")
   outFile<<" vartype=\""<<T->vartype<<"\"";
  if(T->rettype != "")
   outFile<<" rettype=\""<<T->rettype<<"\"";
  if(T->isarray == 0 || T->isarray == 1)
   outFile<<" isarray=\""<<T->isarray<<'\"';
 }

}

 

void Tree::DispTree(TreeNode * T)


 if(T != NULL)
 { 
  blanksPrint();
  printNodeInfo(T);

  if(T->child[0] == NULL && T->child[1] == NULL)   ////在函数定义中,当无参时,第一孩子为空,但第二孩子不空,我们这里假设第一、第二为空则孩子节点为空
   outFile<<"/>"<<endl;
  else
   outFile<<'>'<<endl;

  for(int i = 0;i < 5;i ++)
   if(T->child[i] != NULL)
   { blanksPlus();/////////////////////////////////////////////////-----------------------------------
  blanksPrint();
  outFile<<"<child>"<<endl;
  blanksPlus();//*****************************************************
  DispTree(T->child[i]);
  blanksMinus();//**************************************************
  blanksPrint();
  outFile<<"</child>"<<endl;
  blanksMinus();//////////////////////////////////////////////------------------------------------
  }


  if(T->child[0] != NULL || T->child[1] != NULL)
  {
   blanksPrint(); 
   outFile<<"</tree>"<<endl;
  }

  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<<"undefined declaration."<<endl;
   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<<"in local processer()----------------------------------"<<endl;
  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<<"<?xml version=\"1.0\"?>"<<endl;
 fout<<"<root>"<<endl;
 //输出全局变量
 fout<<"    <grobalVar>"<<endl;
 for (int i = 0;i < gvarlen;i ++)
 {
  //输出参数成分
  /*<grobalVar>
  * <child varName="a" varType="int" isArray="0" arraySize="0" Rva="0" />
  * <child varName="b" varType="int" isArray="0" arraySize="0" Rva="1" />
  *</grobalVar>
  */
  fout<<"        <child varName="<<'\"'<<grobalvartable[i].var_name<<'\"'<<' ';
  fout<<"varType="<<'\"'<<grobalvartable[i].var_type<<'\"'<<' ';
  fout<<"isArray="<<'\"'<<grobalvartable[i].isarray<<'\"'<<' ';
  fout<<"arraySize="<<'\"'<<grobalvartable[i].array_size<<'\"'<<' ';
  fout<<"Rva="<<'\"'<<grobalvartable[i].rva<<'\"'<<' '<<"/>";
  fout<<endl;
 }
 fout<<"    </grobalVar>"<<endl;


 //输出函数部分
 for (int i = 0;i < funlen;i ++)
 {
  //<tree funID="1" funName="main" retType="void" entryAddr="0" paraVarSize="0" localVarSize="2" tryblockCount="0" unwindCount="0">
  fout<<"    <tree funID="<<'\"'<<funtable[i].fun_id<<'\"'<<' ';
  fout<<"funName="<<'\"'<<funtable[i].fun_name<<'\"'<<' ';
  fout<<"retType="<<'\"'<<funtable[i].rt_type<<'\"'<<' ';
  fout<<"entryAddr="<<'\"'<<funtable[i].entry_address<<'\"'<<' ';
  fout<<"paraVarSize="<<'\"'<<funtable[i].para_size<<'\"'<<' ';
  fout<<"localVarSize="<<'\"'<<funtable[i].local_size<<'\"'<<'>';
  fout<<endl;

  //输出参数成分
  /*<paraVar>
  * <child varName="a" varType="int" isArray="0" arraySize="0" Rva="0" />
  * <child varName="b" varType="int" isArray="0" arraySize="0" Rva="1" />
  *</paraVar>
  */

  if (funtable[i].para_size != 0)
  {
   fout<<"        <paraVar>"<<endl;
   for(int j = funtable[i].para_list;j < funtable[i].para_list + funtable[i].para_size;j ++)
   {
    fout<<"            <child varName="<<'\"'<<vartable[j].var_name<<'\"'<<' ';
    fout<<"varType="<<'\"'<<vartable[j].var_type<<'\"'<<' ';
    fout<<"isArray="<<'\"'<<vartable[j].isarray<<'\"'<<' ';
    fout<<"arraySize="<<'\"'<<vartable[j].array_size<<'\"'<<' ';
    fout<<"Rva="<<'\"'<<vartable[j].rva<<'\"'<<' '<<"/>";
    fout<<endl;
   }
   fout<<"        </paraVar>"<<endl;
  }

  //输出local成分
  // <child varName="d" varType="int" varModifier="" isArray="0" arraySize="0" Rva="0" />
  if (funtable[i].local_size != 0)
  {
   fout<<"        <localVar>"<<endl;
   for (int j = funtable[i].local_list;j < funtable[i].local_list + funtable[i].local_size;j ++ )
   {
   
   fout<<"            <child varName="<<'\"'<<vartable[j].var_name<<'\"'<<' ';
   fout<<"varType="<<'\"'<<vartable[j].var_type<<'\"'<<' ';
   fout<<"isarray="<<'\"'<<vartable[j].isarray<<'\"'<<' ';
   fout<<"arraySize="<<"\""<<vartable[j].array_size<<'\"'<<' ';
   fout<<"Rva="<<'\"'<<vartable[j].rva<<'\"'<<" />"<<endl;
   }
   fout<<"        </localVar>"<<endl;
  }
  fout<<"    </tree>"<<endl;

  
  
 }
 fout<<"</root>"<<endl;
 fout.close();
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约