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

📄 commandline.cpp

📁 内含源代码和编译实验报告
💻 CPP
字号:
/******************************************************************
** 文件名: CommandLine.cpp
** 描  述: 通过两个类(类的声明在Commcanline.h中)完成命令行参数的处理。包括:
**         v:    显示版本信息。
**         ?:    使用帮助。
**         S:    进行源程序扫描后就结束
**         p:    执行语法分析后结束
**         A:    执行语义分析后结束。
**         C:    产生实际的80X86汇编代码。
**         命令行使用示例: hc/v   显示版本信息。
**                           hc/c filein.c  fileout.asm   编译生成汇编代码文件。
******************************************************************/
#include	"globals.h"
#include	"CommandLine.h"

/****************************************************
**编译过程中用到的所有简单全局变量,在main.c中被定义。
*****************************************************/
extern	CGlobals		AllGlobals;

/******************************************************
**用于控制编译器各阶是否输出信息的标志,在main.c中被定义
*******************************************************/
extern	CFlags			AllFlags;

/*************************CCommandClass 类*********************************/
CCommandClass::CCommandClass(char pa_chParameter, 
			void (*pa_fnpParameter)(CCompileOption& pa_ComOption), 
			                         CCommandClass *pa_pNextClass){
	m_chParameter=pa_chParameter;
	m_fnpParameter=pa_fnpParameter;
	m_pNextClass=pa_pNextClass;
}

/*********************CCommandOpt 类****************************************/
/********************************
**静态数据成员的初始化
********************************/
int		CCommandOpt::m_argc=0;
char	**CCommandOpt::m_argv=NULL;

CCommandOpt::CCommandOpt(int argc,char *argv[],CCompileOption &pa_ComOption){
	m_argc=argc; m_argv=argv;						//这两个是静态数据成员,这儿只是重新赋值。
	OnParameter();
	try{
		if(argc==1)
			throw CbadCommand("Invalid Command.");
		else{
			m_strComline=argv[1];
			if(m_strComline[0]=='/') Lookup_Func(pa_ComOption,m_strComline[1]);
			else OnlyCode(pa_ComOption);}
	}
	catch(CbadCommand& pa_badCommand){
		pa_badCommand.m_fnImformation();}
}

/**************************************
**在类的析构函数中销毁链表
**************************************/
CCommandOpt::~CCommandOpt(){
	CCommandClass *pTempClass;
	while(m_pFirstClass!=NULL){
		pTempClass=m_pFirstClass->m_pNextClass;
		delete m_pFirstClass;
		m_pFirstClass=pTempClass;
	}
}

/**************************************
**建立参数与相应处理函数的链表
**************************************/
void CCommandOpt::OnParameter() throw(bad_alloc){
	try{
		m_pFirstClass=NULL;
		ADD_PARAMETER('v', OnVersion);  
		ADD_PARAMETER('?', OnHelp);
		ADD_PARAMETER('s', OnlyScan);
		ADD_PARAMETER('p', OnlyParse);
		ADD_PARAMETER('a', OnlyAnalyze);
		ADD_PARAMETER('c', OnlyCode);
	}
	catch (bad_alloc){										//处理堆分配异常。
		cout<<"Can't be allocated in heap, the programme must be terminated."<<endl;
		exit(1);
	}
}

/*******************************************
**根据传入的参数找到相应的处理函数
*******************************************/
void CCommandOpt::Lookup_Func(CCompileOption& pa_ComOption,char pa_chParameter){
	CCommandClass *pTempClass=m_pFirstClass;		     //找到链表头,并顺着链表查找函数。
	if(pa_chParameter<97 && pa_chParameter!=63) 
		pa_chParameter+=32;								//参数全部转化为小写处理。问号无须转化。
	while(pTempClass && pTempClass->m_chParameter!=pa_chParameter)
		pTempClass=pTempClass->m_pNextClass;
	if(pTempClass)
		pTempClass->m_fnpParameter(pa_ComOption);//调用函数前,应先确保指针有效。
	else
		throw CbadCommand("Invalid Command.");
	return;
}

/*******************************************
**显示版本信息的命令行处理函数
*******************************************/	
void CCommandOpt::OnVersion(CCompileOption& pa_ComOption){
	cout<<"C- compiler V1.0"<<endl;
	cout<<"copyright @2002"<<endl;
	cout<<"Author: Helinqiang Nancaihong"<<endl;
}

/******************************************
**显示使用帮助信息
******************************************/
void CCommandOpt::OnHelp(CCompileOption& pa_ComOption){
	cout<<endl;
	cout<<"usage:   "<<"hc [/v] [/?] [/s filename.c] [/p filename.c] [/a filename.c]"<<endl;
	cout<<'\t'<<"    [/c filname.c [filename.asm]]"<<endl<<endl;
	cout<<"options:"<<endl;
	cout<<'\t'<<"/v"<<"\t\t"<<"Show the version of the compiler."<<endl;
	cout<<'\t'<<"/?"<<"\t\t"<<"Help information about the compiler."<<endl;
	cout<<'\t'<<"/s filename.c"<<'\t'<<"Only scan the C source file."<<endl;
	cout<<'\t'<<"/p filename.c"<<'\t'<<"Only prase the C source file."<<endl;
	cout<<'\t'<<"/a filename.c"<<'\t'<<"Only analyze the C source file."<<endl;
	cout<<'\t'<<"/c filename.c [filename.asm]]"<<endl;
	cout<<"\t\t\t"<<"Generate the real asm file"<<endl;
	return;
}

/******************************************
**以下四个函数处理相应的编译开关参数。
******************************************/
void CCommandOpt::OnlyScan(CCompileOption& pa_ComOption){
	if(m_argc!=3)
		throw CbadCommand("usage:  hc/s filename.c\ntype hc/? for more information.");
	char *pchargv=m_argv[2];
	ABOUTFILENAME(".c", 2)		//宏,用于辩识源文件的扩展名,不为.c则错误,没有扩展名,则自动加上。
	OpenSourceFile(m_argv[2]);
	AllFlags.m_iTraceScan=1;
	AllFlags.m_iTraceParse=0;
	AllFlags.m_iTraceAnalyze=0;
	AllFlags.m_TraceCode=0;
	pa_ComOption.m_fNoparse=TRUE;
	pa_ComOption.m_fNoanalyze=TRUE;
	pa_ComOption.m_fNocode=TRUE;
}
	
void CCommandOpt::OnlyParse(CCompileOption& pa_ComOption){
	if(m_argc!=3)
		throw CbadCommand("usage:  hc/p filename.c\ntype hc/? for more information.");
	char *pchargv=m_argv[2];
	ABOUTFILENAME(".c", 2)
	OpenSourceFile(m_argv[2]);
	AllFlags.m_iTraceScan=0;
	AllFlags.m_iTraceParse=1;
	AllFlags.m_iTraceAnalyze=0;
	AllFlags.m_TraceCode=0;
	pa_ComOption.m_fNoparse=FALSE;
	pa_ComOption.m_fNoanalyze=TRUE;
	pa_ComOption.m_fNocode=TRUE;
}
	
void CCommandOpt::OnlyAnalyze(CCompileOption& pa_ComOption){
	if(m_argc!=3)
		throw CbadCommand("usage:  hc/a filename.c\ntype hc/? for more information.");
	char *pchargv=m_argv[2];
	ABOUTFILENAME(".c", 2)
	OpenSourceFile(m_argv[2]);
	AllFlags.m_iTraceScan=0;
	AllFlags.m_iTraceParse=0;
	AllFlags.m_iTraceAnalyze=1;
	AllFlags.m_TraceCode=0;
	pa_ComOption.m_fNoparse=FALSE;
	pa_ComOption.m_fNoanalyze=FALSE;
	pa_ComOption.m_fNocode=TRUE;
}
	
void CCommandOpt::OnlyCode(CCompileOption& pa_ComOption){
	if(m_argc!=3 && m_argc!=4)
		throw CbadCommand("usage:  hc/c filename.c [filename.asm]\ntype hc/? for more information.");
	char *pchargv=m_argv[2];
	ABOUTFILENAME(".c", 2)
	OpenSourceFile(m_argv[2]);
	if(m_argc==3){	//生成代码时,没有指定目标代码文件,则自动生成与源文件同名的文件。
		pchargv=m_argv[2]+strlen(m_argv[2])-2;
		*pchargv='\0';
		strcat(m_argv[2],".asm");
		OpenCodeFile(m_argv[2]);}
	else{
		pchargv=m_argv[3];
		ABOUTFILENAME(".asm", 3)
		OpenCodeFile(m_argv[3]);}
	AllFlags.m_iTraceScan=0;
	AllFlags.m_iTraceParse=0;
	AllFlags.m_iTraceAnalyze=0;
	AllFlags.m_TraceCode=1;
	pa_ComOption.m_fNoparse=FALSE;
	pa_ComOption.m_fNoanalyze=FALSE;
	pa_ComOption.m_fNocode=FALSE;
}

/*****************************************
**  找开源程序文件
*****************************************/
void CCommandOpt::OpenSourceFile(string filename){
	AllGlobals.source.open(filename.c_str(),ios_base::in);
	if(!AllGlobals.source)
		throw CbadCommand("Can't find the source file.");
	return;
}

/***************************************
**  打开目标代码文件
***************************************/
void CCommandOpt::OpenCodeFile(string filename){
	AllGlobals.code.open(filename.c_str(),ios_base::out);
	if(!AllGlobals.code)
		throw CbadCommand("Can't find the code file.");
	return;
}

⌨️ 快捷键说明

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