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

📄 main.cpp

📁 一个词法分析程序。是编译原理完成的一个作业
💻 CPP
字号:
// linpeiwen main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>

//define the ReservedWords total num.
#define MAXRESERVED 6
//define the specialSymbols total num
#define MAXSPECIALSYMBOLS 21

using namespace std;

// define StateType,5 states.
typedef enum {

	START,INCOMMENT,INNUM,INID,DONE
} StateType;

typedef enum {
    /* reserved words */
    IF,ELSE,INT,RETURN,VOID,WHILE,
    /* multicharacter tokens */
    ID,NUM,
    /* special symbols */
    PLUS,MINUS,MTPLUS,DEVIDE,EQ,ASSIGN,LT,MT,TIMES,LXKH,RXKH,LZKH,RZKH,LDKH,RDKH,SEMI,LE,ME,NOTEQ,FH,LZS,RZS,ZS,
	/*stateToken */
	ENDFILE,UNKNOWN,ERROR
} TokenType;

static struct {

	char* str;
    TokenType tt;
} specialSymbols[MAXSPECIALSYMBOLS] = { {"+",PLUS},{"-",MINUS},{"*",MTPLUS},{"/",DEVIDE},{"<",LT},{"<=",LE},{">",MT},
										{">=",ME},{"==",EQ},{"!=",NOTEQ},{"=",ASSIGN},{",",SEMI},{";",FH},{"(",LXKH},
										{")",RXKH},{"[",LZKH},{"]",RZKH},{"{",LDKH},{"}",RDKH},{"/*",LZS},{"*/",RZS}
										};
static struct {

	char* str;
    TokenType tt;
} reservedWords[MAXRESERVED] = {{"if",IF},{"else",ELSE}, {"int",INT},
								{"return",RETURN},{"void",VOID},{"while",WHILE}};

//judge if is digit.
bool isDigit(char c) {

	string digit = "0123456789";
	
	for(int i = 0;i < digit.size();i++) {

		if(digit[i] == c) {
		
			return true;
		}
	}

	return false;
}

//judge if is a letter.
bool isLetter(char c) {

	string alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	
	for(int i = 0;i < alpha.size();i++) {

		if(alpha[i] == c) {
		
			return true;
		}
	}	

	return false;
}

//judge if is ReseredWords,if is return the reservedWords,if is not it is a ID.
TokenType isReservedWords(string str) {

	for(int i = 0;i < MAXRESERVED;i++) { 
	
		if(str == reservedWords[i].str) {
		
			return reservedWords[i].tt;
		} 
	}

	return ID;
}

//output to the outf filestream.
void outputFile(ofstream& outf,TokenType tt,string str) {

	for(int i = 0;i < MAXRESERVED;i++) {

		if(reservedWords[i].str == str) {

			tt = reservedWords[i].tt;
			outf << "ReservedWords: " << str<<endl;
		}
	}

	for(int j=0;j<MAXSPECIALSYMBOLS;j++) {

		if(specialSymbols[j].tt == tt) {
		
			outf << "Special Symbol: " << str <<endl;
		}
	}

	if(tt == ZS) {

		outf << "ZS: " << str << endl; 
	}

	if(tt == ID) {
	
		outf<<"ID: "<< str <<endl;
	}

	if(tt == NUM) {
	
		outf<<"NUM: "<< atoi(str.c_str()) <<endl;
	}

	if(tt == ERROR) {
	
		outf << "ERROR: " << str << endl;
	}

	if(tt == UNKNOWN) {
	
		outf << "UNKNOWN Symbol: " << str << endl;
	}
}

// get the token,有穷自动机的实现
void getToken(ifstream& inf,ofstream& outf,int& lineno) {
	
	TokenType tt; 
	StateType state = START;	
	string str = "";

	static int flag = 1;

	while(state != DONE) {
			
		char c = inf.get();	

		if(flag == 1) {
		
			outf << "-------------------------------------------" << endl;
			outf << "In the line " << lineno << " : " <<endl;
			flag = 0;			
		}
		
		switch(state) {

			case START: if(isLetter(c)) {				
							
							state = INID;
							str += c;
						} else if(isDigit(c)) {				
				
							state = INNUM;
							str += c;
						} else if(c == '\t' || c == ' ') {
							
						} else if(c == '\n') {
						
							//output the line number
							lineno = lineno + 1;
							outf << "-------------------------------------------" << endl;
							outf << "In the line " << lineno << " : " <<endl; 
						} else if(c == '/' && inf.peek() == '*') {
					
							str = str + c;
							c = inf.get();
							str = str + c;							
							state = INCOMMENT;
						} else {

							state = DONE;
							str += c;
							//judge is special symbols,if is not ,output UNKNOWN
							switch(c) {	
								case EOF: tt = ENDFILE;break;              
								case '+': tt = PLUS;break; 
								case '-': tt = MINUS;break;
								case '*': tt = MTPLUS;break;
								case '/': tt = DEVIDE;break;
								case ';': tt = FH;break;
								case '(': tt = LXKH;break;
								case ')': tt = RXKH;break;
								case '=': //judge if is '=='
									      if(inf.peek() == '=') {
							
											c = inf.get();
											tt = EQ; 
											str+=c;
										  //judge if is '='
										  } else {
									
											  tt = ASSIGN;
										  } break;										 
								case '<': //judge if is '<='
									      if(inf.peek() == '=') {

											 c = inf.get();
											 tt = LE;str+=c;
										  //judge if is '<'
										  } else {
											tt = LT;												
										  }break;
								case '>': //judge if is '>='
										  if(inf.peek() == '=') {
											 
											c = inf.get();
											 tt = ME;											 
											 str+=c;
										  //judge if is '>'
										  } else {									
											tt = MT;											
										  } break;
								case ',': tt = SEMI;break;								
								case '[': tt = LZKH;break;
								case ']': tt = RXKH;break;
								case '{': tt = LDKH;break;
								case '}': tt = RDKH;break;
								case '!': c = inf.get();										  
										  if(c == '=') {
											  
											tt = NOTEQ;
											str+=c;										  
										  } else {	
											  
											inf.putback(c);
											tt=UNKNOWN;																						
										  } break;
								default: tt = UNKNOWN;break;
							}
						} break;							
			case INCOMMENT: if(c=='\n')lineno=lineno+1;
							if(c == '*' && inf.peek() == '/') {	
								str = str + c;
								c = inf.get();								
								state = DONE;tt=ZS;							
							} else if(inf.eof()) { 
								tt = ERROR;
								state = DONE;
							} str = str + c;break;
							
			case INNUM:  if(!isDigit(c)) {
					   
							// if is letter,it is error
							if(isLetter(c)) {
								
								str = str + c;

								if(inf.peek() == ' ' || inf.peek() == '\t' || inf.peek() == '\n') {
								
									tt = ERROR;state = DONE;
									break;	
								}
							//else correct												
							} else {
								
								inf.putback(c);
								tt=NUM;
								state = DONE;								
							}	
							
							break;
						 } str += c;break;

			case INID: 	if(!isLetter(c)) {
						
							//if is digit, it is error
							if(isDigit(c)) {
								
								str = str + c;
								if(inf.peek() == ' ' || inf.peek() == '\t' || inf.peek() == '\n') {
									tt = ERROR;state = DONE;break;	
								}
							//else correct	
							} else {
								inf.putback(c);
								tt=ID;state = DONE;
							}						
							break;
					  }str += c;break;

			case DONE:break;

			default:					
				state = DONE;
				tt = ERROR;
				break;
		}		
	}
	
	// if is done output to the file the message.
	if(state == DONE){

		outputFile(outf,tt,str);
	}		
}

int main(int argc, char* argv[]) {

	char *filename = NULL;
	char *output = NULL;

	//check the parameter needed.
	if ( argc == 2 )
     
		filename = argv[1];
    else {
     
		cerr << "Usage: " << argv[0] << " [-n]  file" << endl;
        return EXIT_FAILURE;
    }
    
	ofstream outf("output.txt");
	ifstream inf(argv[1]);

	//if inf is error,output the error message.
	if ( !inf ) {
	
		cerr << "cannot open " << filename << " for input" << endl;
		return EXIT_FAILURE;
	}
	
	int lineno = 1;
	
	while(true){

		getToken(inf,outf,lineno);
	
		if(inf == NULL) {

			outf << "END OF FILE!" << endl;
			break;
		}
	}
	
	// file stream close
	inf.close();
	outf.close();
	return 0;
}
///:~

⌨️ 快捷键说明

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