⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bianyi.cpp

📁 一个简单的编译器
💻 CPP
字号:
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<ctype.h>
enum Token_Type{//记号的类别
	ORIGIN,SCALE,ROT,IS,TO,STEP,DRAW,FOR,FROM,//保留字
	T,//参数
	SEMICO,L_BRACKET,R_BRACKET,COMMA,//分隔符
	PLUS,MINUS,MUL,DIV,POWER,//运算符
	FUNC,//函数
	CONST_ID,//常数
	NONTOKEN,//空记号
	ERRTOKEN//出错记号
};
struct Token{
	Token_Type type;
	char *lexeme;
	double value;
	double (*Funcptr)(double);
};
static Token TokenTab[]=
{
	{CONST_ID,"PI",3.1415926,NULL},
	{CONST_ID,"E",2.71828,NULL},
	{T,"T",0,NULL},
	{FUNC,"SIN",0,sin},
	{FUNC,"COS",0,cos},
	{FUNC,"TAN",0,tan},
	{FUNC,"LOG",0,log},
	{FUNC,"EXP",0,exp},
	{FUNC,"SQRT",0,sqrt},
	{ORIGIN,"ORIGIN",0,NULL},
	{SCALE,"SCALE",0,NULL},
	{ROT,"ROT",0,NULL},
	{IS,"IS",0,NULL},
	{FOR,"FOR",0,NULL},
	{FROM,"FROM",0,NULL},
	{TO,"TO",0,NULL},
	{STEP,"STEP",0,NULL},
	{DRAW,"DRAW",0,NULL},
	{ERRTOKEN,"ERRTOKEN",0,NULL}
};
const int TOKEN_LEN=100;
unsigned int LineNo;
static FILE *InFile;
static char TokenBuffer[TOKEN_LEN];
int InitScanner(const char*FileName){//初始化词法分析器
	LineNo=1;
	InFile=fopen(FileName,"r");
	if(InFile!=NULL)return 1;
	else return 0;
}
void CloseScanner(){//关闭词法分析器
	if(InFile!=NULL)fclose(InFile);
}
static char GetChar(){//从源程序中读入一个字符
	int Char=getc(InFile);
	return toupper(Char);
} 
static void AddCharTokenString(char Char){//将字符读到缓冲区
	int TokenLength=strlen(TokenBuffer);
	if(TokenLength+1>=sizeof(TokenBuffer))return;
	TokenBuffer[TokenLength]=Char;
	TokenBuffer[TokenLength+1]='\0';
}
static void EmptyTokenString(){
	memset(TokenBuffer,0,TOKEN_LEN);
}
static Token JudgeKeyToken(const char *IDString){
	int i;
	for(i=0;i<sizeof(TokenTab)/sizeof(TokenTab[0]);i++){
		if(strcmp(TokenTab[i].lexeme,IDString)==0)
			return TokenTab[i];
	}
	Token errortoken;
	memset(&errortoken,0,sizeof(Token));
	errortoken.type=ERRTOKEN;
	return errortoken;
}
static void BackChar(char Char){
	if(Char!=EOF)ungetc(Char,InFile);
}
extern Token GetToken(void){
	Token token;
	int Char;
	memset(&token,0,sizeof(Token));
	EmptyTokenString();
	token.lexeme=TokenBuffer;
	for(;;){
		Char=GetChar();
		if(Char==EOF){
			token.type=NONTOKEN;
			return token;
		}
		if(Char=='\n')LineNo++;
		if(!isspace(Char))break;
	}//end of for
	AddCharTokenString(Char);
	if(isalpha(Char)){
		for(;;){
			Char=GetChar();
			if(isalnum(Char))
				AddCharTokenString(Char);
			else break;
		}
		BackChar(Char);
		token=JudgeKeyToken(TokenBuffer);
		token.lexeme=TokenBuffer;
		return token;
	}
	else if(isdigit(Char)){
		for(;;){
			Char=GetChar();
			if(isdigit(Char))
				AddCharTokenString(Char);
			else break;
		}
		if(Char=='.'){
			AddCharTokenString(Char);
			for(;;){
				Char=GetChar();
				if(isdigit(Char))
					AddCharTokenString(Char);
				else break;
			}
		}//end of if
		BackChar(Char);
		token.type=CONST_ID;
		token.value=atof(TokenBuffer);
		return token;
	}
	else{
		switch(Char){
		case';':token.type=SEMICO;   break;
		case'(':token.type=L_BRACKET;break;
		case')':token.type=R_BRACKET;break;
		case',':token.type=COMMA;    break;
		case'+':token.type=PLUS;     break;
		case'-':
			Char=GetChar();
			if(Char=='-'){
				while(Char!='\n'&&Char!=EOF)Char=GetChar();
				BackChar(Char);
				return GetToken();
			}//end of if
			else{
				BackChar(Char);
				token.type=MINUS;
				break;
			}//end of else
		case'/':
			Char=GetChar();
			if(Char=='/'){
				while(Char!='\n'&&Char!=EOF)Char=GetChar();
				BackChar(Char);
				return GetToken();
			}
			else{
				BackChar(Char);
				token.type=DIV;
				break;
			}
		case'*':
			Char=GetChar();
			if(Char=='*'){
				token.type=POWER;
				break;
			}
			else{
				BackChar(Char);
				token.type=MUL;
				break;
			}
		default:token.type=ERRTOKEN;break;
		}//end of switch
	}//end of close
	return token;
}
typedef double (*MathFuncPtr)(double);
typedef double (*FuncPtr)(double);
struct ExprNode{//语法树节点类型
	enum Token_Type OpCode;
	union{
		struct{ExprNode *Left,*Right;}CaseOperator;
		struct{ExprNode *Child;FuncPtr MathFuncPtr;}CaseFunc;
		double CaseConst;
		double *CaseParmPtr;
	}Content;
};
static Token token;
//辅助函数声明
static void FetchToken();
static void MatchToken(enum Token_Type AToken);
static void SyntaxError(int case_of);
static void ErrMsg(unsigned LineNo,char*descrip,char*string);
static void PrintSyntaxTree(struct ExprNode *root,int indent);
//非终结符的递归子程序声明
static void Program();
static void Statement();
static void OriginStatement();
static void RotStatement();
static void ScaleStatement();
static void ForStatement();
static struct ExprNode *Expression();
static struct ExprNode *Term();
static struct ExprNode *Factor();
static struct ExprNode *Component();
static struct ExprNode *Atom();
//外部接口与语法树构造函数声明
static struct ExprNode *MakeExprNode(enum Token_Type opcode,...);
extern void Parser(char *SrcFilePtr);
//....................................//
static void FetchToken(){//通过语法分析器接口GetToken()获取一个记号
	token=GetToken();
	if(token.type==ERRTOKEN) SyntaxError(1);
}
static void MatchToken(enum Token_Type The_Token){//匹配记号
	if(token.type!=The_Token)SyntaxError(2);
	FetchToken();
}
static void SyntaxError(int case_of){//语法错误处理
	switch(case_of){
	case 1: ErrMsg(LineNo,"错误记号",token.lexeme);break;
	case 2: ErrMsg(LineNo,"不是预期记号",token.lexeme);break;
	}
}
void ErrMsg(unsigned LineNo,char*descrip,char*string){//打印错误信息
	cout<<"Line No!"<<LineNo<<"     "<<descrip<<"      "<<string;
	CloseScanner();
	exit(1);
}
void PrintSyntaxTree(struct ExprNode *root,int indent){//先序遍历并打印表达式的语法树
	int temp;
	for(temp=1;temp<=indent;temp++)printf("\t");//缩进
	switch(root->OpCode){//打印根节点
	case PLUS:     printf("%s\n","+");                               break;
	case MINUS:    printf("%s\n","-");                               break;
	case MUL:      printf("%s\n","*");                               break;
	case DIV:      printf("%s\n","/");                               break;
	case POWER:    printf("%s\n","**");                              break;
	case FUNC:     printf("%x\n",root->Content.CaseFunc.MathFuncPtr);break;
	case CONST_ID: printf("%f\n",root->Content.CaseConst);           break;
	case T:        printf("%s\n","T");                               break;
	default:       printf("Error Tree Node !\n");      exit(0);
	}
	if(root->OpCode==CONST_ID||root->OpCode ==T)return;//叶子节点返回
	if(root->OpCode==FUNC)//递归打印一个孩子节点
		PrintSyntaxTree(root->Content.CaseFunc.Child,indent+1);
	else{//递归打印两个孩子节点
		PrintSyntaxTree(root->Content.CaseOperator.Left,indent+1);
        PrintSyntaxTree(root->Content.CaseOperator.Right,indent+1);
	}
}
void main(int argc,char *argv[]){
	Token token;
	if(argc<2){
		cout<<"请输入源文件!"<<endl;
		return;
	}
	if(!InitScanner(argv[1])){
		cout<<"打开文件失败!"<<endl;
	}
	cout<<"记号类别      字符串         常数值              函数指针"<<endl;
	cout<<"---------------------------------------------------------"<<endl;
	while(1){
		token=GetToken();
		if(token.type!=NONTOKEN){
			cout<<token.type<<"               ";
			cout<<token.lexeme<<"               ";
			cout<<token.value<<"                 ";
			cout<<token.Funcptr<<endl;
		}
		else break;
	}
	cout<<"-----------------------------------------------------"<<endl;
	CloseScanner();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -