parser_handle_period.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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 PeriodAs variants and ArrowExpression.
  7. // TODO: This currently only supports identifiers on the rhs, but will in the
  8. // future need to handle things like `object.(Interface.member)` for qualifiers.
  9. static auto ParserHandlePeriodOrArrow(ParserContext& context,
  10. ParseNodeKind node_kind, bool is_arrow)
  11. -> void {
  12. auto state = context.PopState();
  13. // `.` identifier
  14. auto dot = context.ConsumeChecked(is_arrow ? TokenKind::MinusGreater
  15. : TokenKind::Period);
  16. if (!context.ConsumeAndAddLeafNodeIf(TokenKind::Identifier,
  17. ParseNodeKind::Name)) {
  18. CARBON_DIAGNOSTIC(ExpectedIdentifierAfterDotOrArrow, Error,
  19. "Expected identifier after `{0}`.", llvm::StringRef);
  20. context.emitter().Emit(*context.position(),
  21. ExpectedIdentifierAfterDotOrArrow,
  22. is_arrow ? "->" : ".");
  23. // If we see a keyword, assume it was intended to be a name.
  24. // TODO: Should keywords be valid here?
  25. if (context.PositionKind().is_keyword()) {
  26. context.AddLeafNode(ParseNodeKind::Name, context.Consume(),
  27. /*has_error=*/true);
  28. } else {
  29. context.AddLeafNode(ParseNodeKind::Name, *context.position(),
  30. /*has_error=*/true);
  31. // Indicate the error to the parent state so that it can avoid producing
  32. // more errors.
  33. context.ReturnErrorOnState();
  34. }
  35. }
  36. context.AddNode(node_kind, dot, state.subtree_start, state.has_error);
  37. }
  38. auto ParserHandlePeriodAsDeclaration(ParserContext& context) -> void {
  39. ParserHandlePeriodOrArrow(context, ParseNodeKind::QualifiedDeclaration,
  40. /*is_arrow=*/false);
  41. }
  42. auto ParserHandlePeriodAsExpression(ParserContext& context) -> void {
  43. ParserHandlePeriodOrArrow(context, ParseNodeKind::MemberAccessExpression,
  44. /*is_arrow=*/false);
  45. }
  46. auto ParserHandlePeriodAsStruct(ParserContext& context) -> void {
  47. ParserHandlePeriodOrArrow(context, ParseNodeKind::StructFieldDesignator,
  48. /*is_arrow=*/false);
  49. }
  50. auto ParserHandleArrowExpression(ParserContext& context) -> void {
  51. ParserHandlePeriodOrArrow(
  52. context, ParseNodeKind::PointerMemberAccessExpression, /*is_arrow=*/true);
  53. }
  54. } // namespace Carbon