Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <map>
- #include <string>
- #include <variant>
- #include <cassert>
- #include <cassert>
- namespace TokenTools
- {
- enum class TokenGroup
- {
- KEYWORD,
- IDENTIFIER,
- NUMERIC_LITERAL,
- USER_LITERAL,
- CHARACTER_LITERAL,
- STRING_LITERAL,
- OPERATORS,
- PUNCTUATORS
- };
- enum class UniCharOperators
- {
- MEMBER_OBJECT_ACCESS = '.',
- ARRAY_SUBSCRIPT_LEFT = '[',
- ARRAY_SUBSCRIPT_RIGHT = ']',
- LEFT_PARANTHESIS = '(',
- RIGHT_PARANTHESIS = ')',
- DOUBLE_QUOUTE = '\"',
- SINGLE_QUOUTE = '\'',
- BINARY_NOT = '~',
- LOGICAL_NOT = '!',
- UNARY_NEGATION = 0,
- UNARY_PLUS = 1,
- ADDRESS_ACCESS = 2,
- DEREFERENCE = 3,
- MULTIPLICATION = 4,
- DIVISION = '/',
- MODULUS = '%',
- ADDITION = 5,
- SUBTRACTION = '-',
- LESS_THAN = '<',
- GREATER_THAN = '>',
- BITWISE_AND = '&',
- BITWISE_EXCLUSIVE_OR = '^',
- BITWISE_INCLUSIVE_OR = '|',
- TERNARY_LEFT = '?',
- TERNARY_RIGHT = ':',
- ASSIGNMENT = '=',
- COMMA = ',',
- // For ambiguous symbols (ie *, +, and -)
- STAR_SYMBOL = '*',
- PLUS_SIGN = '+',
- MINUS_SIGN = '-',
- AND_SIGN = '&'
- };
- enum class MultiCharOperators
- {
- SCOPE_RESOLUTION,
- MEMBER_ACCESS_POINTER,
- ARRAY_SUBSCRIPT,
- FUNCTION_CALL,
- POSTFIX_INCREMENT,
- POSTFIX_DECREMENT,
- TYPE_NAME,
- CONST_TYPE_CONERSION,
- DYNAMIC_TYPE_CONVERSION,
- REINTERPRETED_TYPE_CONVERSION,
- STATIC_TYPE_CONVERSION,
- SIZE_OF_OBJECT,
- PREFIX_INCREMENT,
- PREFIX_DECREMENT,
- CREATE_HEAP_OBJECT,
- DESTROY_HEAP_OBJECT,
- TYPE_CAST,
- MEMBER_ACCESS_OBJECT_DEREFERENCE,
- MEMBER_ACCESS_POINTER_DEREFERENCE,
- BINARY_LEFT_SHIFT,
- BINARY_RIGHT_SHIFT,
- LESS_THAN_OR_EQUAL_TO,
- GREATER_THAN_OR_EQUAL_TO,
- EQUALITY,
- INEQUALITY,
- LOGICAL_AND,
- LOGICAL_OR,
- TERNARY_OPERATOR,
- MULTIPLY_ASSIGNMENT,
- DIVISION_ASSIGNMENT,
- MODULUS_ASSIGNMENT,
- ADDITION_ASSIGNMENT,
- SUBTRACTION_ASSIGNMENT,
- LEFT_SHIFT_ASSIGNMENT,
- RIGHT_SHIFT_ASSIGNMENT,
- BITWISE_AND_ASSIGNMENT,
- BITWISE_INCLUSIVE_OR_ASSIGNMENT,
- BITWISE_EXCLUSIVE_OR_ASSIGNMENT,
- THROW_EXCEPTION,
- // UniCharacter Operators that have multi-character counterparts
- BINARY_NOT,
- LOGICAL_NOT,
- BITWISE_AND,
- BITWISE_EXCLUSIVE_OR,
- BITWISE_INCLUSIVE_OR,
- DOUBLE_QUOUTES,
- SINGLE_QUOUTES,
- // Generalized operator types to avoid duplicate keys
- PARANTHESIS,
- INCREMENT,
- DECREMENT
- };
- }
- using namespace TokenTools;
- namespace
- {
- std::map<std::string, MultiCharOperators> multiCharOperatorMappings{
- {"::", MultiCharOperators::SCOPE_RESOLUTION},
- {"->", MultiCharOperators::MEMBER_ACCESS_POINTER},
- {"[]", MultiCharOperators::ARRAY_SUBSCRIPT},
- {"()", MultiCharOperators::PARANTHESIS},
- {"++", MultiCharOperators::INCREMENT},
- {"--", MultiCharOperators::DECREMENT},
- {"typeid", MultiCharOperators::TYPE_NAME},
- {"const_cast", MultiCharOperators::CONST_TYPE_CONERSION},
- {"dynamic_cast", MultiCharOperators::DYNAMIC_TYPE_CONVERSION},
- {"reinterpret_cast", MultiCharOperators::REINTERPRETED_TYPE_CONVERSION},
- {"static_cast", MultiCharOperators::STATIC_TYPE_CONVERSION},
- {"sizeof", MultiCharOperators::SIZE_OF_OBJECT},
- {"compl", MultiCharOperators::BINARY_NOT},
- {"not", MultiCharOperators::LOGICAL_NOT},
- {"new", MultiCharOperators::CREATE_HEAP_OBJECT},
- {"delete", MultiCharOperators::DESTROY_HEAP_OBJECT},
- {".*", MultiCharOperators::MEMBER_ACCESS_OBJECT_DEREFERENCE},
- {"->*", MultiCharOperators::MEMBER_ACCESS_POINTER_DEREFERENCE},
- {">>", MultiCharOperators::BINARY_LEFT_SHIFT},
- {"<<", MultiCharOperators::BINARY_RIGHT_SHIFT},
- {"<=", MultiCharOperators::LESS_THAN_OR_EQUAL_TO},
- {">=", MultiCharOperators::GREATER_THAN_OR_EQUAL_TO},
- {"==", MultiCharOperators::EQUALITY},
- {"!=", MultiCharOperators::INEQUALITY},
- {"not_eq", MultiCharOperators::INEQUALITY},
- {"bitand", MultiCharOperators::BITWISE_AND},
- {"xor", MultiCharOperators::BITWISE_EXCLUSIVE_OR},
- {"bitor", MultiCharOperators::BITWISE_INCLUSIVE_OR},
- {"&&", MultiCharOperators::LOGICAL_AND},
- {"and", MultiCharOperators::LOGICAL_AND},
- {"||", MultiCharOperators::LOGICAL_OR},
- {"or", MultiCharOperators::LOGICAL_OR},
- {"?:", MultiCharOperators::TERNARY_OPERATOR},
- {"*=", MultiCharOperators::MULTIPLY_ASSIGNMENT},
- {"/=", MultiCharOperators::DIVISION_ASSIGNMENT},
- {"%=", MultiCharOperators::MODULUS_ASSIGNMENT},
- {"+=", MultiCharOperators::ADDITION_ASSIGNMENT},
- {"-=", MultiCharOperators::SUBTRACTION_ASSIGNMENT},
- {"<<=", MultiCharOperators::LEFT_SHIFT_ASSIGNMENT},
- {">>=", MultiCharOperators::RIGHT_SHIFT_ASSIGNMENT},
- {"&=", MultiCharOperators::BITWISE_AND_ASSIGNMENT},
- {"and_eq", MultiCharOperators::BITWISE_AND_ASSIGNMENT},
- {"|=", MultiCharOperators::BITWISE_INCLUSIVE_OR_ASSIGNMENT},
- {"or_eq", MultiCharOperators::BITWISE_INCLUSIVE_OR_ASSIGNMENT},
- {"^=", MultiCharOperators::BITWISE_EXCLUSIVE_OR_ASSIGNMENT},
- {"xor_eq", MultiCharOperators::BITWISE_EXCLUSIVE_OR_ASSIGNMENT},
- {"\"\"", MultiCharOperators::DOUBLE_QUOUTES},
- {"\'\'", MultiCharOperators::SINGLE_QUOUTES}
- };
- }
- class Token
- {
- public:
- Token() = default;
- Token(TokenGroup group, std::variant<char, std::string> contents, Token* previousToken = nullptr);
- // Returns the contents of the token
- std::string getContents();
- // Returns the token's group
- TokenGroup& getGroup();
- // Comparison operators for comparing token types
- bool operator==(const TokenGroup group) const
- {
- return mGroup == group;
- }
- bool operator!=(const TokenGroup group) const
- {
- return mGroup != group;
- }
- // Comparision operators for comparing operator type
- bool operator==(const UniCharOperators otherOperator)
- {
- assert(!mOperatorType.index() && "Cannot compare a single character operator to a multi-character operator!\n");
- return std::get<UniCharOperators>(mOperatorType) == otherOperator;
- }
- bool operator!=(const UniCharOperators otherOperator)
- {
- assert(!mOperatorType.index() && "Cannot compare a single character operator to a multi-character operator!\n");
- return std::get<UniCharOperators>(mOperatorType) != otherOperator;
- }
- bool operator==(const MultiCharOperators otherOperator)
- {
- assert(!mOperatorType.index() && "Cannot compare a multi-character operator to a single character operator!\n");
- return std::get<MultiCharOperators>(mOperatorType) == otherOperator;
- }
- bool operator!=(const MultiCharOperators otherOperator)
- {
- assert(!mOperatorType.index() && "Cannot compare a multi-character operator to a single character operator!\n");
- return std::get<MultiCharOperators>(mOperatorType) != otherOperator;
- }
- private:
- void resolveSingleCharTokenOperator(UniCharOperators operatorContents, Token* previousToken);
- void resolveSingleCharTokenPrecedence(UniCharOperators operatorContents);
- void resolveMultiCharTokenOperator(MultiCharOperators operatorContents, Token* previousToken);
- void resolveMultiCharTokenPrecedence(MultiCharOperators operatorContents);
- void calculateUniCharacter(UniCharOperators operatorContents, Token* previousToken);
- void calculateMultiCharacter(MultiCharOperators operatorContents, Token* previousToken);
- bool isMultiCharToken;
- int mPrecedenceGroup;
- TokenGroup mGroup;
- std::variant<char, std::string> mContents;
- std::variant<UniCharOperators, MultiCharOperators> mOperatorType;
- };
- #include "token.h"
- using namespace TokenTools;
- Token::Token(TokenGroup group, std::variant<char, std::string> contents, Token* previousToken) : mGroup(group), mContents(contents), mPrecedenceGroup(-1)
- {
- isMultiCharToken = mContents.index();
- if (isMultiCharToken)
- {
- mOperatorType = multiCharOperatorMappings[std::get<std::string>(mContents)];
- switch (std::get<MultiCharOperators>(mOperatorType))
- {
- case MultiCharOperators::INCREMENT: case MultiCharOperators::DECREMENT: case MultiCharOperators::PARANTHESIS:
- resolveMultiCharTokenOperator(std::get<MultiCharOperators>(mOperatorType), previousToken);
- break;
- default:
- break;
- }
- resolveMultiCharTokenPrecedence(std::get<MultiCharOperators>(mOperatorType));
- }
- else
- {
- mOperatorType = UniCharOperators{ std::get<char>(mContents) };
- switch (std::get<UniCharOperators>(mOperatorType))
- {
- case UniCharOperators::STAR_SYMBOL: case UniCharOperators::PLUS_SIGN: case UniCharOperators::MINUS_SIGN:
- case UniCharOperators::AND_SIGN:
- resolveSingleCharTokenOperator(std::get<UniCharOperators>(mOperatorType), previousToken);
- break;
- default:
- break;
- }
- resolveSingleCharTokenPrecedence(std::get<UniCharOperators>(mOperatorType));
- }
- }
- void Token::resolveSingleCharTokenOperator(UniCharOperators operatorContents, Token* previousToken)
- {
- using UCO = UniCharOperators;
- switch (operatorContents)
- {
- case UCO::STAR_SYMBOL:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = UCO::MULTIPLICATION;
- else
- mOperatorType = UCO::DEREFERENCE;
- }
- else
- mOperatorType = UCO::DEREFERENCE;
- break;
- case UCO::PLUS_SIGN:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = UCO::ADDITION;
- else
- mOperatorType = UCO::UNARY_PLUS;
- }
- else
- mOperatorType = UCO::UNARY_PLUS;
- break;
- case UCO::MINUS_SIGN:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = UCO::SUBTRACTION;
- else
- mOperatorType = UCO::UNARY_NEGATION;
- }
- else
- mOperatorType = UCO::UNARY_NEGATION;
- break;
- case UCO::AND_SIGN:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = UCO::BITWISE_AND;
- else
- mOperatorType = UCO::ADDRESS_ACCESS;
- }
- else
- mOperatorType = UCO::ADDRESS_ACCESS;
- break;
- default:
- break;
- }
- }
- void Token::resolveSingleCharTokenPrecedence(UniCharOperators operatorContents)
- {
- using UCO = UniCharOperators;
- switch (operatorContents)
- {
- case UCO::MEMBER_OBJECT_ACCESS:
- mPrecedenceGroup = 16;
- break;
- case UCO::BINARY_NOT: case UCO::LOGICAL_NOT: case UCO::UNARY_NEGATION: case UCO::UNARY_PLUS: case UCO::ADDRESS_ACCESS:
- case UCO::DEREFERENCE:
- mPrecedenceGroup = 15;
- break;
- case UCO::MULTIPLICATION: case UCO::DIVISION: case UCO::MODULUS:
- mPrecedenceGroup = 12;
- break;
- case UCO::ADDITION: case UCO::SUBTRACTION:
- mPrecedenceGroup = 11;
- break;
- case UCO::LESS_THAN: case UCO::GREATER_THAN:
- mPrecedenceGroup = 9;
- break;
- case UCO::BITWISE_AND:
- mPrecedenceGroup = 8;
- break;
- case UCO::BITWISE_EXCLUSIVE_OR:
- mPrecedenceGroup = 7;
- break;
- case UCO::BITWISE_INCLUSIVE_OR:
- mPrecedenceGroup = 6;
- break;
- case UCO::ASSIGNMENT:
- mPrecedenceGroup = 2;
- break;
- case UCO::COMMA:
- mPrecedenceGroup = 0;
- break;
- default:
- break;
- }
- }
- void Token::resolveMultiCharTokenOperator(MultiCharOperators operatorContents, Token* previousToken)
- {
- using MCO = MultiCharOperators;
- switch (operatorContents)
- {
- case MCO::INCREMENT:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = MCO::POSTFIX_INCREMENT;
- else
- mOperatorType = MCO::PREFIX_INCREMENT;
- }
- else
- mOperatorType = MCO::PREFIX_INCREMENT;
- break;
- case MCO::DECREMENT:
- if (previousToken != nullptr)
- {
- if (*previousToken == TokenGroup::NUMERIC_LITERAL || *previousToken == TokenGroup::USER_LITERAL ||
- *previousToken == TokenGroup::IDENTIFIER)
- mOperatorType = MCO::POSTFIX_DECREMENT;
- else
- mOperatorType = MCO::PREFIX_DECREMENT;
- }
- else
- mOperatorType = MCO::PREFIX_DECREMENT;
- break;
- case MCO::PARANTHESIS:
- if (previousToken != nullptr)
- {
- switch (previousToken->getGroup())
- {
- case TokenGroup::IDENTIFIER:
- mOperatorType = MCO::FUNCTION_CALL;
- break;
- case TokenGroup::KEYWORD:
- mOperatorType = MCO::TYPE_CAST;
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- void Token::resolveMultiCharTokenPrecedence(MultiCharOperators operatorContents)
- {
- using MCO = MultiCharOperators;
- switch (operatorContents)
- {
- case MCO::SCOPE_RESOLUTION:
- mPrecedenceGroup = 17;
- break;
- case MCO::MEMBER_ACCESS_POINTER: case MCO::ARRAY_SUBSCRIPT: case MCO::FUNCTION_CALL: case MCO::POSTFIX_INCREMENT:
- case MCO::POSTFIX_DECREMENT: case MCO::TYPE_NAME: case MCO::CONST_TYPE_CONERSION: case MCO::DYNAMIC_TYPE_CONVERSION:
- case MCO::REINTERPRETED_TYPE_CONVERSION: case MCO::STATIC_TYPE_CONVERSION:
- mPrecedenceGroup = 16;
- break;
- case MCO::SIZE_OF_OBJECT: case MCO::PREFIX_DECREMENT: case MCO::PREFIX_INCREMENT: case MCO::CREATE_HEAP_OBJECT:
- case MCO::DESTROY_HEAP_OBJECT: case MCO::TYPE_CAST:
- mPrecedenceGroup = 15;
- break;
- case MCO::MEMBER_ACCESS_POINTER_DEREFERENCE: case MCO::MEMBER_ACCESS_OBJECT_DEREFERENCE:
- mPrecedenceGroup = 14;
- break;
- case MCO::BINARY_LEFT_SHIFT: case MCO::BINARY_RIGHT_SHIFT:
- mPrecedenceGroup = 11;
- break;
- case MCO::GREATER_THAN_OR_EQUAL_TO: case MCO::LESS_THAN_OR_EQUAL_TO:
- mPrecedenceGroup = 10;
- break;
- case MCO::EQUALITY: case MCO::INEQUALITY:
- mPrecedenceGroup = 9;
- break;
- case MCO::LOGICAL_AND:
- mPrecedenceGroup = 5;
- break;
- case MCO::LOGICAL_OR:
- mPrecedenceGroup = 4;
- break;
- case MCO::TERNARY_OPERATOR:
- mPrecedenceGroup = 3;
- break;
- case MCO::MULTIPLY_ASSIGNMENT: case MCO::DIVISION_ASSIGNMENT: case MCO::MODULUS_ASSIGNMENT:
- case MCO::ADDITION_ASSIGNMENT: case MCO::SUBTRACTION_ASSIGNMENT: case MCO::LEFT_SHIFT_ASSIGNMENT:
- case MCO::RIGHT_SHIFT_ASSIGNMENT: case MCO::BITWISE_AND_ASSIGNMENT: case MCO::BITWISE_INCLUSIVE_OR_ASSIGNMENT:
- case MCO::BITWISE_EXCLUSIVE_OR_ASSIGNMENT:
- mPrecedenceGroup = 2;
- break;
- case MCO::THROW_EXCEPTION:
- mPrecedenceGroup = 1;
- break;
- default:
- break;
- }
- }
- std::string Token::getContents()
- {
- if (!mContents.index())
- return std::string{ std::get<char>(mContents) };
- else
- return std::get<std::string>(mContents);
- }
- TokenGroup& Token::getGroup()
- {
- return mGroup;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement