Token.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibXML/Forward.h>
  8. #include "AST/AST.h"
  9. #include "DiagnosticEngine.h"
  10. namespace JSSpecCompiler {
  11. constexpr i32 ambiguous_operator_precedence = -2;
  12. constexpr i32 pre_merged_operator_precedence = 2;
  13. constexpr i32 unary_operator_precedence = 3;
  14. constexpr i32 closing_bracket_precedence = 18;
  15. // NOTE: Operator precedence is generally the same as in
  16. // https://en.cppreference.com/w/cpp/language/operator_precedence (common sense applies).
  17. #define ENUMERATE_TOKENS(F) \
  18. F(Invalid, -1, Invalid, Invalid, Invalid, "") \
  19. F(AmbiguousMinus, -2, Invalid, Invalid, Invalid, "minus") \
  20. F(BinaryMinus, 6, Invalid, Minus, Invalid, "binary minus") \
  21. F(BraceClose, 18, Invalid, Invalid, BraceOpen, "'}'") \
  22. F(BraceOpen, -1, Invalid, Invalid, BraceClose, "'{'") \
  23. F(Colon, -1, Invalid, Invalid, Invalid, "':'") \
  24. F(Comma, 17, Invalid, Comma, Invalid, "','") \
  25. F(Division, 5, Invalid, Division, Invalid, "division") \
  26. F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'") \
  27. F(Enumerator, -1, Invalid, Invalid, Invalid, "enumerator") \
  28. F(Equals, 10, Invalid, CompareEqual, Invalid, "equals") \
  29. F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark") \
  30. F(Greater, 9, Invalid, CompareGreater, Invalid, "greater than") \
  31. F(Identifier, -1, Invalid, Invalid, Invalid, "identifier") \
  32. F(Is, -1, Invalid, Invalid, Invalid, "operator is") \
  33. F(Less, 9, Invalid, CompareLess, Invalid, "less than") \
  34. F(ListEnd, -1, Invalid, Invalid, Invalid, "»") \
  35. F(ListStart, -1, Invalid, Invalid, Invalid, "«") \
  36. F(MemberAccess, 2, Invalid, MemberAccess, Invalid, "member access operator '.'") \
  37. F(Multiplication, 5, Invalid, Multiplication, Invalid, "multiplication") \
  38. F(NotEquals, 10, Invalid, CompareNotEqual, Invalid, "not equals") \
  39. F(Number, -1, Invalid, Invalid, Invalid, "number") \
  40. F(ParenClose, 18, Invalid, Invalid, ParenOpen, "')'") \
  41. F(ParenOpen, -1, Invalid, Invalid, ParenClose, "'('") \
  42. F(Plus, 6, Invalid, Plus, Invalid, "plus") \
  43. F(QuestionMark, 3, ReturnIfAbrubt, Invalid, Invalid, "question mark") \
  44. F(SectionNumber, -1, Invalid, Invalid, Invalid, "section number") \
  45. F(SquareBracketClose, -1, Invalid, Invalid, Invalid, "']'") \
  46. F(SquareBracketOpen, -1, Invalid, Invalid, Invalid, "'['") \
  47. F(String, -1, Invalid, Invalid, Invalid, "string literal") \
  48. F(Superscript, 4, Invalid, Power, Invalid, "subscript") \
  49. F(UnaryMinus, 3, Minus, Invalid, Invalid, "unary minus") \
  50. F(WellKnownValue, -1, Invalid, Invalid, Invalid, "constant") \
  51. F(Word, -1, Invalid, Invalid, Invalid, "word")
  52. enum class TokenType {
  53. #define ID(name, precedence, unary_name, binary_name, matching_bracket, name_for_diagnostic) name,
  54. ENUMERATE_TOKENS(ID)
  55. #undef ID
  56. };
  57. constexpr struct TokenInfo {
  58. StringView name;
  59. i32 precedence;
  60. UnaryOperator as_unary_operator;
  61. BinaryOperator as_binary_operator;
  62. TokenType matching_bracket;
  63. StringView name_for_diagnostic;
  64. } token_info[] = {
  65. #define TOKEN_INFO(name, precedence, unary_name, binary_name, matching_bracket, name_for_diagnostic) \
  66. { \
  67. #name##sv, \
  68. precedence, \
  69. UnaryOperator::unary_name, \
  70. BinaryOperator::binary_name, \
  71. TokenType::matching_bracket, \
  72. name_for_diagnostic##sv \
  73. },
  74. ENUMERATE_TOKENS(TOKEN_INFO)
  75. #undef TOKEN_INFO
  76. };
  77. struct Token {
  78. TokenInfo const& info() const { return token_info[to_underlying(type)]; }
  79. StringView name() const { return info().name; }
  80. StringView name_for_diagnostic() const { return info().name_for_diagnostic; }
  81. i32 precedence() const { return info().precedence; }
  82. bool is_operator() const { return precedence() > 0 && precedence() < closing_bracket_precedence; }
  83. bool is_ambiguous_operator() const { return precedence() == ambiguous_operator_precedence; }
  84. bool is_pre_merged_binary_operator() const { return precedence() == pre_merged_operator_precedence; }
  85. bool is_unary_operator() const { return precedence() == unary_operator_precedence; }
  86. bool is_binary_operator() const { return is_operator() && !is_unary_operator(); }
  87. bool is_bracket() const { return info().matching_bracket != TokenType::Invalid; }
  88. bool is_opening_bracket() const { return is_bracket() && precedence() == -1; }
  89. bool is_closing_bracket() const { return is_bracket() && precedence() == closing_bracket_precedence; }
  90. UnaryOperator as_unary_operator() const
  91. {
  92. VERIFY(is_unary_operator());
  93. return info().as_unary_operator;
  94. }
  95. BinaryOperator as_binary_operator() const
  96. {
  97. VERIFY(is_binary_operator());
  98. return info().as_binary_operator;
  99. }
  100. bool matches_with(Token const& bracket)
  101. {
  102. VERIFY(is_bracket());
  103. return info().matching_bracket == bracket.type;
  104. }
  105. TokenType type;
  106. StringView data;
  107. Location location;
  108. };
  109. }