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

📄 construe.h

📁 是几份有关编译原理词法分析器的C++编程
💻 H
字号:
#include "clanguageinfo.h"
//#include <type>
//#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;

#define ERROR_INFO  cout<<"\n\nerror line:"<<line_count<<endl

bool construe(char *sourcefile); //construe the C language source
void outcode(char *str);
int  iskey(char *str);             // Is this str  a key ?
int ismacro(char *str);            //Is this str a macro ?
void blank(char* &p);         //throw blank away
void initOperator(list<W_OPERATOR_STRUCT*> &oplist);
bool  findOperator(char *op,W_OPERATOR_STRUCT* &pri);
void dealword(string str1,string str2,int flog,int k=-1);  //stor and deal a vocable
     /* str1——vocable, str2——attribute, flog——the type of this vocable*/


bool construe(char *sourcefile)
{
	char line[256]="";    //read the line
	char *p=NULL;         //point the line 
	char token[20]="";    //the courrent string
	bool include_bool=false;
	int type=-1;
	int i=0;
	int flog;
	int line_count=0;
	ifstream fin;
	W_OPERATOR_STRUCT* ptr=NULL;
	
	initOperator(oplist);//初始化运算符表
	outcode(sourcefile); //输出源程序

	//open the file source 
	fin.open(sourcefile,ios_base::in);
	if( !fin.good()){
		cout<<"Can not open the file,Thank you!!!"<<endl;
		exit(0);
	}	

	while(fin.good()){
		fin.getline(line,sizeof(line));
		++line_count;
		p=line;
		blank(p); //throw the front space away

		//visit this line,this is the main scouse
		while( p<line+strlen(line))
		{
			i=0;
			blank(p);

			//////////////////////////////////////
			//Is the corrent token a identifier?//
			if( isalpha(*p) || (*p=='_') )
			{
				while( isalnum(*p) || (*p=='_') )
				{
					token[i++]=*(p++);
				}
				token[i]='\0';
				flog=iskey(token);				
				if(flog>=0){
					dealword(token,"关键字",0,flog);
				}
				else if(strcmp(token,"main")==0)
					dealword(token,"入口函数",0);
				else
					dealword(token,"标识符",1);
			}//end_if

			///////////////////////////////
			//Is a number?/////////////////
			else if(*p>='0'&&*p<='9')
			{
				while((*p>='0'&&*p<='9') || *p=='.')
					token[i++]=*(p++);
				token[i]='\0';
				dealword(token,"常数",2);
			}

			///////////////////////////////
			//operator or /////////////////
			else{
				//界符判断,单符号及三符号这里处理,只有二符号查表处理,
				//因为三操作符较少,直接可以这里判断,
				//这样的好处有:
				//		1、从空间上来看,可以减少操作符的存储空间,可以只存储二符号的运算符,
				//		2、从效率上来看,大大减少了查表时间,在查表的算法中不用去考虑它是几符号运算符
				switch(*p){
				case ';' :  dealword(";", "分号",6);   p++;	type=6;	break;
				case '{' :	dealword("{", "域界符", 6);  p++;	type=6; break;
				case '}' :	dealword("}", "域界符", 6);  p++;	type=6; break;

				case '#' :  //宏开头,下面直读宏标识符
					p++;
					while(*p==' ') p++;
					while(*p>='a'&&*p<='z')
					{
						token[i++]=*(p++);
					}
					token[i]='\0';
					flog=ismacro(token);
					if(flog>=0){
						include_bool=true;
						dealword("#","宏界符",7,-2);
						dealword(token,"宏名称",7,flog);
					}
					else{
						ERROR_INFO;	
						return false;
					}
					type=7;
					break;

				//“ ' ” 
				case '\'':
					i=0;
					while(*(++p) != '\'')
					   token[i++]=*p;
					token[i]='\0';
					p++;
					if(strlen(token)>3){
						ERROR_INFO;
						return false;
					}
					dealword(token,"字符",3);
					type=3;
					break;

				//“ " ” 
				case '\"' :	
					p++;
					i=0;
					if(include_bool){			
						blank(p);
						while( isalnum(*p) || (*p=='_') || (*p=='.') || (*p=='-'))
						{
								token[i++]=*(p++);
						}
						token[i]='\0';
						dealword("\"","界符",7,-2);
						dealword(token,"包含的文件",7);
						dealword("\"","界符",7,-2);
						blank(p);
						if(*p!='\"'){
							ERROR_INFO;
							return false;
						}
						p++;
						include_bool=false;
					}
					else{
						p++;
						while(*p != '\"'){
							token[i++]=*(p++);
						}
						++p;
						token[i]='\0';
						dealword(token,"STRING",4);
					}
					type=7;
					break;

				default://当不是界符的时候,
					i=0;
					token[i++]=*p;	token[i]='\0';
					++p;//2
					W_OPERATOR_STRUCT* pptr=ptr;
					if(findOperator(token,ptr)){//查找单运算符
						token[i++]=*p;	token[i]='\0';
						pptr=ptr;
						++p;//3
						if(findOperator(token,ptr)){//查找二运算符
							token[i++]=*p;	token[i]='\0';
							++p;//4
							if( strcmp(token,">>=")==0 ){//考虑三运算符,由于只有两个,所以不用搜索了
								dealword(">>=", "右移赋值", 5, 37);
								type=5;
							}
							else if( strcmp(token,"<<=")==0){
								dealword("<<=","左移赋值", 5, 38);
								type=5;
							}
							else {//是二运算符
								--p;//3
								dealword(pptr->op, pptr->attribute, 5, pptr->pri);
								type=5;
							}
						}//end_if2
						else{//是一运算符 
							--p;//2
							switch(token[0]){
							case '*' :
								if(type && type<4){
									dealword(pptr->op, "乘", 5, pptr->pri);
								}
								else{
									dealword(pptr->op, "指针运算", 5, pptr->pri);
								}
								type=5;
								break;

							case '-' :
								if(type && type<4){
									dealword(pptr->op, "减运算", 5, pptr->pri);
								}
								else{
									dealword(pptr->op, "负运算", 5, pptr->pri);
								}
								type=5;
								break;

							case '&' :
								if(type && type<4){
									dealword(pptr->op, "按位与运算", 5, pptr->pri);
								}
								else{
									dealword(pptr->op, "地址运算", 5, pptr->pri);
								}
								type=5;
								break;

							case '/' :
								if(*p=='*'){
									while(!(*p=='*' && *(p+1)=='/'))
									{
										p++;
										if(!(p+1) && fin.good()){
											fin.getline(line,sizeof(line));
											++line_count;
											p=line;
										}
										if(!fin.good()){
											ERROR_INFO;
											return false;
										}
									}
								}
								else{
									dealword("/","除法运算",5,13);
								}
								break;

							case '<' :
								if(include_bool){
									i=0;
									++p;
									blank(p);
									while( isalnum(*p) || (*p=='_') || (*p=='.'))
									{
										token[i++]=*(p++);
									}
									token[i]='\0';
									blank(p);
									if(*p != '>'){
										ERROR_INFO;
										return false;
									}
									++p;
									dealword("<","界符",7,-2);
									dealword(token,"包含文件",7);
									dealword(">", "界符", 7);
									include_bool=false;
									type=7;
								}
								else{
									dealword(pptr->op, "指针运算", 5, pptr->pri);
									type=5;
								}							
								break;

							default  :
								dealword(pptr->op, pptr->attribute, 5, pptr->pri);
								type=5;
								break;
							}//end_switch
						}//end_else	
					}//end_if1
					else{
						ERROR_INFO;
						return false;
					}					
				}//end_switch
			}//end_else
		}//end_while(p)		
	}//end_while(fin)
	return true;
}



int iskey(char *str)//serach this word in key list
{
	int i;
	for(i=0; i<KEY_COUNT; i++){
		if(w_key[i]==str)
			break;
	}
	if(i<KEY_COUNT)
		return i;
	return -1;
}

int ismacro(char *str)//serach this word in macro list
{
	int i;
	for(i=0; i<MACRO_COUNT; i++){
		if(w_macro[i]==str)
			break;
	}
	if(i<MACRO_COUNT)
		return i;
	return -1;
}

void blank(char* &p){         //throw blank away
	while(*p==' ' || *p=='\t')
		p++;
}

void dealword(string str1,string str2,int flog,int k)  //stor and deal a vocable
     //str1 为原词,str2为属性说明,flog为类型,
	 //K: 当是关键字或是宏时,为其所在表中的下标
	 //   当是运算符时,是运算符的优先级
	 //   其他类型时没有意义。
{
	switch(flog){
	case 0 : //关键字
		break;
	case 1 : //标识符
		break;
	case 2 : //常数 number
		break;
	case 3 : //字母 char
		break;
	case 4 : //字符串常量
		break;
	case 5 : //运算符
		break;
	case 6 : //分隔符
		break;
	default: break;
	}
	cout<<setiosflags(ios_base::left)
			<<setw(10)
			<<str1<<", "
			<<setw(3)
			<<flog<<"——"
			<<str2;
	if(k>=0)
		cout<<"——"<<k;
	cout<<endl;
}


void outcode(char *str)
{
	FILE *fp;
	char ch='0';
	fp=fopen(str,"r");
	if( !fp){
		cout<<"Can not open the file,Thank you!!!"<<endl;
		exit(0);
	}
	cout<<"**************** source *******************|"<<endl;
	while(fp && ch!=-1){
		ch=fgetc(fp);
		putchar(ch);
	}
	cout<<"\n********************************************|\n"<<endl;
	fclose(fp);
}


void initOperator(list<W_OPERATOR_STRUCT*> &oplist)
{	
	FILE *fp;	
	bool b=true;
	int pri;
	char op[4],attribute[20];
	W_OPERATOR_STRUCT *opstru;

	fp=fopen("COperator.txt","r");
	while(fp!=NULL)
	{
		fscanf(fp,"%s\t%d\t%s",op,&pri,attribute);
		if(strcmp(op,"#")==0)
			break;
		opstru=new W_OPERATOR_STRUCT;
		opstru->op=op;
		opstru->pri=pri;
		opstru->attribute=attribute;
		oplist.push_back(opstru);		
	}
	fclose(fp);
}

bool  findOperator(char *op,W_OPERATOR_STRUCT* &ptr)
{
	int r=0;
	list<W_OPERATOR_STRUCT*>::const_iterator it;
	it=oplist.begin();
	while( it != oplist.end() ){
		if((*it)->op==op){
			ptr=*it;
			return true;
		}
		++it;
	}

	return false;
}

⌨️ 快捷键说明

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