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

📄 parser.cpp

📁 C-MINUS编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			scan->add_err();
			outputMsg(scan->lineno(), "Syntax error: missing \'}\' before file end");
			scan->push();
			break;
		}

		switch (cToken.type){
			case k_READ:
				temp = read_stmt();	
				break;
			case k_WRITE:
				temp = write_stmt();
				break;
			case SEMI:	//;
			case k_NUM:
			case LPARAN:
				// cout << "k_NUM, LPARAN, expression_stmt()" <<endl; // debug
				temp = expression_stmt();	
				break;
			case k_ID:
				// cout << "k_ID, subcompound_stmt()"<<endl;
				temp = subcompound_stmt();	
				break;
			case k_IF:
				temp = if_stmt();	
				break;
			case k_WHILE:
				temp = while_stmt();
				break;
			case k_RETURN:
				temp = return_stmt();		
				break;
			case k_ELSE:
				scan->add_err();
				outputMsg(scan->lineno(), " unpaired \'else\' statement");
				consumeUntil(SEMI, RBRACE);
				break;
			default:
				scan->add_err();
				sprintf(msg_temp, "Syntax error: undefined symbol \"%s\"", cToken.str.c_str());
				outputMsg(scan->lineno(), msg_temp);
				consumeUntil(SEMI, RBRACE);
				break;
		}

		if (noBraces)	return temp;	// no braces
		if (temp)
		{
			if (!first)
			{
				first = temp;
				last = temp->LastSibling();
			}
			else
			{
				last->sibling = temp;
				last = temp->LastSibling();
			}

		}

		cToken = scan->nextToken();
	}

	return first;
}


/**:  11. local-declarations→ local-declarations var-declaration | empty
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::local_declarations()
{
	TreeNode *temp = NULL;

	iToken = cToken = scan->nextToken();
	if (iToken.type != k_ID)
	{
		scan->add_err();
		sprintf(msg_temp, "\"%s\" is a reserved token", iToken.str.c_str());
		outputMsg(scan->lineno(), msg_temp);
		consumeUntil(SEMI);
		return NULL;
	}

	cToken = scan->nextToken();	// ';', '[', ','
	if (cToken.type == SEMI || cToken.type == LSQUARE
		|| cToken.type == COMMA)
	{
		temp = var_declaration();
	}
	else
	{
		scan->add_err();
		sprintf(msg_temp, "missing \';\' after indentifier \"%s\"", iToken.str.c_str());
		outputMsg(scan->lineno(), msg_temp);
		scan->push();
	}

	return temp;
}

/**:  12. statement-list → statement-list statement | empty
&
* author:	lonelyforest
* data:		2006.03.30
*/ 

/**: 13. statement → expression-stmt | compound-stmt | selection-stmt
&                                     | iteration-stmt | return-stmt 
*
* author:	lonelyforest
* data:		2006.03.30
*/   

/**:  14. expression-stmt --> expression; | ;
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::expression_stmt()
{// cToken == ( / k_ID / k_NUM / ;
	//cout <<"expressino_stmt()"<<endl;	// use debug 
	if (cToken.type == SEMI)	return NULL;
	TreeNode* temp = expression();
	if (!match(SEMI))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \';\'");
		scan->push();
	}

	return temp;
}

/**: 15. selection-stmt → if (expression ) s tatement
&                        | if ( expression ) statement else statement 
*
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::if_stmt()
{
	TreeNode* temp = newStmtNode(ifK, cToken.str);
	TreeNode* p = NULL;

	if (!match(LPARAN))
	{ // if (
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"if\" statement");
	}
	else
	{
		cToken = scan->nextToken();
	}

	temp->child[0] = expression();
	if (temp->child[0]) temp->child[0]->father = temp;
	if (!match(RPARAN))
	{	// if ( )
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \')\' in if statement");
		scan->push();
	}

	p = temp->child[1] = compound_stmt();
	if (p) p->father = temp;
	while (p && p->sibling )
	{
		p = p->sibling ;
		p->father = temp;
	}

	cToken = scan->nextToken();
	if (cToken.type == k_ELSE)
	{
		p = temp->child[2] = compound_stmt();
		if (p) p->father = temp;
		while (p && p->sibling)
		{
			p = p->sibling;
			p->father = temp;
		}
	}
	else
	{	// if has no 'else' statement, push the next token back
		scan->push();
	}

	return temp;
}

/**:  16. iteration-stmt → while ( expression ) statement
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::while_stmt()
{	// current token is "while"
	TreeNode* temp = newStmtNode( whileK, cToken.str);
	TreeNode* p = NULL;

	if (!match(LPARAN))
	{	// while (
		scan->add_err();	// add error count,
		// out put the error message
		outputMsg(scan->lineno(), "Syntax error: missing \'(\' in \"while\" statement");
	}
	else
	{
		cToken = scan->nextToken();
	}

	// cToken should be the first token of expression now ...
	temp->child[0] = expression();
	if (temp->child[0]) temp->child[0]->father = temp;
	if (!match(RPARAN))
	{	// while ( )
		scan->add_err();	// record the parser error into class Scanner ...
		outputMsg(scan->lineno(), "Syntax error: missing \')\' in \"while\" statement");
		scan->push();
	}

	p = temp->child[1] = compound_stmt();
	if (p) p->father = temp;
	while (p && p->sibling )
	{
		p = p->sibling ;
		p->father = temp;
	}

	return temp;
}

/**:  17. return-stmt → return; | return expression;
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::return_stmt()
{	// cToken.str == "return"
	TreeNode* temp = newStmtNode(returnK, cToken.str);
	cToken = scan->nextToken();

	if (cToken.type != SEMI)
	{
		temp->child[0] = expression();
		if (!match(SEMI))
		{
			scan->add_err();
			outputMsg(scan->lineno(), "Syntax error: missing \';\' in \"return\" stamtement");
			scan->push();
		}
	}

	return temp;
}


/**:  18. expression → var = expression | simple-expression
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::expression()
{	// cToken == (, k_ID, k_NUM
	TreeNode* temp = simple_expression();
	TreeNode* p = temp;			// 曾今忘记赋值, 使我的语法树没有了许多的节点!!=_=

	cToken = scan->nextToken();
	// cout << "expression()"<<endl;
	if (cToken.type == ASSIGN)
	{
		if (temp->type != k_ID && temp->type != ASSIGN)
		{
			scan->add_err();
			outputMsg(scan->lineno(), "Syntax error: left of \'=\' should be a ID");
			consumeUntil(SEMI, RPARAN);
			delete temp;
			return NULL;
		}

		p = newExpNode(OpK, cToken.type, cToken.str);
		p->child[0] = temp;
		if (p->child[0])	p->child[0]->father = p;
		cToken = scan->nextToken();
		p->child[1] = expression();
		if (p->child[1])	p->child[1]->father = p;
	}
	else
	{
		scan->push();
	}

	return p;
}


/**:  19. var → ID | ID [ expression ]
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::var()
{
	TreeNode* temp = newExpNode(IDK, iToken.type, iToken.str);
	cToken = scan->nextToken();	// "["

	if (cToken.type == LSQUARE)
	{
		temp->bArr = true;
		cToken = scan->nextToken();
		temp->child[0] = expression();

		if (!match(RSQUARE))
		{
			scan->add_err();
			outputMsg(scan->lineno(), "Syntax error: missing \']\'");
			scan->push();
		}
	}
	else	
	{
		scan->push();
	}

	return temp;
}

/**:  20. simple-expression → additive-expression relop additive-expression
&                                            |additive-expression
&	  21. relop →<= | < | > | >= | == | !=
*
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::simple_expression()
{
	TreeNode* p = additive_expression();

	// cout << "simple_expression()"<<endl;
	cToken = scan->nextToken();
	if (cToken.type == NGT || cToken.type == LT ||
		cToken.type == GT  || cToken.type == NLT
		|| cToken.type == EQ || cToken.type == NEQ)
	{
		TreeNode *temp = newExpNode(OpK, cToken.type, cToken.str);
		temp->child[0] = p;
		p = temp;
		if (p->child[0]) p->child[0]->father = p;

		cToken = scan->nextToken();

        p->child[1] = additive_expression();
		if (p->child[1])
			p->child[1]->father = p;
	}
	else
	{
		scan->push();
	}

	return p;
}

/**:  22. additive-expression → additive-expression addop term | term
&	  23. addop →+ | -
*
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::additive_expression()
{
	TreeNode *p = term();

	cToken = scan->nextToken();
	while (cToken.type == PLUS  || cToken.type == MINUS)
	{
		TreeNode *temp = newExpNode( OpK, cToken.type, cToken.str);
		temp->child[0] = p;
		p = temp;
		if (p->child[0]) p->child[0]->father = p;

		cToken = scan->nextToken();
        p->child[1] = term();
		if (p->child[1]!= NULL)
		{
			p->child[1]->father = p;
		}

		cToken = scan->nextToken();
	}

	scan->push();

	return p;
}


/**:  24. term → term mulop factor | factor
&	 25. mulop →* | /
*
* author:	lonelyforest
* data:		2006.03.30
*/
TreeNode* Parser::term()
{
	TreeNode *p = factor();

	cToken = scan->nextToken();
	while (cToken.type == TIMES || cToken.type == DIV
		|| cToken.type == MOD)
	{
		TreeNode *temp = newExpNode(OpK, cToken.type, cToken.str);
		temp->child[0] = p;
		p = temp;
		if (p->child[0]) p->child[0]->father = p;

		cToken = scan->nextToken();
        p->child[1] = factor();
		if (p->child[1] != NULL) p->child[1]->father = p;
		cToken = scan->nextToken();
	}

	scan->push();

	return p;
}

/**:  26. factor → ( expression ) | var | call | NUM
&
* author:	lonelyforest
* data:		2006.03.30
*/
TreeNode* Parser::factor()
{
	TreeNode* temp = NULL;
	switch (cToken.type ){
		case k_NUM:
			temp = newExpNode(ConstK, cToken.type, cToken.str);
			break;
		case k_ID:
			iToken = cToken;
			cToken = scan->nextToken();
			if (cToken.type == LPARAN)	temp = call();
			else {
				scan->push();
				temp = var();
			}
			break;
		case LPARAN:
			cToken = scan->nextToken();
			temp = expression();
			if (!match(RPARAN))
			{
				scan->add_err();
				outputMsg(scan->lineno(), "Syntax Error: missing \')\'");
				scan->push();
			}
			break;
		default:
			scan->add_err();
			sprintf(msg_temp, "Syntax error: \'%s\' expression is unexpected!", cToken.str.c_str());
			outputMsg(scan->lineno(), msg_temp);
			consumeUntil(SEMI, RBRACE);
	}

	return temp;
}


/**: 27. call → ID ( args )
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::call()
{
	TreeNode* p = newStmtNode(callK, iToken.str);
	TreeNode* temp = NULL;
	p->scope = "global";

    p->child[0] = args();
	if (p->child[0])
	{
		p->child[0]->father = p;
	}

	temp = p->child[0];
	while (temp && temp->sibling)
	{
		temp = temp->sibling;
		temp->father = p;
	}

	if (!match(RPARAN))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \')\'");
		scan->push();
	}

	return p;
}


/**: 28. args → arg-list | empty
&	29. arg-list → arg-list , expression | expression
*
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::args()
{
	TreeNode *first = NULL,
		*temp = NULL;
	cToken = scan->nextToken();
	if (cToken.type == RPARAN)
	{	// ()
		scan->push();
		return NULL;
	}

	while (true)
	{
		if ((temp=expression()) != NULL)
		{
			if (!first)	first = temp;
			else
			{
				temp->sibling = first;
				first = temp;
			}
		}

		cToken = scan->nextToken();
		if (cToken.type == COMMA)
		{
			cToken = scan->nextToken();
		}
		else
		{
			break;
		}
	}

	scan->push();
	return first;
}

/**: 30. read → read( int ); 
&
* author:	lonelyforest
* data:		2006.03.30
*/
TreeNode* Parser::read_stmt()
{// currentToken.str == "read"
	TreeNode* temp = NULL;

	if (!match(LPARAN))
	{
		scan->add_err();
		outputMsg(scan->lineno(),"Syntax error: missing \'(\'");
		consumeUntil(SEMI, RBRACE);
		return NULL;
	}

	iToken = cToken = scan->nextToken();
	if (cToken.type != k_ID)
	{
		scan->add_err();
		sprintf(msg_temp, "\"%s\" is a bad argument", cToken.str.c_str());
		outputMsg(scan->lineno(), msg_temp);
		consumeUntil(SEMI, RBRACE);
		return NULL;
	}

	temp = newStmtNode(readK, "read");
	if ((temp->child[0] = var()) != NULL)
	{
		temp->child[0]->father = temp;
	}

	if (!match(RPARAN))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \')\'");
		consumeUntil(SEMI, RBRACE);
		return temp;
	}

	if (!match(SEMI))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \';\'");
		scan->push();
	}

	return temp;
}

/**: 31. write → write( int );
&
* author:	lonelyforest
* data:		2006.03.30
*/
TreeNode* Parser::write_stmt()
{// cToken.str == "write"
	TreeNode* temp = NULL;
	if (!match(LPARAN))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \')\'");
		consumeUntil(SEMI, RBRACE);
		return NULL;
	}

	temp = newStmtNode(writeK, "write");
	cToken = scan->nextToken();
	if ((temp->child[0] = expression()) != NULL)
	{
		temp->child[0]->father = temp;
	}

	if (!match(RPARAN))
	{	// "}"
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax Error: missing \')\'");
		consumeUntil(SEMI, RBRACE);
		return temp;
	}

	if (!match(SEMI))
	{
		scan->add_err();
		outputMsg(scan->lineno(), "Syntax error: missing \';\'");
		scan->push();
	}

	return temp;
}

//
/**: sub_compoundstmt → ID; | call; | expression_stmt
&
* author:	lonelyforest
* data:		2006.03.31
*/
TreeNode* Parser::subcompound_stmt()
{
	TreeNode* temp = NULL;

	// cout << "Subcompound_stmt()" <<endl;
	iToken = cToken;
	cToken = scan->nextToken();
	if (cToken.type == LPARAN)
	{	// call statement
		temp = call();
		if (!match(SEMI)){
			scan->add_err();
			outputMsg(scan->lineno(), "Syntax error: missing \';\' after fun call");
			scan->push();
		}
	}
	else
	{
		scan->push();
		cToken = iToken;
		temp = expression_stmt();
	}

	return temp;
}

⌨️ 快捷键说明

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