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

📄 construe.h

📁 是几份有关编译原理词法分析器的C++编程
💻 H
字号:

#include <stdio.h>
#include "clanguageinfo.h"

#define ERROR_INFO cout<<"\n\nerror line:"<<line_count<<endl;
//#include <type>
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;
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 dealword(char *str1,char *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 i=0;
	int flog;
	int line_count=0;     //line counts
	ifstream fin;

	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,"KEY",0,flog);
				}
				else if(strcmp(token,"main")==0)
					dealword(token,"entry function",0);
				else
					dealword(token,"identifier",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,"NUMBER",2);
			}

			///////////////////////////////
			//operator or /////////////////
			else{
				switch(*p){
				case '(' :  dealword("(", "OPERATE", 5, 1); p++;	break;			
				case ')' :  dealword(")", "OPERATE", 5, 1); p++;	break;
				case '[' :	dealword("[", "OPERATE", 5, 3); p++;	break;
				case ']' :  dealword("]", "OPERATE", 5, 2); p++;	break;
				case '?' :	dealword("?", "OPERATE", 5,30); p++;	break;
				case ':' :  dealword(":", "OPERATE", 5,30); p++;	break;
				case '.' :  dealword(".", "OPERATE", 5, 4); p++;	break;  
				case ';' :  dealword(";", "SEPARATOR",6);   p++;	break;
				case '~' :  dealword("~", "OPERATE", 5, 6); p++;	break;
				case '{' :	dealword("{", "SEPARATOR", 6);  p++;	break;
				case '}' :	dealword("}", "SEPARATOR", 6);  p++;	break;
				case ',' :	dealword(",", "OPERATE", 5,42); p++;	break;

				case '#' :  //the macro
					p++;
					blank(p);
					while(*p>='a'&&*p<='z')//the macro is made by letter charactre
					{
						token[i++]=*(p++);
					}
					token[i]='\0';
					flog=ismacro(token);
					if(flog>=0){
						include_bool=true;
						dealword("#","MACRO",7,-2);
						dealword(token,"MACRO",7,flog);
					}
					else{
						ERROR_INFO
						return false;
					}
					break;

				// " ' " a character like 'a' or '\t' 
				case '\'':
					i=0;
					while(*(++p) != '\'')
					   token[i++]=*p;
					token[i]='\0';
					p++;
					if(strlen(token)>3){
						ERROR_INFO
						return false;
					}
					dealword(token,"CHARACTER",3);
					break;

				//"  "   " a string character
				case '\"' :	
					p++;
					i=0;
					if(include_bool){//当这个是宏的包含时的情况
						blank(p);
						while( isalnum(*p) || (*p=='_') || (*p=='.') || (*p=='-'))
						{
								token[i++]=*(p++);
						}
						token[i]='\0';
						dealword("\"","INCLUDE_1",7,-2);
						dealword(token,"INCLUDE_FILE",7);
						dealword("\"","INCLUDE_2",7,-2);
						blank(p);
						if(*p!='\"'){
							ERROR_INFO
							return false;
						}
						p++;
						include_bool=false;
					}
					else{//当这是符号串时的情况
						p++;
						while(*p != '\"' && (*p!='\n' || *p!='\r')){
							token[i++]=*(p++);
						}
						p++;
						token[i]='\0';
						dealword(token,"STRING",4);
					}

					break;

				//the more
				case '!' :
					p++;
					if(*p=='='){
						dealword("!=","OPERATOR",5,24);
						++p;
					}
					else
						dealword("=","OPERATOR",5,5);
					break;

				case '+' :
					p++;
					if(*p=='+'){
						dealword("++","OPERATOR",5,7);
						++p;
					}
					else if(*p=='='){
						dealword("==","OPERATOR",5,32);
						++p;
					}
					else
						dealword("=","OPERATOR",5,15);
					break;
				// -
				case '-' :
					p++;
					if(*p=='-'){
						dealword("--","OPERATOR",5,8);
						p++;
					}
					else if(*p=='='){
						dealword("-=","OPERATOR",5,33);
						p++;
					}
					else if(*p=='>'){
						dealword("->","OPERATOR",5,3);
						p++;
					}
					else if(isalnum(*(p-1)) || *(p-1)=='_') //当“-”的前一个字符是数字、字母或是下划线时,可是断定这是减号
						dealword("-","OPERATOR_SUB",5,16);
					else
						dealword("-","OPERATOR_NEGATIVE",5,9);
					break;
				
				//" /  "——/(除)、 /=(除赋值)、/*(解释)
				case '/' :
					p++;
					if(*p=='='){
						dealword("/=","OPERATOR",5,35);
						++p;
					}
					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("/","OPERATOR",5,13);
					}
					break;

				//" %  "——%(模)、 %=(模赋值)
				case '%' :
					p++;
					if(*p=='='){
						dealword("%=","OPERATOR",5,36);
						++p;
					}
					else{
						dealword("%","OPERATOR",5,14);
						++p;
					}
					break;

				//" |  "——|(按位或)、||(逻辑或)、|=(按位或赋值)
				case '|' :
					p++;
					if(*p=='='){
						dealword("|=","OPERATOR",5,41);
						++p;	
					}
					else if(*p=='|'){
						dealword("||","OPERATOR",5,26);
						++p;	
					}
					else{
						dealword("|","OPERATOR",5,27);
					}
					break;

				//" ^  "——^(按位异或)、^=(按位异或赋值)
				case '^' :
					p++;
					if(*p=='='){
						dealword("^=","OPERATOR",5,40);
						++p;
					}
					else{
						dealword("^","OPERATOR",5,26);
					}
					break;

				//" =  "——=(赋值)、==(逻辑等于)
				case '=' :
					p++;
					if(*p=='='){
						dealword("==","OPERATOR",5,23);
						++p;
					}
					else{
						dealword("==","OPERATOR",5,31);
					}
					break;

				//" >  "—— >(大于)、>>(右移)、>=(大于等于)、>>=(右移赋值)
				case '>' :
					p++;
					if(*p=='='){
						dealword(">=","OPERATOR",5,21);
						++p;
					}
					else if(*p=='>'){
						p++;
						if(*p=='='){
							dealword(">>=","OPERATOR",5,37);
							++p;
						}
						else{
							dealword(">>=","OPERATOR",5,18);
						}
					}
					else if(include_bool){
						include_bool=false;
						dealword(">","INCLUDE_2",7,-2);
					}
					else{
						dealword(">","OPERATOR",5,22);
					}
					break;

				//" <  "—— <(小于)、<<(左移)、<=(小于等于)、<<=(左移赋值)
				case '<' :
					p++;
					if(*p=='='){
						dealword("<=","OPERATOR",5,20);
						p++;
					}
					else if(*p=='<'){
						p++;
						if(*p=='='){
							dealword("<<=","OPERATOR",5,38);
							p++;
						}
						else
							dealword("<<=","OPERATOR",5,17);
					}
					else if(include_bool){
						i=0;
						blank(p);
						while( isalnum(*p) || (*p=='_') || (*p=='.'))
						{
							token[i++]=*(p++);
						}
						token[i]='\0';
						dealword("<","INCLUDE_1",7,-2);
						dealword(token,"INCLUDE_FILE",7);
					}
					else
						dealword("<","OPERATE",5,19);
					break;

				//" *  "—— *(乘)、*(指针运算)、*=(乘赋值)
				case '*' :
					p++;
					if(*p=='='){
						dealword("*=","OPERATE",5,34);
						++p;
					}
					else if( isalnum(*(p-2)) ){
						dealword("*","OPERATE_MUL",5,12);
					}
					else{
						dealword("*","OPERATE_POINT",5,10);
					}
					break;

				//" &  "—— &(按位与)、&(地址运算)、&&(逻辑与)、&=(按位与赋值)
				case '&' :
					p++;
					if(*p=='='){
						dealword("&=","OPERATE",5,39);
						p++;
					}
					if(*p=='&'){
						dealword("&&","OPERATE",5,28);
						p++;
					}
					else if( isalnum(*(p-2)) ){
						dealword("&","OPERATE",5,25);
					}
					else{
						dealword("&","OPERATE",5,11);
					}
					break;

				//其他则错误
				default:
					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++;
}

inline void dealword(char *str1,char *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;
	case 7 : //宏
		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);
}

⌨️ 快捷键说明

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