Token.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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(MemberAccess, 2, Invalid, MemberAccess, Invalid, "member access operator '.'") \
  35. F(Multiplication, 5, Invalid, Multiplication, Invalid, "multiplication") \
  36. F(NotEquals, 10, Invalid, CompareNotEqual, Invalid, "not equals") \
  37. F(Number, -1, Invalid, Invalid, Invalid, "number") \
  38. F(ParenClose, 18, Invalid, Invalid, ParenOpen, "')'") \
  39. F(ParenOpen, -1, Invalid, Invalid, ParenClose, "'('") \
  40. F(Plus, 6, Invalid, Plus, Invalid, "plus") \
  41. F(QuestionMark, 3, ReturnIfAbrubt, Invalid, Invalid, "question mark") \
  42. F(SectionNumber, -1, Invalid, Invalid, Invalid, "section number") \
  43. F(String, -1, Invalid, Invalid, Invalid, "string literal") \
  44. F(Superscript, 4, Invalid, Power, Invalid, "subscript") \
  45. F(UnaryMinus, 3, Minus, Invalid, Invalid, "unary minus") \
  46. F(WellKnownValue, -1, Invalid, Invalid, Invalid, "constant") \
  47. F(Word, -1, Invalid, Invalid, Invalid, "word")
  48. enum class TokenType {
  49. #define ID(name, precedence, unary_name, binary_name, matching_bracket, name_for_diagnostic) name,
  50. ENUMERATE_TOKENS(ID)
  51. #undef ID
  52. };
  53. constexpr struct TokenInfo {
  54. StringView name;
  55. i32 precedence;
  56. UnaryOperator as_unary_operator;
  57. BinaryOperator as_binary_operator;
  58. TokenType matching_bracket;
  59. StringView name_for_diagnostic;
  60. } token_info[] = {
  61. #define TOKEN_INFO(name, precedence, unary_name, binary_name, matching_bracket, name_for_diagnostic) \
  62. { \
  63. #name##sv, \
  64. precedence, \
  65. UnaryOperator::unary_name, \
  66. BinaryOperator::binary_name, \
  67. TokenType::matching_bracket, \
  68. name_for_diagnostic##sv \
  69. },
  70. ENUMERATE_TOKENS(TOKEN_INFO)
  71. #undef TOKEN_INFO
  72. };
  73. struct Token {
  74. TokenInfo const& info() const { return token_info[to_underlying(type)]; }
  75. StringView name() const { return info().name; }
  76. StringView name_for_diagnostic() const { return info().name_for_diagnostic; }
  77. i32 precedence() const { return info().precedence; }
  78. bool is_operator() const { return precedence() > 0 && precedence() < closing_bracket_precedence; }
  79. bool is_ambiguous_operator() const { return precedence() == ambiguous_operator_precedence; }
  80. bool is_pre_merged_binary_operator() const { return precedence() == pre_merged_operator_precedence; }
  81. bool is_unary_operator() const { return precedence() == unary_operator_precedence; }
  82. bool is_binary_operator() const { return is_operator() && !is_unary_operator(); }
  83. bool is_bracket() const { return info().matching_bracket != TokenType::Invalid; }
  84. bool is_opening_bracket() const { return is_bracket() && precedence() == -1; }
  85. bool is_closing_bracket() const { return is_bracket() && precedence() == closing_bracket_precedence; }
  86. UnaryOperator as_unary_operator() const
  87. {
  88. VERIFY(is_unary_operator());
  89. return info().as_unary_operator;
  90. }
  91. BinaryOperator as_binary_operator() const
  92. {
  93. VERIFY(is_binary_operator());
  94. return info().as_binary_operator;
  95. }
  96. bool matches_with(Token const& bracket)
  97. {
  98. VERIFY(is_bracket());
  99. return info().matching_bracket == bracket.type;
  100. }
  101. TokenType type;
  102. StringView data;
  103. Location location;
  104. };
  105. }