📄 userfun.cpp
字号:
#include "globals.h"
#include "string.h"
#include "userfun.h"
#include "iostream.h"
char * userfun::getRoot(char * filename)
{
/*
char * point=strchr (filename, '.');
char * root="";
if (point == NULL)
{
strcat(filename,".txt");
}
for(char * p=filename;p<point;p++)
{
strcat(root,);
}
*/
char * root=filename;
return root;
}
void userfun::printTokenlist(ChainNodeType *tokenlist)
{
ChainNodeType *currentP=tokenlist;
char lex[20];
do
{
switch (currentP->Token.Lex)
{
/* 单词token为保留字,将保留字词元以指定格式写入列表文件listing */
case PROGRAM:
case PROCEDURE:
case TYPE:
case VAR:
case IF:
case THEN:
case ELSE:
case FI:
case INTEGER:
case CHAR:
case WHILE:
case DO:
case ENDWH:
case BEGIN:
case END:
case READ:
case WRITE:
case ARRAY:
case OF:
case RECORD:
case RETURN:
strcpy(lex,"reserved word:");
break;
/* 单词token为特殊符号:ASSIGN (赋值),将":="写入文件listing */
case ASSIGN: strcpy(lex,"ASSIGN"); break;
/* 单词token为特殊符号:LT (小于),将"<"写入文件listing */
case LT: strcpy(lex,"LT"); break;
/* 单词token为特殊符号:EQ (等于),将"="写入文件listing */
case EQ: strcpy(lex,"EQ");break;
/* 单词token为特殊符号:LPAREN (左括号),将"("写入文件listing */
case LPAREN: strcpy(lex,"LPAREN"); break;
/* 单词token为特殊符号:RPAREN (右括号),将")"写入文件listing */
case RPAREN: strcpy(lex,"RPAREN"); break;
/* 单词token为特殊符号:SEMI (分号),将";"写入文件listing */
case SEMI: strcpy(lex,"SEMI"); break;
/* 单词token为特殊符号:PLUS (加号),将"+"写入文件listing */
case PLUS: strcpy(lex,"PLUS"); break;
/* 单词token为特殊符号;MINUS (减号),将"-"写入文件listing */
case MINUS: strcpy(lex,"MINUS"); break;
/* 单词token为特殊符号:TIMES (乘号),将"*"写入文件listing */
case TIMES: strcpy(lex,"TIMES"); break;
/* 单词token为特殊符号:OVER (除号),将"/"写入文件listing */
case OVER: strcpy(lex,"OVER"); break;
case DOT: strcpy(lex,"DOT"); break;
case COMMA: strcpy(lex,"COMMA"); break;
case LMIDPAREN: strcpy(lex,"LMIDPAREN"); break;
case RMIDPAREN: strcpy(lex,"RMIDPAREN"); break;
case UNDERANGE: strcpy(lex,"UNDERANGE"); break;
/* 单词token为簿记单词符号:ENDFILE (文件结尾),将EOF写入文件listing */
case ENDFILE:strcpy(lex,"ENDFILE"); break;
/* 单词token为多字符单词符号:NUM (数字),将数值写入文件listing */
case INTC:
strcpy(lex,"NUM, val=");
break;
case CHARC:
strcpy(lex,"INCHAR, char=");
break;
/* 单词token为多字符单词符号:ID (标识符),将标识符名写入文件listing */
case ID:
strcpy(lex,"ID, name=");
break;
/* 单词token为簿记单词符号:ERROR (错误),将错误信息写入文件listing */
case ERROR:
strcpy(lex,"ERROR:");
break;
/* 单词token为其他未知单词,未知信息写入文件listing,此种情况不应发生 */
default:
strcpy(lex,"Unknown token:");
break;
}
cout<<currentP->Token.lineshow<<":"<<lex<<" "<<currentP->Token.Sem<<endl;
currentP=currentP->nextToken;
}
while (currentP!=NULL);
}
void userfun::ChainToFile(ChainNodeType *Chainhead,char * root)
{
int num=1;
ChainNodeType *currentP=Chainhead;
/*创建一个新的文件,以存储Token序列*/
strcat(root,".scn"); //词法分析结果文件的扩展名
FILE *fp;
fp=fopen(root,"wb+");
if (fp==NULL)
{ cout<<"cannot create file Tokenlist!"<<endl;
Error = TRUE;
//exit(0);
}
fp=fopen(root,"ab"); /*按追加方式打开文件*/
if (fp==NULL)
{ cout<<"cannot open file Tokenlist!"<<endl;
Error = TRUE;
//exit(0);
}
/*从表头到表尾,依次将所有的Token写入文件*/
do
{ fwrite(currentP,TOKENLEN,1,fp);
currentP=currentP->nextToken;
num++;
}
while (currentP!=NULL);
cout<<"成功!"<<endl;
fclose(fp); /*关闭文件*/
}
/******************************************************/
/* 函数名 printTree */
/* 功 能 把语法树输出,显示在屏幕上 */
/* 说 明 该函数运用了宏来定义增量减量的缩进 */
/******************************************************/
void userfun::printTree(treeNode * tree)
{ int i;
/* 增量缩进宏,每次进入语法树节点都进行增量缩进 */
/* 静态变量indentno在函数printTree中 *
* 用于存储当前子树缩进格数,初始为0 */
static indentno = 0;
/** 增量/减量缩进宏定义 **/
#define INDENT indentno+=4
#define UNINDENT indentno-=4
INDENT;
/* 函数参数给定语法树节点指针tree非NULL(空) */
while (tree != NULL)
{
/*打印行号*/
if(tree->lineno==0)
for(int i=0;i<9;i++)
cout<<" ";
else
switch((int)(tree->lineno / 10))
{
case 0:
cout<<"line:"<<tree->lineno;
for( i=0;i<3;i++)
cout<<" ";
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
cout<<"line:"<<tree->lineno;
for(i=0;i<2;i++)
cout<<" ";
break;
default:
cout<<"line:"<<tree->lineno;
cout<<" ";
}
/* 打印相应的空格,进行缩进 */
for (i=0;i<indentno;i++)
cout<<" ";
switch ( tree->nodekind)
{ case ProK :
cout<<"ProK ";
break;
case PheadK:
{
cout<<"PheadK ";
cout<<tree->name[0]<<" ";
}
break;
case DecK:
{ cout<<"DecK ";
if (tree->attr.ProcAttr.paramt==varparamType )
cout<<"var param: ";
if (tree->attr.ProcAttr.paramt==valparamType)
cout<<"value param: ";
switch(tree->kind.dec)
{ case ArrayK:
{
cout<<"ArrayK ";
cout<<tree->attr.ArrayAttr.up<<" ";
cout<<tree->attr.ArrayAttr.low<<" ";
if (tree->attr.ArrayAttr.childtype == CharK)
cout<<"Chark ";
else if( tree->attr.ArrayAttr.childtype == IntegerK)
cout<<"IntegerK ";
};break;
case CharK:
cout<<"CharK ";break;
case IntegerK:
cout<<"IntegerK ";break;
case RecordK:
cout<<"RecordK ";break;
case IdK:
cout<<"IdK ";
cout<<tree->attr.type_name<<" ";
break;
default:
cout<<"error1!";
Error = TRUE;
};
if (tree->idnum !=0)
for (int i=0 ; i <= (tree->idnum);i++)
{
cout<<tree->name[i]<<" ";
}
else
{
cout<<"wrong!no var!"<<endl;
Error = TRUE;
}
} break;
case TypeK:
cout<<"TypeK ";break;
case VarK:
cout<<"VarK ";
if(tree->table[0]!=NULL)
cout<<tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";
break;
case ProcDecK:
cout<<"ProcDecK ";
cout<<tree->name[0]<<" ";
if(tree->table[0]!=NULL)
cout<<tree->table[0]->attrIR.More.ProcAttr.mOff<<" "<<tree->table[0]->attrIR.More.ProcAttr.nOff<<" "<<tree->table[0]->attrIR.More.ProcAttr.level<<" ";
break;
case StmLK:
cout<<"StmLk ";break;
case StmtK:
{ cout<<"StmtK ";
switch (tree->kind.stmt)
{ case IfK:
cout<<"If ";break;
case WhileK:
cout<<"While ";break;
case AssignK:
cout<<"Assign ";
break;
case ReadK:
cout<<"Read ";
cout<<tree->name[0]<<" ";
if(tree->table[0]!=NULL)
cout<<tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";
break;
case WriteK:
cout<<"Write ";break;
case CallK:
cout<<"Call ";
cout<< tree->name[0]<<" ";
break;
case ReturnK:
cout<<"Return ";break;
default:
cout<<"error2! ";
Error = TRUE;
}
};break;
case ExpK:
{ cout<<"ExpK ";
switch (tree->kind.exp)
{ case OpK:
{ cout<<"Op ";
switch(tree->attr.ExpAttr.op)
{ case EQ: cout<< " ="; break;
case LT: cout<< " <"; break;
case PLUS: cout<< " +"; break;
case MINUS:cout<< " -"; break;
case TIMES:cout<< " *"; break;
case OVER: cout<< " /"; break;
default:
cout<< "error3!"; break;
Error = TRUE;
}
if(tree->attr.ExpAttr.varkind==ArrayMembV)
{
cout<< "ArrayMember ";
cout<< tree->name[0]<<" ";
}
};break;
case ConstK:
cout<< "Const ";
switch(tree->attr.ExpAttr.varkind)
{
case IdV:
cout<< "Id ";
cout<< tree->name[0]<<" ";
break;
case FieldMembV:
cout<< "FieldMember ";
cout<< tree->name[0]<<" ";
break;
case ArrayMembV:
cout<< "ArrayMember ";
cout<< tree->name[0]<<" ";
break;
default:
cout<< "var type error!";
Error = TRUE;
}
cout<< tree->attr.ExpAttr.val<<" ";
break;
case VariK:
cout<< "Vari ";
switch(tree->attr.ExpAttr.varkind)
{
case IdV:
cout<< "Id ";
cout<< tree->name[0]<<" ";
break;
case FieldMembV:
cout<< "FieldMember ";
cout<< tree->name[0]<<" ";
break;
case ArrayMembV:
cout<< "ArrayMember ";
cout<< tree->name[0]<<" ";
break;
default:
cout<< "var type error!";
Error = TRUE;
}
if(tree->table[0]!=NULL)
cout<< tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";
break;
default:
cout<< "error4!";
Error = TRUE;
}
};break;
default:
cout<< "error5!";
Error = TRUE;
}
cout<<endl;
/* 对语法树结点tree的各子结点递归调用printTree过程 *
* 缩进写入列表文件listing */
for (i=0;i<MAXCHILDREN;i++)
printTree(tree->child[i]);
/* 对语法树结点tree的兄弟节点递归调用printTree过程 *
* 缩进写入列表文件listing */
tree = tree->sibling;
}
/* 减量缩进宏,每次退出语法树节点时减量缩进 */
UNINDENT;
}
/********************************************************/
/* 函数名 PrintOneLayer */
/* 功 能 打印符号表的一层 */
/* 说 明 有符号表打印函数PrintSymbTable调用 */
/********************************************************/
void userfun::PrintOneLayer(int level,SymbTable **scope)
{
SymbTable *t= scope[level];
cout<<"\n-------SymbTable in level" <<level<<"---------"<<endl;
while (t!=NULL)
{ /*输出标识符名字*/
cout<<t->idName<<": ";
AttributeIR *Attrib = &(t->attrIR );
/*输出标识符的类型信息,过程标识符除外*/
if (Attrib->idtype!=NULL) /*过程标识符*/
switch(Attrib->idtype->kind)
{case intTy : cout<<"intTy "; break;
case charTy: cout<<"charTy "; break;
case arrayTy: cout<<"arrayTy "; break;
case recordTy:cout<<"recordTy ";break;
default : cout<<"error type! "; break;
}
/*输出标识符的类别,并根据不同类型输出不同其它属性*/
switch(Attrib->kind)
{case typeKind :
cout<<"typekind "; break;
case varKind :
cout<<"varkind ";
cout<<"level="<<Attrib->More.VarAttr.level<<" ";
cout<<"Offset="<< Attrib->More.VarAttr.off<<" ";
switch(Attrib->More.VarAttr.access)
{ case dir : cout<<"dir "; break;
case indir: cout<<"indir ";break;
default :cout<<"errorkind "; break;
}
break;
case procKind:
cout<<"funckind ";
cout<<"Level="<<Attrib->More.ProcAttr.level<<" ";
cout<<"Noff="<<Attrib->More.ProcAttr.nOff<<" ";
break;
default :cout<<"error ";
}
cout<<endl;
t = t->next;
}
}
/********************************************************/
/* 函数名 PrintSymbTable */
/* 功 能 打印生成的符号表 */
/* 说 明 */
/********************************************************/
void userfun::PrintSymbTable(SymbTable **scope)
{ /*层数从0开始*/
int level=0;
while (scope[level]!=NULL)
{ userfun::PrintOneLayer(level,scope);
level++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -