token_kind.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 <stdint.h>
  7. #include <iterator>
  8. #include "llvm/ADT/StringRef.h"
  9. namespace Carbon {
  10. class TokenKind {
  11. enum class KindEnum : int8_t {
  12. #define CARBON_TOKEN(TokenName) TokenName,
  13. #include "lexer/token_registry.def"
  14. };
  15. public:
  16. #define CARBON_TOKEN(TokenName) \
  17. static constexpr auto TokenName()->TokenKind { return KindEnum::TokenName; }
  18. #include "lexer/token_registry.def"
  19. // The default constructor is deleted as objects of this type should always be
  20. // constructed using the above factory functions for each unique kind.
  21. TokenKind() = delete;
  22. auto operator==(const TokenKind& rhs) const -> bool {
  23. return kind_value == rhs.kind_value;
  24. }
  25. auto operator!=(const TokenKind& rhs) const -> bool {
  26. return kind_value != rhs.kind_value;
  27. }
  28. // Get a friendly name for the token for logging or debugging.
  29. auto Name() const -> llvm::StringRef;
  30. // Test whether this kind of token is a simple symbol sequence (punctuation,
  31. // not letters) that appears directly in the source text and can be
  32. // unambiguously lexed with `starts_with` logic. While these may appear
  33. // inside of other tokens, outside of the contents of other tokens they
  34. // don't require any specific characters before or after to distinguish them
  35. // in the source. Returns false otherwise.
  36. auto IsSymbol() const -> bool;
  37. // Test whether this kind of token is a grouping symbol (part of an opening
  38. // and closing pair that must always be matched in the token stream).
  39. auto IsGroupingSymbol() const -> bool;
  40. // Test whether this kind of token is an opening symbol for a group.
  41. auto IsOpeningSymbol() const -> bool;
  42. // Returns the associated closing symbol for an opening symbol.
  43. //
  44. // The token kind must be an opening symbol.
  45. auto GetClosingSymbol() const -> TokenKind;
  46. // Test whether this kind of token is an closing symbol for a group.
  47. auto IsClosingSymbol() const -> bool;
  48. // Returns the associated opening symbol for a closing symbol.
  49. //
  50. // The token kind must be an closing symbol.
  51. auto GetOpeningSymbol() const -> TokenKind;
  52. // Test whether this kind of token is a keyword.
  53. auto IsKeyword() const -> bool;
  54. // If this token kind has a fixed spelling when in source code, returns it.
  55. // Otherwise returns an empty string.
  56. auto GetFixedSpelling() const -> llvm::StringRef;
  57. // Enable implicit conversion to an int, including in a `constexpr` context,
  58. // to enable usage in `switch` and `case`.
  59. constexpr operator int() const { return static_cast<int>(kind_value); }
  60. private:
  61. constexpr TokenKind(KindEnum kind_value) : kind_value(kind_value) {}
  62. KindEnum kind_value;
  63. };
  64. } // namespace Carbon
  65. #endif // LEXER_TOKEN_KIND_H_