📄 yufa.cpp
字号:
#include<stdio.h>
#include<string>
#include<fstream>
#include<iostream>
using namespace std;
#define null 0
char ch;
char strToken[10];
char read[50];
int i=0,j=0,m=0,n=0;
char *p[120];
int q[100];
int wordnum=0;//词法分析中单词串计数
int yf_wordnum=0;//语法分析中单词串计数
int filelinenum=0;//chengxu.txt行号计数
int toktype;//词法分析中用到的char* type[]下标计数
int yufaright=1;//语法分析是否正确,初始化为1
int treeheight=0;//
int tempwordnum;//printerror()里面未避免重复输出使用
int gloablevarnum;
int paranum=0;
int varnum=0;
int isroot=1;//是否为全局变量或函数
int funnum=0;//生成符号表时所用(函数个数计数)
char curfunname[10];// 为避免递归产生错误的判断
int needreturn=0;
int curcodenum=0;//正生成的代码计数
int curfunnum=0;//正在进行目标代码生成的函数计数
int returnfinish=0;
ofstream cfoutfile("chengxu.xml");
ofstream yfoutfile("chengxu_syntaxTree.xml");
ofstream sym_table("chengxu_symtable.xml");
ofstream codelist("chengxu_asm.xml");
enum TokenType
{
//关键字
IF,ELSE,WHILE,RETURN,VOID,INT, EXP,THROW,CATCH,TRY,VIRTUAL,THIS,DELETE,NEW,PROTECTED,PRIVATE,PUBLIC,CLASS,
//运算符 + - * / = < <= > >= != … //界符 ; , ( ) [ ] { } /* */
PLUS,MINUS,STAR,SLASH,LT,LTEQ,GT,GTEQ,EQ,NEQ,ASSIGN,SEMI,COMMA,COLON,DOT,
WAVE,LPAREN,RPAREN,LSQUAR,RSQUAR,LBRACE,RBRACE,LCOMMENT,RCOMMENT,
ID, //标识符
NUMBER, //数字常量
NONTOKEN,ERROR,ENDFILE // 其它
};
//变量是全局变量还是局部变量还是参数变量
/*enum VarType
{
LOCALVAR,PARAVAR,GLOBALVAR
};*/
char* type[]={
//关键字
"IF","ELSE","WHILE","RETURN","VOID","INT","EXP","THROW","CATCH","TRY","VIRTUAL","THIS",
"DELETE","NEW","PROTECTED","PRIVATE","PUBLIC","CLASS",
//运算符
"PLUS","MINUS","STAR","SLASH", "LT","LTEQ","GT","GTEQ","EQ","NEQ","ASSIGN",
//界符 ; , ( ) [ ] { } /* */
"SEMI","COMMA","COLON","DOT",
"WAVE","LPAREN","RPAREN","LSQUAR","RSQUAR","LBRACE","RBRACE",
"LCOMMENT","RCOMMENT",
"ID", //标识符
"NUMBER", //数字常量
"NONTOKEN","ERROR","ENDFILE"// 其它
};
//语法树节点类型
enum NodeType
{
FunDecl,VarDecl,Para,
ADD, SUB, MUL, DIV, REQ, RLT, RGT, RNEQ, RNGT, RNLT,
AssignStm,IfStm,IfElseStm,ElseStm,WhileStm,ReturnStm,
FunCall, ConstID, VarID,OTHER
};
char * nodetype[]={"FunDecl","VarDecl","Para",
"ADD", "SUB", "MUL", "DIV", "REQ", "RLT", "RGT", "RNEQ", "RNGT", "RNLT",
"AssignStm","IfStm","IfElseStm","ElseStm","WhileStm","ReturnStm",
"FunCall", "ConstID", "VarID","OTHER"
};
//节点结构
typedef struct TreeNode
{
int lineno; //行号
struct TreeNode *child[3];//子节点
struct TreeNode *sibling;//兄弟节点
NodeType ntype;//节点类型
char nodestr[10]; //保存标识符的名称,便于在语法树中显示
char vartype[10]; //用于标明变量类型int char float
char rettype[10]; //函数返回类型void int char float
bool isarray;
}TreeNode,* NodeList; //语法树结点结构定义及数组定义
//建立抽象语法树结点
struct Token
{
string str; //单词字符串
TokenType ttype; //单词的类型
int line; //所在行号信息
} tok[200];
struct keyword
{
int code;
char keyname[10];
};
struct keyword key[18]=
{
{1,"int"}, {2,"void"},{3,"if"},{4,"else"},{5,"while"},{6,"return"},{7,"exp"},{8,"throw"},{9,"catch"},{10,"try"},
{11,"virtual"}, {12,"this"},{13,"delete"},{14,"new"},{15,"protected"},{16,"private"},{17,"public"}, {18,"class"}
};
//变量结构体
struct VarTable
{
char varname[10];
char vartype[10];
int isarray;
int arraysize;
int Rva;
}gloablevarlist[20];
//函数结构体
struct FunTable
{
char funname[10];
int FunId;
char rettype[10];
int entryAddr;
int paraVarSize;
char varName[10];
int localVarSize;
int tryblockCount;
int unwindCount;
VarTable pvartable[10];
VarTable pparavartable[10];
int size;
}funlist[20];
struct Code
{
string label;//标号
string op;//操作码
string arg1;//操作数1
string arg2;//操作数2
}gencode[100];
//函数声明
NodeList CreateTreeNode();
void GetChar();
void GetBC();
void Concat();
int InsertConst();
int InsertId();
int IsLetter();
int IsDigit();
int Reserve();
void Retract();
int scan();
int cifa();
NodeList CreateTreeNode();
void printerror();
int match();
NodeList fun_decla();
NodeList var_decla();
NodeList params();
NodeList param_list();
NodeList param();
NodeList compound_stmt();
NodeList local_decla();
NodeList statement_list();
NodeList statement();
NodeList return_stmt();
NodeList if_stmt();
NodeList while_stmt();
NodeList exp_stmt();
NodeList exp();
NodeList var();
NodeList simple_expression();
NodeList relop();
NodeList additive_expression();
NodeList term();
NodeList factor();
NodeList call();
NodeList args();
NodeList program();
void printtree(NodeList node);
void ScanTree(NodeList root);
int insertgloablevar(NodeList root);
int insertvar(NodeList root);
int insertfun(NodeList root);
int searchvar(NodeList root,int funnum);
int searchfun(NodeList root);
void printsymtable();
void stmtprocess(NodeList root);
//void ScanTreelast(NodeList root);
void ifstmt(NodeList root);
void ifelsestmt(NodeList root);
void whilestmt(NodeList root);
void assignstmt(NodeList root);
void funcallstmt(NodeList root);
void fundeclstmt(NodeList root);
void returnstmt(NodeList root);
void expressionstmt(NodeList root);
string varprocess(int varlocate);
void initcodelist();
void codegen(NodeList root);
int geningsearchfun(NodeList root);
int searchmain();
//词法分析函数定义
void GetChar()
{
ch=read[i];
i++;
}
void GetBC()
{
while(ch==' '||ch==' ')
GetChar();
}
void Concat()
{
strToken[j++]=ch;
}
int IsLetter()
{
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
return 1;
else return 0;
}
int IsDigit()
{
if(ch>='0'&&ch<='9')
return 1;
else return 0;
}
int Reserve()
{
int k=0,m,code1,len;
for(m=0;m<18;m++)
{
len=strlen(key[m].keyname);
if(j==len)
{
while(strToken[k]==key[m].keyname[k]&&k<j)
k++;
}
if(k==j)
{code1=key[m].code;
return code1;
}
}
return 0;
}
void Retract()
{
i--;
ch=null;
}
int InsertId()
{
p[m++]=strToken;
return m;
}
int InsertConst()
{
int temp,sum=0,digit;
for(temp=0;temp<j;temp++)
{
digit=strToken[temp]-'0';
sum=sum*10+digit;
}
q[n++]=sum;
return n-1;
}
int scan()
{
int t;
int code,value;
j=0;
GetChar();
GetBC();
if(IsLetter())
{while(IsLetter()||IsDigit())
{
Concat();
GetChar();
}
Retract();
code=Reserve();
switch (code)
{
case 0:
value=InsertId();
tok[wordnum].ttype=ID;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<"$ID"<<' '<<value;
break;
case 1:
tok[wordnum].ttype=INT;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 2:
tok[wordnum].ttype=VOID;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 3:
tok[wordnum].ttype=IF;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 4:
tok[wordnum].ttype=ELSE;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 5:
tok[wordnum].ttype=WHILE;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 6:
tok[wordnum].ttype=RETURN;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 7:
tok[wordnum].ttype=EXP;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 8:
tok[wordnum].ttype=THROW;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 9:
tok[wordnum].ttype=CATCH;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 10:
tok[wordnum].ttype=TRY;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 11:
tok[wordnum].ttype=VIRTUAL;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 12:
tok[wordnum].ttype=THIS;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 13:
tok[wordnum].ttype=DELETE;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 14:
tok[wordnum].ttype=NEW;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 15:
tok[wordnum].ttype=PROTECTED;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 16:
tok[wordnum].ttype=PRIVATE;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 17:
tok[wordnum].ttype=PUBLIC;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
case 18:
tok[wordnum].ttype=CLASS;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<code<<' '<<"keyword";
break;
}
}
else if(IsDigit())
{
while(IsDigit())
{Concat();
GetChar();
}
Retract();
// value=InsertConst();
tok[wordnum].ttype=NUMBER;
tok[wordnum].str=strToken;
tok[wordnum].line=filelinenum;
cout<<"$INT"<<' '<<strToken;
}
else if(ch=='+')
{
tok[wordnum].ttype=PLUS;
tok[wordnum].str="+";
tok[wordnum].line=filelinenum;
cout<<"$PLUS";
}
else if(ch=='-')
{
tok[wordnum].ttype=MINUS;
tok[wordnum].str="-";
tok[wordnum].line=filelinenum;
cout<<"$MINUS";
}
else if(ch=='.')
{
tok[wordnum].ttype=DOT;
tok[wordnum].str=".";
tok[wordnum].line=filelinenum;
cout<<"$DOT";
}
else if(ch==':')
{
tok[wordnum].ttype=COLON;
tok[wordnum].str=":";
tok[wordnum].line=filelinenum;
cout<<"$COLON";
}
else if(ch=='*')
{GetChar();
if(ch=='/')
{
tok[wordnum].ttype=RCOMMENT;
tok[wordnum].str="*/";
tok[wordnum].line=filelinenum;
cout<<"$RCOMMENT";
}
else
{
Retract();
tok[wordnum].ttype=STAR;
tok[wordnum].str="*";
tok[wordnum].line=filelinenum;
cout<<"$STAR";
}
}
else if(ch=='/')
{GetChar();
if(ch=='*')
{
tok[wordnum].ttype=LCOMMENT;
tok[wordnum].str="/*";
tok[wordnum].line=filelinenum;
cout<<"$LCOMMENT";
}
else
{
Retract();
tok[wordnum].ttype=SLASH;
tok[wordnum].str="/";
tok[wordnum].line=filelinenum;
cout<<"$SLASH";
}
}
else if(ch=='=')
{GetChar();
if(ch=='=')
{
tok[wordnum].ttype=EQ;
tok[wordnum].str="==";
tok[wordnum].line=filelinenum;
cout<<"$EQ";
}
else
{Retract();
tok[wordnum].ttype=ASSIGN;
tok[wordnum].str="=";
tok[wordnum].line=filelinenum;
cout<<"$ASSIGN";
}
}
else if(ch=='>')
{GetChar();
if(ch=='=')
{
tok[wordnum].ttype=GTEQ;
tok[wordnum].str=">=";
tok[wordnum].line=filelinenum;
cout<<"$GTEQ";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -