token_kind.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 CARBON_TOOLCHAIN_LEXER_TOKEN_KIND_H_
  5. #define CARBON_TOOLCHAIN_LEXER_TOKEN_KIND_H_
  6. #include <cstdint>
  7. #include "common/enum_base.h"
  8. #include "llvm/Support/FormatVariadicDetails.h"
  9. namespace Carbon {
  10. CARBON_DEFINE_RAW_ENUM_CLASS(TokenKind, uint8_t) {
  11. #define CARBON_TOKEN(TokenName) CARBON_RAW_ENUM_ENUMERATOR(TokenName)
  12. #include "toolchain/lexer/token_kind.def"
  13. };
  14. class TokenKind : public CARBON_ENUM_BASE(TokenKind) {
  15. public:
  16. #define CARBON_TOKEN(TokenName) CARBON_ENUM_CONSTANT_DECLARATION(TokenName)
  17. #include "toolchain/lexer/token_kind.def"
  18. // Test whether this kind of token is a simple symbol sequence (punctuation,
  19. // not letters) that appears directly in the source text and can be
  20. // unambiguously lexed with `starts_with` logic. While these may appear
  21. // inside of other tokens, outside of the contents of other tokens they
  22. // don't require any specific characters before or after to distinguish them
  23. // in the source. Returns false otherwise.
  24. [[nodiscard]] auto is_symbol() const -> bool;
  25. // Test whether this kind of token is a grouping symbol (part of an opening
  26. // and closing pair that must always be matched in the token stream).
  27. [[nodiscard]] auto is_grouping_symbol() const -> bool;
  28. // Test whether this kind of token is an opening symbol for a group.
  29. [[nodiscard]] auto is_opening_symbol() const -> bool;
  30. // Returns the associated closing symbol for an opening symbol.
  31. //
  32. // The token kind must be an opening symbol.
  33. [[nodiscard]] auto closing_symbol() const -> TokenKind;
  34. // Test whether this kind of token is a closing symbol for a group.
  35. [[nodiscard]] auto is_closing_symbol() const -> bool;
  36. // Returns the associated opening symbol for a closing symbol.
  37. //
  38. // The token kind must be a closing symbol.
  39. [[nodiscard]] auto opening_symbol() const -> TokenKind;
  40. // Test whether this kind of token is a keyword.
  41. [[nodiscard]] auto is_keyword() const -> bool;
  42. // Test whether this kind of token is a sized type literal.
  43. [[nodiscard]] auto is_sized_type_literal() const -> bool;
  44. // If this token kind has a fixed spelling when in source code, returns it.
  45. // Otherwise returns an empty string.
  46. [[nodiscard]] auto fixed_spelling() const -> llvm::StringRef;
  47. // Test whether this token kind is in the provided list.
  48. [[nodiscard]] auto IsOneOf(std::initializer_list<TokenKind> kinds) const
  49. -> bool {
  50. for (TokenKind kind : kinds) {
  51. if (*this == kind) {
  52. return true;
  53. }
  54. }
  55. return false;
  56. }
  57. };
  58. #define CARBON_TOKEN(TokenName) \
  59. CARBON_ENUM_CONSTANT_DEFINITION(TokenKind, TokenName)
  60. #include "toolchain/lexer/token_kind.def"
  61. } // namespace Carbon
  62. namespace llvm {
  63. // We use formatv primarily for diagnostics. In these cases, it's expected that
  64. // the spelling in source code should be used.
  65. template <>
  66. struct format_provider<Carbon::TokenKind> {
  67. static void format(const Carbon::TokenKind& kind, raw_ostream& out,
  68. StringRef /*style*/) {
  69. auto spelling = kind.fixed_spelling();
  70. if (!spelling.empty()) {
  71. out << spelling;
  72. } else {
  73. // Default to the name if there's no fixed spelling.
  74. out << kind;
  75. }
  76. }
  77. };
  78. } // namespace llvm
  79. #endif // CARBON_TOOLCHAIN_LEXER_TOKEN_KIND_H_