Exemplo n.º 1
0
bool Parser::TryParseType(std::string& aOutType)
{
	if (m_lexer.NextToken().id != Lexer::TOK_IDENTIFIER)
		return false;
	aOutType = m_lexer.currTok.strId;
	if (!IsTypeName(aOutType))
		return false;
	if (aOutType == "const" || aOutType == "unsigned" || aOutType == "signed") {
		std::string properType = "";
		if (!TryParseType(properType))
			return false;
		aOutType += " " + properType;
		return true;
	}
	if (m_lexer.PeekToken().id == '<')
	{
		m_lexer.NextToken();
		// we have a complicated type to deal with. (like std::map<std::string, std::vector<T>>)
		aOutType += '<';
		do {
			std::string innerType = "";
			bool gotInnerType = TryParseType(innerType);
			// a syntax error occured
			if (!gotInnerType)
				return false;
			aOutType += innerType;
			m_lexer.NextToken();
			if (m_lexer.currTok.id == ',' || m_lexer.currTok.id == '>')
				aOutType += m_lexer.currTok.id;
			else
				return false; // a syntax error ocurred
		} while (m_lexer.currTok.id == ',' && m_lexer.currTok.id != '>' && m_lexer.currTok.id != Lexer::TOK_EOF);
		if (m_lexer.currTok.id == Lexer::TOK_EOF)
			return false; // syntax error
		if (m_lexer.PeekToken().id == ':')
		{
			m_lexer.NextToken();
			if (m_lexer.PeekToken().id == ':') {
				m_lexer.NextToken();
				std::string additionalType = "";
				if (TryParseType(additionalType))
					aOutType += "::" + additionalType;
				else
					return false;
			}
			else {
				return false; // syntax error
			}
		}
	}
	Lexer::Token peekToken = m_lexer.PeekToken();
	while (peekToken.id == '&' || peekToken.id == '*') {
		m_lexer.NextToken();
		aOutType += m_lexer.currTok.id;
		peekToken = m_lexer.PeekToken();
	}
	return true;
}
Exemplo n.º 2
0
Arquivo: expr.c Projeto: M-ike/work
/**
 *  unary-expression:
 *		postfix-expression
 *		unary-operator unary-expression
 *		( type-name ) unary-expression
 *		sizeof unary-expression
 *		sizeof ( type-name )
 *
 *  unary-operator:
 *		++ -- & * + - ! ~
 */
static AstExpression ParseUnaryExpression()
{
	AstExpression expr;
	int t;

	switch (CurrentToken)
	{
	case TK_INC:
	case TK_DEC:
	case TK_BITAND:
	case TK_MUL:
	case TK_ADD:
	case TK_SUB:
	case TK_NOT:
	case TK_COMP:

		CREATE_AST_NODE(expr, Expression);

		expr->op = UNARY_OP;
		NEXT_TOKEN;
		expr->kids[0] = ParseUnaryExpression();

		return expr;

	case TK_LPAREN:

		/// When current token is (, it may be a type cast expression
		/// or a primary expression, we need to look ahead one token,
		/// if next token is type name, the expression is treated as
		/// a type cast expression; otherwise a primary expresion
		BeginPeekToken();
		t = GetNextToken();
		if (IsTypeName(t))
		{
			EndPeekToken();

			CREATE_AST_NODE(expr, Expression);

			expr->op = OP_CAST;
			NEXT_TOKEN;
			expr->kids[0] =  (AstExpression)ParseTypeName();
			Expect(TK_RPAREN);
			expr->kids[1] = ParseUnaryExpression();

			return expr;
		}
		else
		{
			EndPeekToken();
			return ParsePostfixExpression();
		}
		break;

	case TK_SIZEOF:

		/// this case hase the same issue with TK_LPAREN case
		CREATE_AST_NODE(expr, Expression);

		expr->op = OP_SIZEOF;
		NEXT_TOKEN;
		if (CurrentToken == TK_LPAREN)
		{
			BeginPeekToken();
			t = GetNextToken();
			if (IsTypeName(t))
			{
				EndPeekToken();

				NEXT_TOKEN;
				/// In this case, the first kid is not an expression,
				/// but thanks to both type name and expression have a 
				/// kind member to discriminate them.
				expr->kids[0] = (AstExpression)ParseTypeName();
				Expect(TK_RPAREN);
			}
			else
			{
				EndPeekToken();
				expr->kids[0] = ParseUnaryExpression();
			}
		}
		else
		{
			expr->kids[0] = ParseUnaryExpression();
		}

		return expr;

	default:
		return ParsePostfixExpression();
	}
}