parser_handle_declaration_name_and_params.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. #include "toolchain/parser/parser_context.h"
  5. namespace Carbon {
  6. // Handles DeclarationNameAndParamsAs(Optional|Required).
  7. static auto ParserHandleDeclarationNameAndParams(ParserContext& context,
  8. ParserState after_name)
  9. -> void {
  10. auto state = context.PopState();
  11. // TODO: Should handle designated names.
  12. if (auto identifier = context.ConsumeIf(TokenKind::Identifier)) {
  13. state.state = after_name;
  14. context.PushState(state);
  15. if (context.PositionIs(TokenKind::Period)) {
  16. // Because there's a qualifier, we process the first segment as an
  17. // expression for simplicity. This just means semantics has one less thing
  18. // to handle here.
  19. context.AddLeafNode(ParseNodeKind::NameExpression, *identifier);
  20. state.state = ParserState::PeriodAsDeclaration;
  21. context.PushState(state);
  22. } else {
  23. context.AddLeafNode(ParseNodeKind::Name, *identifier);
  24. }
  25. } else {
  26. CARBON_DIAGNOSTIC(ExpectedDeclarationName, Error,
  27. "`{0}` introducer should be followed by a name.",
  28. TokenKind);
  29. context.emitter().Emit(*context.position(), ExpectedDeclarationName,
  30. context.tokens().GetKind(state.token));
  31. context.ReturnErrorOnState();
  32. context.AddLeafNode(ParseNodeKind::InvalidParse, *context.position());
  33. }
  34. }
  35. auto ParserHandleDeclarationNameAndParamsAsNone(ParserContext& context)
  36. -> void {
  37. ParserHandleDeclarationNameAndParams(
  38. context, ParserState::DeclarationNameAndParamsAfterNameAsNone);
  39. }
  40. auto ParserHandleDeclarationNameAndParamsAsOptional(ParserContext& context)
  41. -> void {
  42. ParserHandleDeclarationNameAndParams(
  43. context, ParserState::DeclarationNameAndParamsAfterNameAsOptional);
  44. }
  45. auto ParserHandleDeclarationNameAndParamsAsRequired(ParserContext& context)
  46. -> void {
  47. ParserHandleDeclarationNameAndParams(
  48. context, ParserState::DeclarationNameAndParamsAfterNameAsRequired);
  49. }
  50. enum class Params {
  51. None,
  52. Optional,
  53. Required,
  54. };
  55. static auto ParserHandleDeclarationNameAndParamsAfterName(
  56. ParserContext& context, Params params) -> void {
  57. auto state = context.PopState();
  58. if (context.PositionIs(TokenKind::Period)) {
  59. // Continue designator processing.
  60. context.PushState(state);
  61. state.state = ParserState::PeriodAsDeclaration;
  62. context.PushState(state);
  63. return;
  64. }
  65. if (params == Params::None) {
  66. return;
  67. }
  68. if (context.PositionIs(TokenKind::OpenSquareBracket)) {
  69. context.PushState(ParserState::DeclarationNameAndParamsAfterDeduced);
  70. context.PushState(ParserState::ParameterListAsDeduced);
  71. } else if (context.PositionIs(TokenKind::OpenParen)) {
  72. context.PushState(ParserState::ParameterListAsRegular);
  73. } else if (params == Params::Required) {
  74. CARBON_DIAGNOSTIC(ParametersRequiredByIntroducer, Error,
  75. "`{0}` requires a `(` for parameters.", TokenKind);
  76. context.emitter().Emit(*context.position(), ParametersRequiredByIntroducer,
  77. context.tokens().GetKind(state.token));
  78. context.ReturnErrorOnState();
  79. }
  80. }
  81. auto ParserHandleDeclarationNameAndParamsAfterNameAsNone(ParserContext& context)
  82. -> void {
  83. ParserHandleDeclarationNameAndParamsAfterName(context, Params::None);
  84. }
  85. auto ParserHandleDeclarationNameAndParamsAfterNameAsOptional(
  86. ParserContext& context) -> void {
  87. ParserHandleDeclarationNameAndParamsAfterName(context, Params::Optional);
  88. }
  89. auto ParserHandleDeclarationNameAndParamsAfterNameAsRequired(
  90. ParserContext& context) -> void {
  91. ParserHandleDeclarationNameAndParamsAfterName(context, Params::Required);
  92. }
  93. auto ParserHandleDeclarationNameAndParamsAfterDeduced(ParserContext& context)
  94. -> void {
  95. context.PopAndDiscardState();
  96. if (context.PositionIs(TokenKind::OpenParen)) {
  97. context.PushState(ParserState::ParameterListAsRegular);
  98. } else {
  99. CARBON_DIAGNOSTIC(
  100. ParametersRequiredByDeduced, Error,
  101. "A `(` for parameters is required after deduced parameters.");
  102. context.emitter().Emit(*context.position(), ParametersRequiredByDeduced);
  103. context.ReturnErrorOnState();
  104. }
  105. }
  106. } // namespace Carbon