token_kind.h 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef LEXER_TOKEN_KIND_H_
  5. #define LEXER_TOKEN_KIND_H_
  6. #include <cstdint>
  7. #include <iterator>
  8. #include "llvm/ADT/StringRef.h"
  9. namespace Carbon {
  10. class TokenKind {
  11. // Note that this must be declared earlier in the class so that its type can
  12. // be used, for example in the conversion operator.
  13. enum class KindEnum : int8_t {
  14. #define CARBON_TOKEN(TokenName) TokenName,
  15. #include "lexer/token_registry.def"
  16. };
  17. public:
  18. // The formatting for this macro is weird due to a `clang-format` bug. See
  19. // https://bugs.llvm.org/show_bug.cgi?id=48320 for details.
  20. #define CARBON_TOKEN(TokenName) \
  21. static constexpr auto TokenName()->TokenKind { \
  22. return TokenKind(KindEnum::TokenName); \
  23. }
  24. #include "lexer/token_registry.def"
  25. // The default constructor is deleted as objects of this type should always be
  26. // constructed using the above factory functions for each unique kind.
  27. TokenKind() = delete;
  28. friend auto operator==(TokenKind lhs, TokenKind rhs) -> bool {
  29. return lhs.kind_value == rhs.kind_value;
  30. }
  31. friend auto operator!=(TokenKind lhs, TokenKind rhs) -> bool {
  32. return lhs.kind_value != rhs.kind_value;
  33. }
  34. // Get a friendly name for the token for logging or debugging.
  35. [[nodiscard]] auto Name() const -> llvm::StringRef;
  36. // Test whether this kind of token is a simple symbol sequence (punctuation,
  37. // not letters) that appears directly in the source text and can be
  38. // unambiguously lexed with `starts_with` logic. While these may appear
  39. // inside of other tokens, outside of the contents of other tokens they
  40. // don't require any specific characters before or after to distinguish them
  41. // in the source. Returns false otherwise.
  42. [[nodiscard]] auto IsSymbol() const -> bool;
  43. // Test whether this kind of token is a grouping symbol (part of an opening
  44. // and closing pair that must always be matched in the token stream).
  45. [[nodiscard]] auto IsGroupingSymbol() const -> bool;
  46. // Test whether this kind of token is an opening symbol for a group.
  47. [[nodiscard]] auto IsOpeningSymbol() const -> bool;
  48. // Returns the associated closing symbol for an opening symbol.
  49. //
  50. // The token kind must be an opening symbol.
  51. [[nodiscard]] auto GetClosingSymbol() const -> TokenKind;
  52. // Test whether this kind of token is an closing symbol for a group.
  53. [[nodiscard]] auto IsClosingSymbol() const -> bool;
  54. // Returns the associated opening symbol for a closing symbol.
  55. //
  56. // The token kind must be an closing symbol.
  57. [[nodiscard]] auto GetOpeningSymbol() const -> TokenKind;
  58. // Test whether this kind of token is a keyword.
  59. [[nodiscard]] auto IsKeyword() const -> bool;
  60. // If this token kind has a fixed spelling when in source code, returns it.
  61. // Otherwise returns an empty string.
  62. [[nodiscard]] auto GetFixedSpelling() const -> llvm::StringRef;
  63. // Enable conversion to our private enum, including in a `constexpr` context,
  64. // to enable usage in `switch` and `case`. The enum remains private and
  65. // nothing else should be using this.
  66. // NOLINTNEXTLINE(google-explicit-constructor)
  67. constexpr operator KindEnum() const { return kind_value; }
  68. private:
  69. constexpr explicit TokenKind(KindEnum kind_value) : kind_value(kind_value) {}
  70. KindEnum kind_value;
  71. };
  72. } // namespace Carbon
  73. #endif // LEXER_TOKEN_KIND_H_