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

📄 parser.cpp

📁 一个上课很好用的课件
💻 CPP
字号:
//#define TRACE_DEBUG
#ifdef TRACE_DEBUG
#define TRACE(FUNCTION) printf("%-16s token = %s\n", FUNCTION, currentToken.name);
#else
#define TRACE(FUNCTION)
#endif
#include "Parser.h"
#include <stdio.h>
#include <stdlib.h>
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){
	}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;");
		}
	}
	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;
}

⌨️ 快捷键说明

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