/
thomas-king
/
SyntacticAnalyzer
Обзор
Документация
Войти
/
thomas-king
/
SyntacticAnalyzer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
lib/Services/SyntacticAnalyzer.cpp
335 строк
8 KB
Ace Rodstin
Update tree parse end condition.
06 апр 2023, 13:53
06 апр 2023, 13:53
4f26776
Код
Авторство
О чём код?
// // SyntacticAnalyzer.cpp // SyntacticAnalyzer // // Created by Ace Rodstin on 3/7/23. // Copyright © 2023 Ace Rodstin. All rights reserved. // #include "Services/SyntacticAnalyzer.h" using namespace ace; using namespace ast; SyntacticAnalyzer::SyntacticAnalyzer(TokensParser& tokensParser) : tokensParser(tokensParser), token(tokensParser.next()) {} unique_ptr<Statement> SyntacticAnalyzer::parse() { auto tree = parseStatement(); if (!isToken(Token::Kind::endOfInput) || hasError) { return nullptr; } else { return std::move(tree); } } unique_ptr<Statement> SyntacticAnalyzer::parseStatement() { if (isToken(Keyword::val)) { auto declaration = parseDeclaration(); return make_unique<Statement>(std::move(declaration)); } else { hasError = true; return nullptr; } } unique_ptr<Declaration> SyntacticAnalyzer::parseDeclaration() { if (isToken(Keyword::val)) { auto constantDeclaration = parseConstantDeclaration(); return make_unique<Declaration>(std::move(constantDeclaration)); } else { hasError = true; return nullptr; } } unique_ptr<ConstantDeclaration> SyntacticAnalyzer::parseConstantDeclaration() { if (isToken(Keyword::val)) { advance(); auto constantSpecification = parseConstantSpecification(); return make_unique<ConstantDeclaration>(std::move(constantSpecification)); } else { hasError = true; return nullptr; } } unique_ptr<ConstantSpecification> SyntacticAnalyzer::parseConstantSpecification() { unique_ptr<IdentifierList> identifierList = parseIdentifierList(); unique_ptr<Type> type; unique_ptr<Expression> expression; if (isToken(Punctuator::colon)) { advance(); type = parseType(); } if (isToken(Operator::assign)) { advance(); expression = parseExpression(); } if (identifierList == nullptr) { hasError = true; return nullptr; } if (type == nullptr && expression == nullptr) { hasError = true; return nullptr; } else { return make_unique<ConstantSpecification>(std::move(identifierList), std::move(type), std::move(expression)); } } unique_ptr<IdentifierList> SyntacticAnalyzer::parseIdentifierList() { if (!isToken(Token::Kind::identifier)) { hasError = true; return nullptr; } vector<unique_ptr<Identifier>> identifiers; while (!isToken(Token::Kind::endOfInput)) { auto identifier = parseIdentifier(); identifiers.push_back(std::move(identifier)); if (isToken(Punctuator::comma)) { advance(); } else { break; } } return make_unique<IdentifierList>(std::move(identifiers)); } unique_ptr<Type> SyntacticAnalyzer::parseType() { auto typeName = parseTypeName(); return make_unique<Type>(std::move(typeName)); } unique_ptr<TypeName> SyntacticAnalyzer::parseTypeName() { auto identifier = parseIdentifier(); return make_unique<TypeName>(std::move(identifier)); } unique_ptr<Identifier> SyntacticAnalyzer::parseIdentifier() { if (!isToken(Token::Kind::identifier)) { hasError = true; return nullptr; } auto identifier = token.getIdentifier(); advance(); return make_unique<Identifier>(identifier); } unique_ptr<Expression> SyntacticAnalyzer::parseExpression() { auto unaryExpression = parseUnaryExpression(); if (isToken(Token::Kind::_operator)) { auto binaryOperator = parseBinaryOperator(); auto op = binaryOperator->getOperator(); auto operatorPecedence = getPrecedence(op); return parseBinaryExpression(std::move(unaryExpression), std::move(binaryOperator), operatorPecedence); } else { return std::move(unaryExpression); } } unique_ptr<BinaryExpression> SyntacticAnalyzer::parseBinaryExpression(unique_ptr<Expression> lhs, unique_ptr<ast::Operator> binaryOperator, Precedence operatorPrecedence) { auto rhs = parseUnaryExpression(); if (isToken(Token::Kind::_operator)) { auto nextBinaryOperator = parseBinaryOperator(); auto op = nextBinaryOperator->getOperator(); auto nextOperatorPecedence = getPrecedence(op); if (operatorPrecedence < nextOperatorPecedence) { auto right = parseBinaryExpression(std::move(rhs), std::move(nextBinaryOperator), nextOperatorPecedence); return make_unique<BinaryExpression>(std::move(lhs), std::move(binaryOperator), std::move(right)); } else { auto left = make_unique<BinaryExpression>(std::move(lhs), std::move(binaryOperator), std::move(rhs)); return parseBinaryExpression(std::move(left), std::move(nextBinaryOperator), nextOperatorPecedence); } } return make_unique<BinaryExpression>(std::move(lhs), std::move(binaryOperator), std::move(rhs)); } unique_ptr<UnaryExpression> SyntacticAnalyzer::parseUnaryExpression() { unique_ptr<ast::Operator> unaryOperator; if (isToken(Token::Kind::_operator)) { unaryOperator = parseUnaryOperator(); } auto primaryExpression = parsePrimaryExpression(); return make_unique<UnaryExpression>(std::move(unaryOperator), std::move(primaryExpression)); } unique_ptr<PrimaryExpression> SyntacticAnalyzer::parsePrimaryExpression() { auto operand = parseOperand(); return make_unique<PrimaryExpression>(std::move(operand)); } unique_ptr<ast::Operator> SyntacticAnalyzer::parseUnaryOperator() { if (!isToken(Token::Kind::_operator)) { hasError = true; return nullptr; } auto op = token.getOperator(); switch (op) { case Operator::plus: case Operator::minus: advance(); return make_unique<ast::Operator>(op); default: hasError = true; return nullptr; } } unique_ptr<ast::Operator> SyntacticAnalyzer::parseBinaryOperator() { if (!isToken(Token::Kind::_operator)) { hasError = true; return nullptr; } auto op = token.getOperator(); advance(); return make_unique<ast::Operator>(op); } unique_ptr<Operand> SyntacticAnalyzer::parseOperand() { if (isToken(Token::Kind::literal)) { auto literal = parseLiteral(); return make_unique<Operand>(std::move(literal)); } if (isToken(Punctuator::left_parenthesis)) { advance(); // Skip left parenthesis auto expression = parseExpression(); if (isToken(Punctuator::right_parenthesis)) { advance(); // Skip right parenthesis return make_unique<Operand>(std::move(expression)); } else { hasError = true; return nullptr; } } if (isToken(Token::Kind::identifier)) { auto operandName = parseOperandName(); return make_unique<Operand>(std::move(operandName)); } hasError = true; return nullptr; } unique_ptr<ast::Literal> SyntacticAnalyzer::parseLiteral() { if (!isToken(Token::Kind::literal)) { hasError = true; return nullptr; } auto literal = token.getLiteral(); auto kind = literal.getKind(); switch (kind) { case ace::Literal::Kind::integer: { auto _kind = ast::Literal::Kind::integer; auto value = literal.getValue(); auto numberBase = literal.getNumberBase(); advance(); return make_unique<ast::Literal>(_kind, value, numberBase); } case ace::Literal::Kind::_float: { auto _kind = ast::Literal::Kind::_float; auto value = literal.getValue(); auto numberBase = literal.getNumberBase(); advance(); return make_unique<ast::Literal>(_kind, value, numberBase); } default: hasError = true; return nullptr; } } unique_ptr<OperandName> SyntacticAnalyzer::parseOperandName() { auto identifier = parseIdentifier(); return make_unique<OperandName>(std::move(identifier)); } SyntacticAnalyzer::Precedence SyntacticAnalyzer::getPrecedence(Operator op) { switch (op) { case Operator::plus: case Operator::minus: return 2; case Operator::multiply: case Operator::divide: return 3; case Operator::assign: return 1; } } SyntacticAnalyzer::Precedence SyntacticAnalyzer::getPrecedence(Punctuator punctuator) { switch (punctuator) { case Punctuator::left_parenthesis: case Punctuator::right_parenthesis: return 1; default: return 0; } } SyntacticAnalyzer::Precedence SyntacticAnalyzer::getPrecedence(ace::Literal literal) { auto kind = literal.getKind(); switch (kind) { case Literal::Kind::integer: case Literal::Kind::_float: return 1; default: return 0; } } void SyntacticAnalyzer::advance() { token = tokensParser.next(); } bool SyntacticAnalyzer::isToken(Keyword keyword) { if (!isToken(Token::Kind::keyword)) { return false; } else { return token.getKeyword() == keyword; } } bool SyntacticAnalyzer::isToken(ace::Operator op) { if (!isToken(Token::Kind::_operator)) { return false; } else { return token.getOperator() == op; } } bool SyntacticAnalyzer::isToken(Punctuator punctuator) { if (!isToken(Token::Kind::punctuator)) { return false; } else { return token.getPunctuator() == punctuator; } } bool SyntacticAnalyzer::isToken(Token::Kind kind) { return token.getKind() == kind; }