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

📄 yufa.cpp

📁 对已给语言文法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				if(c=='='){
					token.type = EQ;
					token.name = "==";
				}else{
					token.type = ASSIGN;
					token.name = "=";
					next = false;
				}
				state = DONE;
				break;
			case INLE:
				if(c=='='){
					token.type = LE;
					token.name = "<=";
				}else{
					token.type = LT;
					token.name = "<";
					next = false;
				}
				state = DONE;
				break;
			case INGE:
				if(c=='='){
					token.type = GE;
					token.name = ">=";
				}else{
					token.type = GT;
					token.name = ">";
					next = false;
				}
				state = DONE;
				break;
			case INID:
				if((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')){
					buf[bufindex++] = c;
				}else{
					state = DONE;
					next = false;
				}
				break;
			case INNUM:
				if(c>='0' && c<='9'){
					buf[bufindex++] = c;
				}else{
					state = DONE;
					next = false;
				}
				break;
			default:
				state = DONE;
				token.type = ERROR;
				token.name = "ERROR!";
				printf("Error! Because no state is define! This should never happen! \
						Current character is: %c\n", src[index]);
				break;
		}// end scanner state
		index ++;
	}// end while
	
	if(next==false){
		index --;
	}
	
	if(bufindex == TOKENBUFSIZE - 1){
		// OUT OF BUFFER! It should never happen.
		token.type = ERROR;
		token.name = "OUT OF BUFFER!";
	}
	
	if(bufindex!=0){
		buf[bufindex] = '\0';
		token.name = new char[bufindex];
		strcpy(token.name, buf);
		if(token.type==ID){	// looking for reserved word and set the right type
			keywordLookup(token);
		}
	}
	
	return token;
}


// looking for reserved word and set the right type
void keywordLookup(Token &token){
	for(int i=0;i<MAXRESERVED;i++){
		if(strcmp(token.name, ReservedWords[i].name)==0){
			token.type = ReservedWords[i].type;
			if(token.type == BEGIN)
				token.name = "{";
			if(token.type == END)
				token.name = "}";
			break;
		}
	}
}


void getSingleOperator(char c, Token &token){
	switch(c){
		case '{':
			token.type = BEGIN;
			token.name = "{";
			break;
		case '}':
			token.type = END;
			token.name = "}";
			break;
		case '+':
			token.type = PLUS;
			token.name = "+";
			break;
		case '-':
			token.type = MINUS;
			token.name = "-";
			break;
		case '*':
			token.type = MUL;
			token.name = "*";
			break;
		case '/':
			token.type = DIV;
			token.name = "/";
			break;
		case '#':
		case '\0':	// end of file
			token.type = LEXER_DONE;
			token.name = "FINISH";
			break;
		case '&':
			token.type = AND;
			token.name = "&";
			break;
		case '|':
			token.type = OR;
			token.name = "|";
			break;
		case ';':
			token.type = SEMI;
			token.name = ";";
			break;
		default:
			token.type = ERROR;
			token.name = "ERROR! Unknown character.";
			printf("Error occured when state=START! Current character is: %c\n", c);
			break;
	}
}





/**************************************************Parser*************/


#ifdef TRACE_DEBUG
	#define TRACE(FUNCTION) printf("%-16s token = %s\n", FUNCTION, currentToken.name);
#else
	#define TRACE(FUNCTION)
#endif





Parser::Parser(char* sourcefile){
	lexer = new Lexer(sourcefile);
}

Parser::Parser(){
}

Parser::~Parser(){
	delete lexer;
}

void Parser::setLexer(Lexer *srclexer){
	lexer = srclexer;
}


Token Parser::nextToken(){
	currentToken = lexer->nextToken();
	return currentToken;
}

void Parser::reset(){
	lexer->reset();
}

void Parser::printError(const char *error){	// private method
	printf("%s when token = '%s'\n", error, currentToken.name);
}

void Parser::printError(){	// public method
	if(lexer->isReady())
		printf("\n*** ERROR BEFORE: ***\n%s", lexer->getSrc()+lexer->getIndex());
	else
		printf("Lexer is not ready!\n");
}

/*==================================================================*/

SyntaxTree* Parser::parse(){
	SyntaxTree* tree = NULL;
	if(lexer->isReady()){
		currentToken = lexer->nextToken();
		tree = Statement();
	}else{
		printf("no ready\n");
	}
	return tree;
}


SyntaxTree* Parser::Statement(){
	TRACE("in Statement();");
	
	SyntaxTree *tree = NULL;
	
	switch(currentToken.type){
		case LEXER_DONE:
			tree = new SyntaxTree(LEXER_DONE);
			break;
		case ID:
			this->nextToken();
			tree = Assign();
			if(tree != NULL){
				tree->addLeft(ID);
			}
			break;
		case WHILE:
			this->nextToken();
			tree = While();
			break;
		case BEGIN:
			this->nextToken();
			tree = Block();
			if(currentToken.type != END){
				tree =  NULL;
				this->printError("ERROR! begin without end");
			}
			//this->nextToken();
			this->currentToken.type = SEMI;
			break;
		case IF:
			this->nextToken();
			tree = Condition();
			break;
		default:
			tree = NULL;
			break;
	}
	
	TRACE("out Statement();");
	return tree;
}


SyntaxTree* Parser::Assign(){
	TRACE("in Assign();");
	
	SyntaxTree *tree = NULL;

	if(currentToken.type == ASSIGN){
		this->nextToken();
		SyntaxTree *temptree = Expression();
		
		if(temptree != NULL){
			tree = new SyntaxTree(ASSIGN);
			tree->addRight(temptree);
		}
	}else{
		this->printError("ERROR! Assignment statement expects '=';");
		return NULL;
	}
	
	TRACE("out Assign();");
	return tree;
}


SyntaxTree* Parser::Expression(){
	TRACE("in Expression();");

	SyntaxTree *temp = NULL;
	SyntaxTree *tree = T();

	if(tree == NULL){
		return NULL;
	}
	
	while(currentToken.type == PLUS || currentToken.type == MINUS){
		temp = new SyntaxTree(currentToken.type);
		temp->addLeft(tree);
		tree = temp;
		this->nextToken();
		
		temp = T();
		if(temp != NULL){
			tree->addRight(temp);
		}else{
			this->printError("ERROR! Behind '+';");
			return NULL;
		}
	}
	
	return tree;
}


SyntaxTree* Parser::T(){
	SyntaxTree *temp = NULL;
	SyntaxTree *tree = F();
	
	if(tree == NULL){
		return NULL;
	}
	
	while(currentToken.type == MUL || currentToken.type == DIV){
		temp = new SyntaxTree(currentToken.type);
		temp->addLeft(tree);
		tree = temp;
		this->nextToken();
		
		temp = F();
		if(temp != NULL){
			tree->addRight(temp);
		}else{
			this->printError("ERROR in T();");
			return NULL;
		}
	}
	
	return tree;
}


SyntaxTree* Parser::F(){
	SyntaxTree *tree = NULL;
	
	if(currentToken.type == ID){
		tree = new SyntaxTree(ID);
	}else if(currentToken.type == NUM){
		tree = new SyntaxTree(NUM, atoi(currentToken.name));
	}else{
		this->printError("ERROR! in F();");
	}
	
	this->nextToken();
	
	return tree;
}

/*==================================================================*/

SyntaxTree* Parser::Boolean(){
	TRACE("in Boolean();");

	SyntaxTree *temp = NULL;
	SyntaxTree *tree = T2();

	if(tree == NULL){
		return NULL;
	}
	
	while(currentToken.type == OR){
		temp = new SyntaxTree(OR);
		temp->addLeft(tree);
		tree = temp;
		this->nextToken();
		
		temp = T2();
		if(temp != NULL){
			tree->addRight(temp);
		}else{
			this->printError("ERROR! behind OR;");
			return NULL;
		}
	}
	
	TRACE("out Boolean();");
	return tree;
}


SyntaxTree* Parser::T2(){
	SyntaxTree *temp = NULL;
	SyntaxTree *tree = F2();

	if(tree == NULL){
		return NULL;
	}
	
	while(currentToken.type == AND){
		temp = new SyntaxTree(AND);
		temp->addLeft(tree);
		tree = temp;
		this->nextToken();
		
		temp = F2();
		if(temp != NULL){
			tree->addRight(temp);
		}else{
			this->printError("ERROR! behind AND;");
			return NULL;
		}
	}
	
	return tree;
}


SyntaxTree* Parser::F2(){
	SyntaxTree *temp = NULL;
	SyntaxTree *tree = Expression();
	
	if(tree == NULL){
		return NULL;
	}
	
	switch(currentToken.type){
		case LT:
			temp = new SyntaxTree(LT);
			break;
		case GT:
			temp = new SyntaxTree(GT);
			break;
		case EQ:
			temp = new SyntaxTree(EQ);
			break;
		default :
			break;
	}
	
	if(temp != NULL){
		this->nextToken();
		temp->addLeft(tree);
		tree = temp;
		temp = Expression();
		if(temp != NULL){
			tree->addRight(temp);
		}else{
			this->printError("ERROR! Relation Operator needs Expression behind;");
			return NULL;
		}
	}

	return tree;
}

/*==================================================================*/

SyntaxTree* Parser::While(){
	TRACE("in While();");

	SyntaxTree *tree = new SyntaxTree(WHILE);
	SyntaxTree *temp = Boolean();
	
	if(temp == NULL){
		this->printError("ERROR! in While(); Condition NULL;");
		return NULL;
	}
	tree->addLeft(temp);
	
	if(currentToken.type != DO){
		this->printError("ERROR! in While(); token.type!=DO;");
		return NULL;
	}
	this->nextToken();
	temp = Statement();

	if(temp == NULL){
		this->printError("ERROR! in While(); DO empty;");
		return NULL;
	}
	tree->addRight(temp);
	
	TRACE("out While();");
	return tree;
}


/*==================================================================*/

SyntaxTree* Parser::Begin(){
	return Block();
}

/*
	L = S(;S)* | <empsilon>
*/
SyntaxTree* Parser::Block(){
	TRACE("in Block();");

	SyntaxTree *tree = Statement();
	SyntaxTree *temp = new SyntaxTree(BEGIN);
	
	if(tree == NULL){
		//this->printError("WARNNING! Don't accept empty block.");
		return NULL;
		/*
		while(currentToken.type == SEMI){
			this->nextToken();
		}
		return new SyntaxTree(BEGIN);
		*/
	}
	temp->addLeft(tree);
	tree = temp;
	
//	temp = L2();

	while(currentToken.type == SEMI){
		this->nextToken();
	}
	temp = Block();

	if(temp != NULL){	// it couldn't be
		if(temp->getLeft() != NULL)
			tree->addRight(temp);
	}
	
	TRACE("out Block();");

	if(tree == NULL)
		return NULL;
	if(tree->getRight() == NULL)
		return tree->getLeft();
	else
		return tree;
}


/*==================================================================*/


SyntaxTree* Parser::Condition(){
	TRACE("in Condition();");
	
	SyntaxTree *tree = new SyntaxTree(IF);
	SyntaxTree *temp = Boolean();
	SyntaxTree *temp2 = NULL;
	
	if(temp == NULL){
		this->printError("ERROR! if without a boolean statement.");
		return NULL;
	}
	tree->addLeft(temp);
	
	if(currentToken.type != THEN){
		this->printError("ERROR! if without then.");
		return NULL;
	}
	this->nextToken();
	temp = Statement();
	
	if(temp == NULL){
		this->printError("ERROR! then without a statement.");
		return NULL;
	}
	
	temp2 = new SyntaxTree(THEN);
	temp2->addLeft(temp);
	
	//temp2 = temp;
	
	this->nextToken();
	if(currentToken.type == ELSE){
		TRACE("ELSE");
		this->nextToken();
		//temp = new SyntaxTree(BEGIN);
		//temp->addLeft(temp2);
		//temp2 = temp;
		
		temp = Statement();
		if(temp == NULL){
			this->printError("ERROR! else without a statement.");
			return NULL;
		}
		temp2->addRight(temp);
	}
	
	tree->addRight(temp2);
	
	TRACE("out Condition();");
	return tree;
}











int main(int argc, char* argv[]){
	char *filename = "test.txt";
	char *fileout = "";
	FILE *fp = NULL;
	
	if(argc > 1){
		filename = argv[1];
	}
	
	if(argc > 2){
		fileout = argv[2];
		fp = fopen(fileout, "w");
	}
	
	Parser parser = Parser(filename);
	SyntaxTree *tree = parser.parse();

	if(tree!=NULL){
		printf("\n************= Tree =****************:\n");
		tree->display();
		if(fp != NULL) tree->display(fp);
	}else{
		parser.printError();
	}
	
	if(fp != NULL) fclose(fp);
	
	printf("\n");
	
	return 0;
}



⌨️ 快捷键说明

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