diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index ea8e974ba0fa..359a833fba62 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -523,84 +523,70 @@ auto Parser::HandleBraceExpressionState() -> void { } } -auto Parser::BraceExpressionKindToParserState(BraceExpressionKind kind, - ParserState type, - ParserState value, - ParserState unknown) - -> ParserState { - switch (kind) { - case BraceExpressionKind::Type: { - return type; - } - case BraceExpressionKind::Value: { - return value; - } - case BraceExpressionKind::Unknown: { - return unknown; - } - } -} - auto Parser::HandleBraceExpressionParameterError(StateStackEntry state, - BraceExpressionKind kind) + ParserState param_finish_state) -> void { + bool is_type = + param_finish_state == ParserState::BraceExpressionParameterFinishAsType; + bool is_value = + param_finish_state == ParserState::BraceExpressionParameterFinishAsValue; + bool is_unknown = param_finish_state == + ParserState::BraceExpressionParameterFinishAsUnknown; + CARBON_CHECK(is_type || is_value || is_unknown); CARBON_DIAGNOSTIC(ExpectedStructLiteralField, Error, "Expected {0}{1}{2}.", llvm::StringRef, llvm::StringRef, llvm::StringRef); - bool can_be_type = kind != BraceExpressionKind::Value; - bool can_be_value = kind != BraceExpressionKind::Type; emitter_->Emit(*position_, ExpectedStructLiteralField, - can_be_type ? "`.field: field_type`" : "", - (can_be_type && can_be_value) ? " or " : "", - can_be_value ? "`.field = value`" : ""); + (is_type || is_unknown) ? "`.field: field_type`" : "", + is_unknown ? " or " : "", + (is_value || is_unknown) ? "`.field = value`" : ""); - state.state = BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionParameterFinishAsType, - ParserState::BraceExpressionParameterFinishAsValue, - ParserState::BraceExpressionParameterFinishAsUnknown); + state.state = param_finish_state; state.has_error = true; PushState(state); } -auto Parser::HandleBraceExpressionParameter(BraceExpressionKind kind) -> void { +auto Parser::HandleBraceExpressionParameter(ParserState after_designator_state, + ParserState param_finish_state) + -> void { auto state = PopState(); if (!PositionIs(TokenKind::Period)) { - HandleBraceExpressionParameterError(state, kind); + HandleBraceExpressionParameterError(state, param_finish_state); return; } - state.state = BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionParameterAfterDesignatorAsType, - ParserState::BraceExpressionParameterAfterDesignatorAsValue, - ParserState::BraceExpressionParameterAfterDesignatorAsUnknown); + state.state = after_designator_state; PushState(state); PushState(ParserState::DesignatorAsStruct); } auto Parser::HandleBraceExpressionParameterAsTypeState() -> void { - HandleBraceExpressionParameter(BraceExpressionKind::Type); + HandleBraceExpressionParameter( + ParserState::BraceExpressionParameterAfterDesignatorAsType, + ParserState::BraceExpressionParameterFinishAsType); } auto Parser::HandleBraceExpressionParameterAsValueState() -> void { - HandleBraceExpressionParameter(BraceExpressionKind::Value); + HandleBraceExpressionParameter( + ParserState::BraceExpressionParameterAfterDesignatorAsValue, + ParserState::BraceExpressionParameterFinishAsValue); } auto Parser::HandleBraceExpressionParameterAsUnknownState() -> void { - HandleBraceExpressionParameter(BraceExpressionKind::Unknown); + HandleBraceExpressionParameter( + ParserState::BraceExpressionParameterAfterDesignatorAsUnknown, + ParserState::BraceExpressionParameterFinishAsUnknown); } auto Parser::HandleBraceExpressionParameterAfterDesignator( - BraceExpressionKind kind) -> void { + ParserState param_finish_state) -> void { auto state = PopState(); if (state.has_error) { auto recovery_pos = FindNextOf({TokenKind::Equal, TokenKind::Colon, TokenKind::Comma}); if (!recovery_pos || tokens_->GetKind(*recovery_pos) == TokenKind::Comma) { - state.state = BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionParameterFinishAsType, - ParserState::BraceExpressionParameterFinishAsValue, - ParserState::BraceExpressionParameterFinishAsUnknown); + state.state = param_finish_state; PushState(state); return; } @@ -608,61 +594,69 @@ auto Parser::HandleBraceExpressionParameterAfterDesignator( } // Work out the kind of this element. - auto elem_kind = BraceExpressionKind::Unknown; + bool is_type; if (PositionIs(TokenKind::Colon)) { - elem_kind = BraceExpressionKind::Type; + is_type = true; } else if (PositionIs(TokenKind::Equal)) { - elem_kind = BraceExpressionKind::Value; - } - // Unknown kinds and changes between type and value are errors. - if (elem_kind == BraceExpressionKind::Unknown || - (kind != BraceExpressionKind::Unknown && elem_kind != kind)) { - HandleBraceExpressionParameterError(state, kind); + is_type = false; + } else { + HandleBraceExpressionParameterError( + state, ParserState::BraceExpressionParameterFinishAsUnknown); return; } - // If we're setting the kind, update the BraceExpressionFinish state. - if (kind == BraceExpressionKind::Unknown) { - kind = elem_kind; + // If we're changing from unknown, update the related finish states. + if (param_finish_state == + ParserState::BraceExpressionParameterFinishAsUnknown) { auto finish_state = PopState(); CARBON_CHECK(finish_state.state == ParserState::BraceExpressionFinishAsUnknown); - finish_state.state = BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionFinishAsType, - ParserState::BraceExpressionFinishAsValue, - ParserState::BraceExpressionFinishAsUnknown); + if (is_type) { + finish_state.state = ParserState::BraceExpressionFinishAsType; + param_finish_state = ParserState::BraceExpressionParameterFinishAsType; + } else { + finish_state.state = ParserState::BraceExpressionFinishAsValue; + param_finish_state = ParserState::BraceExpressionParameterFinishAsValue; + } PushState(finish_state); } - state.state = BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionParameterFinishAsType, - ParserState::BraceExpressionParameterFinishAsValue, - ParserState::BraceExpressionParameterFinishAsUnknown); - - state.token = Consume(); + auto want_param_finish_state = + is_type ? ParserState::BraceExpressionParameterFinishAsType + : ParserState::BraceExpressionParameterFinishAsValue; + if (param_finish_state != want_param_finish_state) { + HandleBraceExpressionParameterError(state, param_finish_state); + return; + } // Struct type fields and value fields use the same grammar except // that one has a `:` separator and the other has an `=` separator. + state.state = param_finish_state; + state.token = Consume(); PushState(state); PushState(ParserState::Expression); } auto Parser::HandleBraceExpressionParameterAfterDesignatorAsTypeState() -> void { - HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Type); + HandleBraceExpressionParameterAfterDesignator( + ParserState::BraceExpressionParameterFinishAsType); } auto Parser::HandleBraceExpressionParameterAfterDesignatorAsValueState() -> void { - HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Value); + HandleBraceExpressionParameterAfterDesignator( + ParserState::BraceExpressionParameterFinishAsValue); } auto Parser::HandleBraceExpressionParameterAfterDesignatorAsUnknownState() -> void { - HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Unknown); + HandleBraceExpressionParameterAfterDesignator( + ParserState::BraceExpressionParameterFinishAsUnknown); } -auto Parser::HandleBraceExpressionParameterFinish(BraceExpressionKind kind) +auto Parser::HandleBraceExpressionParameterFinish(ParseNodeKind node_kind, + ParserState param_state) -> void { auto state = PopState(); @@ -670,50 +664,49 @@ auto Parser::HandleBraceExpressionParameterFinish(BraceExpressionKind kind) AddLeafNode(ParseNodeKind::StructFieldUnknown, state.token, /*has_error=*/true); } else { - AddNode(kind == BraceExpressionKind::Type ? ParseNodeKind::StructFieldType - : ParseNodeKind::StructFieldValue, - state.token, state.subtree_start, /*has_error=*/false); + AddNode(node_kind, state.token, state.subtree_start, /*has_error=*/false); } if (ConsumeListToken(ParseNodeKind::StructComma, TokenKind::CloseCurlyBrace, state.has_error) == ListTokenKind::Comma) { - PushState(BraceExpressionKindToParserState( - kind, ParserState::BraceExpressionParameterAsType, - ParserState::BraceExpressionParameterAsValue, - ParserState::BraceExpressionParameterAsUnknown)); + PushState(param_state); } } auto Parser::HandleBraceExpressionParameterFinishAsTypeState() -> void { - HandleBraceExpressionParameterFinish(BraceExpressionKind::Type); + HandleBraceExpressionParameterFinish( + ParseNodeKind::StructFieldType, + ParserState::BraceExpressionParameterAsType); } auto Parser::HandleBraceExpressionParameterFinishAsValueState() -> void { - HandleBraceExpressionParameterFinish(BraceExpressionKind::Value); + HandleBraceExpressionParameterFinish( + ParseNodeKind::StructFieldValue, + ParserState::BraceExpressionParameterAsValue); } auto Parser::HandleBraceExpressionParameterFinishAsUnknownState() -> void { - HandleBraceExpressionParameterFinish(BraceExpressionKind::Unknown); + HandleBraceExpressionParameterFinish( + ParseNodeKind::StructFieldUnknown, + ParserState::BraceExpressionParameterAsUnknown); } -auto Parser::HandleBraceExpressionFinish(BraceExpressionKind kind) -> void { +auto Parser::HandleBraceExpressionFinish(ParseNodeKind node_kind) -> void { auto state = PopState(); - AddNode(kind == BraceExpressionKind::Type ? ParseNodeKind::StructTypeLiteral - : ParseNodeKind::StructLiteral, - Consume(), state.subtree_start, state.has_error); + AddNode(node_kind, Consume(), state.subtree_start, state.has_error); } auto Parser::HandleBraceExpressionFinishAsTypeState() -> void { - HandleBraceExpressionFinish(BraceExpressionKind::Type); + HandleBraceExpressionFinish(ParseNodeKind::StructTypeLiteral); } auto Parser::HandleBraceExpressionFinishAsValueState() -> void { - HandleBraceExpressionFinish(BraceExpressionKind::Value); + HandleBraceExpressionFinish(ParseNodeKind::StructLiteral); } auto Parser::HandleBraceExpressionFinishAsUnknownState() -> void { - HandleBraceExpressionFinish(BraceExpressionKind::Unknown); + HandleBraceExpressionFinish(ParseNodeKind::StructLiteral); } auto Parser::HandleCallExpressionState() -> void { diff --git a/toolchain/parser/parser.h b/toolchain/parser/parser.h index a917364a09ee..6e3196c18c73 100644 --- a/toolchain/parser/parser.h +++ b/toolchain/parser/parser.h @@ -40,9 +40,6 @@ class Parser { // Possible return values for FindListToken. enum class ListTokenKind { Comma, Close, CommaClose }; - // Supported kinds for HandleBraceExpression. - enum class BraceExpressionKind { Unknown, Value, Type }; - // Supported kinds for HandlePattern. enum class PatternKind { DeducedParameter, Parameter, Variable }; @@ -281,29 +278,25 @@ class Parser { // Propagates an error up the state stack, to the parent state. auto ReturnErrorOnState() -> void { state_stack_.back().has_error = true; } - // Returns the appropriate ParserState for the input kind. - static auto BraceExpressionKindToParserState(BraceExpressionKind kind, - ParserState type, - ParserState value, - ParserState unknown) - -> ParserState; - // Prints a diagnostic for brace expression syntax errors. auto HandleBraceExpressionParameterError(StateStackEntry state, - BraceExpressionKind kind) -> void; - - // Handles BraceExpressionParameterAs(Type|Value|Unknown). - auto HandleBraceExpressionParameter(BraceExpressionKind kind) -> void; - - // Handles BraceExpressionParameterAfterDesignatorAs(Type|Value|Unknown). - auto HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind kind) + ParserState param_finish_state) -> void; + // Handles BraceExpressionParameterAs(Type|Value|Unknown). + auto HandleBraceExpressionParameter(ParserState after_designator_state, + ParserState param_finish_state) -> void; + + // Handles BraceExpressionParameterAfterDesignatorAs(Type|Value|Unknown). + auto HandleBraceExpressionParameterAfterDesignator( + ParserState param_finish_state) -> void; + // Handles BraceExpressionParameterFinishAs(Type|Value|Unknown). - auto HandleBraceExpressionParameterFinish(BraceExpressionKind kind) -> void; + auto HandleBraceExpressionParameterFinish(ParseNodeKind node_kind, + ParserState param_state) -> void; // Handles BraceExpressionFinishAs(Type|Value|Unknown). - auto HandleBraceExpressionFinish(BraceExpressionKind kind) -> void; + auto HandleBraceExpressionFinish(ParseNodeKind node_kind) -> void; // Handles DeclarationNameAndParamsAs(Optional|Required). auto HandleDeclarationNameAndParams(bool params_required) -> void;