Преглед на файлове

Finish Parser2 support and switch. (#2381)

Adds remaining expression support, and switches the default to Parser2.

Note, this doesn't delete the current Parser yet. I'll just do that in its own PR.
Jon Ross-Perkins преди 3 години
родител
ревизия
cd93ae6618
променени са 5 файла, в които са добавени 1192 реда и са изтрити 183 реда
  1. 1 3
      toolchain/parser/parse_tree.cpp
  2. 2 25
      toolchain/parser/parse_tree_test.cpp
  3. 689 119
      toolchain/parser/parser2.cpp
  4. 63 20
      toolchain/parser/parser2.h
  5. 437 16
      toolchain/parser/parser_state.def

+ 1 - 3
toolchain/parser/parse_tree.cpp

@@ -28,9 +28,7 @@ auto ParseTree::Parse(TokenizedBuffer& tokens, DiagnosticConsumer& consumer)
   TokenDiagnosticEmitter emitter(translator, consumer);
 
   // Delegate to the parser.
-  // TODO: Edit this to swap between Parser and Parser2. This is manual in order
-  // to avoid test duplication.
-  return Parser::Parse(tokens, emitter);
+  return Parser2::Parse(tokens, emitter);
 }
 
 auto ParseTree::postorder() const -> llvm::iterator_range<PostorderIterator> {

+ 2 - 25
toolchain/parser/parse_tree_test.cpp

@@ -209,7 +209,7 @@ TEST_F(ParseTreeTest, PrintPreorderAsYAML) {
   EXPECT_THAT(Yaml::Value::FromText(print_output), ElementsAre(file));
 }
 
-TEST_F(ParseTreeTest, RecursionLimit) {
+TEST_F(ParseTreeTest, HighRecursion) {
   std::string code = "fn Foo() { return ";
   code.append(10000, '(');
   code.append(10000, ')');
@@ -217,31 +217,8 @@ TEST_F(ParseTreeTest, RecursionLimit) {
   TokenizedBuffer tokens = GetTokenizedBuffer(code);
   ASSERT_FALSE(tokens.has_errors());
   Testing::MockDiagnosticConsumer consumer;
-  // Recursion might be exceeded multiple times due to quirks in parse tree
-  // handling; we only need to be sure it's hit at least once for test
-  // correctness.
-  EXPECT_CALL(consumer, HandleDiagnostic(IsDiagnosticMessage(
-                            llvm::formatv("Exceeded recursion limit ({0})",
-                                          ParseTree::StackDepthLimit)
-                                .str())))
-      .Times(AtLeast(1));
   ParseTree tree = ParseTree::Parse(tokens, consumer);
-  EXPECT_TRUE(tree.has_errors());
-}
-
-TEST_F(ParseTreeTest, ParsePostfixExpressionRegression) {
-  // Stack depth errors could cause ParsePostfixExpression to infinitely loop
-  // when calling children and those children error. Because of the fragility of
-  // stack depth, this tries a few different values.
-  for (int n = 0; n <= 10; ++n) {
-    std::string code = "var x: auto = ";
-    code.append(ParseTree::StackDepthLimit - n, '*');
-    code += "(z);";
-    TokenizedBuffer tokens = GetTokenizedBuffer(code);
-    ASSERT_FALSE(tokens.has_errors());
-    ParseTree tree = ParseTree::Parse(tokens, consumer);
-    EXPECT_TRUE(tree.has_errors());
-  }
+  EXPECT_FALSE(tree.has_errors());
 }
 
 TEST_F(ParseTreeTest, PackageErrors) {

Файловите разлики са ограничени, защото са твърде много
+ 689 - 119
toolchain/parser/parser2.cpp


+ 63 - 20
toolchain/parser/parser2.h

@@ -5,6 +5,7 @@
 #ifndef CARBON_TOOLCHAIN_PARSER_PARSER2_H_
 #define CARBON_TOOLCHAIN_PARSER_PARSER2_H_
 
+#include "common/check.h"
 #include "llvm/ADT/Optional.h"
 #include "toolchain/lexer/token_kind.h"
 #include "toolchain/lexer/tokenized_buffer.h"
@@ -88,22 +89,32 @@ class Parser2 {
   static_assert(sizeof(StateStackEntry) == 12,
                 "StateStackEntry has unexpected size!");
 
+  // Possible return values for FindListToken.
+  enum class ListTokenKind {
+    Comma,
+    Close,
+    CommaClose,
+  };
+
+  // The kind of brace expression being evaluated.
+  enum class BraceExpressionKind { Unknown, Value, Type };
+
   Parser2(ParseTree& tree, TokenizedBuffer& tokens,
           TokenDiagnosticEmitter& emitter);
 
   auto Parse() -> void;
 
-  // Adds a node to the parse tree that is fully parsed, has no children
-  // ("leaf"), and has a subsequent sibling.
-  //
-  // This sets up the next sibling of the node to be the next node in the parse
-  // tree's preorder sequence.
+  // Adds a node to the parse tree that has no children (a leaf).
   auto AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
                    bool has_error = false) -> void;
 
+  // Adds a node to the parse tree that has children.
   auto AddNode(ParseNodeKind kind, TokenizedBuffer::Token token,
                int subtree_start, bool has_error) -> void;
 
+  // Returns the current position and moves past it.
+  auto Consume() -> TokenizedBuffer::Token { return *(position_++); }
+
   // Parses a close paren token corresponding to the given open paren token,
   // possibly skipping forward and diagnosing if necessary. Creates a parse node
   // of the specified kind if successful.
@@ -163,6 +174,15 @@ class Parser2 {
   // whether there's an error, it's expected that parsing continues.
   auto DiagnoseOperatorFixity(OperatorFixity fixity) -> void;
 
+  // If the current position is a `,`, consumes it, adds the provided token, and
+  // returns `Comma`. Returns `Close` if the current position is close_token
+  // (for example, `)`). `CommaClose` indicates it found both (for example,
+  // `,)`). Handles cases where invalid tokens are present by advancing the
+  // position, and may emit errors. Pass already_has_error in order to suppress
+  // duplicate errors.
+  auto ConsumeListToken(ParseNodeKind comma_kind, TokenKind close_kind,
+                        bool already_has_error) -> ListTokenKind;
+
   // Gets the kind of the next token to be consumed.
   auto PositionKind() const -> TokenKind { return tokens_.GetKind(*position_); }
 
@@ -205,43 +225,66 @@ class Parser2 {
   // Pushes a constructed state onto the stack.
   auto PushState(StateStackEntry state) -> void {
     state_stack_.push_back(state);
+    // Verify the stack doesn't grow unbounded by programming error.
+    CARBON_CHECK(state_stack_.size() < (1 << 20));
   }
 
   // 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)
+      -> void;
+
+  // Handles BraceExpressionParameterFinishAs(Type|Value|Unknown).
+  auto HandleBraceExpressionParameterFinish(BraceExpressionKind kind) -> void;
+
+  // Handles BraceExpressionFinishAs(Type|Value|Unknown).
+  auto HandleBraceExpressionFinish(BraceExpressionKind kind) -> void;
+
+  // Handles DesignatorAs.
+  auto HandleDesignator(bool as_struct) -> void;
+
   // When handling errors before the start of the definition, treat it as a
   // declaration. Recover to a semicolon when it makes sense as a possible
   // function end, otherwise use the fn token for the error.
   auto HandleFunctionError(StateStackEntry state, bool skip_past_likely_end)
       -> void;
 
-  // Handles a code block in the context of a statement scope.
-  auto HandleCodeBlock() -> void;
-
-  // Handles parsing of a function parameter list, including commas and the
-  // close paren.
-  auto HandleFunctionParameterList(bool is_start) -> void;
+  // Handles ParenExpressionParameterFinish(AsUnknown|AsTuple)
+  auto HandleParenExpressionParameterFinish(bool as_tuple) -> void;
 
   // Handles the start of a pattern.
   // If the start of the pattern is invalid, it's the responsibility of the
   // outside context to advance past the pattern.
   auto HandlePatternStart(PatternKind pattern_kind) -> void;
 
-  // Handles a single statement. While typically within a statement block, this
-  // can also be used for error recovery where we expect a statement block and
-  // are missing braces.
-  auto HandleStatement(TokenKind token_kind) -> void;
-
-  // Handles a `if` statement at the start `if` token.
-  auto HandleStatementIf() -> void;
+  // Handles the end of a pattern.
+  auto HandlePatternFinish() -> bool;
 
   // Handles the `;` after a keyword statement.
   auto HandleStatementKeywordFinish(TokenKind token_kind,
                                     ParseNodeKind node_kind) -> void;
 
-  // Handles a `while` statement at the start `while` token.
-  auto HandleStatementWhile() -> void;
+  // Handles VarAs(RequireSemicolon|NoSemicolon).
+  auto HandleVar(bool require_semicolon) -> void;
+
+  // Handles VarFinishAs(RequireSemicolon|NoSemicolon).
+  auto HandleVarFinish(bool require_semicolon) -> void;
 
   // `clang-format` has a bug with spacing around `->` returns in macros. See
   // https://bugs.llvm.org/show_bug.cgi?id=48320 for details.

+ 437 - 16
toolchain/parser/parser_state.def

@@ -13,100 +13,521 @@
 #error "Must define the x-macro to use this file."
 #endif
 
+// Handles the `{` of a brace expression.
+//
+// If `CloseCurlyBrace`:
+//   1. BraceExpressionFinishAsUnknown
+// Else:
+//   1. BraceExpressionParameterAsUnknown
+//   2. BraceExpressionFinishAsUnknown
+CARBON_PARSER_STATE(BraceExpression)
+
+// Handles a brace expression parameter. Note this will always start as unknown,
+// but should be known after the first valid parameter. All later inconsistent
+// parameters are invalid.
+//
+// If valid:
+//   1. DesignatorExpressionAsStruct
+//   2. BraceExpressionParameterAfterDesignatorAs(Type|Value|Unknown)
+// Else:
+//   1. BraceExpressionParameterFinishAs(Type|Value|Unknown)
+CARBON_PARSER_STATE(BraceExpressionParameterAsType)
+CARBON_PARSER_STATE(BraceExpressionParameterAsValue)
+CARBON_PARSER_STATE(BraceExpressionParameterAsUnknown)
+
+// Handles a brace expression parameter after the initial designator. This
+// should be at a `:` or `=`, depending on whether it's a type or value literal.
+//
+// If valid:
+//   1. Expression
+//   2. BraceExpressionParameterFinishAs(Type|Value|Unknown)
+// Else:
+//   1. BraceExpressionParameterFinishAs(Type|Value|Unknown)
+CARBON_PARSER_STATE(BraceExpressionParameterAfterDesignatorAsType)
+CARBON_PARSER_STATE(BraceExpressionParameterAfterDesignatorAsValue)
+CARBON_PARSER_STATE(BraceExpressionParameterAfterDesignatorAsUnknown)
+
+// Handles the end of a brace expression parameter.
+//
+// If `Comma`:
+//   1. BraceExpressionParameterAsUnknown
+// Else:
+//   (state done)
+CARBON_PARSER_STATE(BraceExpressionParameterFinishAsType)
+CARBON_PARSER_STATE(BraceExpressionParameterFinishAsValue)
+CARBON_PARSER_STATE(BraceExpressionParameterFinishAsUnknown)
+
+// Handles the `}` of a brace expression.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(BraceExpressionFinishAsType)
+CARBON_PARSER_STATE(BraceExpressionFinishAsValue)
+CARBON_PARSER_STATE(BraceExpressionFinishAsUnknown)
+
+// Handles a call expression `(...)`.
+//
+// If `CloseParen`:
+//   1. CallExpressionFinish
+// Else:
+//   1. Expression
+//   2. CallExpressionParameterFinish
+//   3. CallExpressionFinish
+CARBON_PARSER_STATE(CallExpression)
+
+// Handles the `,` or `)` after a call parameter.
+//
+// If `Comma`:
+//   1. Expression
+//   2. CallExpressionParameterFinish
+// Else:
+//   (state done)
+CARBON_PARSER_STATE(CallExpressionParameterFinish)
+
+// Handles finishing the call expression.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(CallExpressionFinish)
+
+// Handles processing at the `{` on a typical code block.
+//
+// If `OpenCurlyBrace`:
+//   1. StatementScopeLoop
+//   2. CodeBlockFinish
+// Else:
+//   1. Statement
+//   2. CodeBlockFinish
+CARBON_PARSER_STATE(CodeBlock)
+
 // Handles processing at the `}` on a typical code block, after a statement
 // scope is done.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(CodeBlockFinish)
 
 // Handles processing of a declaration scope. Things like fn, class, interface,
 // and so on.
-CARBON_PARSER_STATE(Declaration)
+//
+// If `EndOfFile`:
+//   (state done)
+// If `Fn`:
+//   1. FunctionIntroducer
+//   2. DeclarationLoop
+// If `Package`:
+//   1. Package
+//   2. DeclarationLoop
+// If `Semi`:
+//   1. DeclarationLoop
+// If `Var`:
+//   1. Var
+//   2. DeclarationLoop
+// Else:
+//   1. DeclarationLoop
+CARBON_PARSER_STATE(DeclarationLoop)
 
 // Handles a designator expression, such as `.z` in `x.(y.z)`.
-CARBON_PARSER_STATE(DesignatorExpression)
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(DesignatorAsExpression)
+CARBON_PARSER_STATE(DesignatorAsStruct)
 
 // Handles processing of an expression.
+//
+// If valid prefix operator:
+//   1. Expression
+//   2. ExpressionLoopForPrefix
+// Else:
+//   1. ExpressionInPostfix
+//   2. ExpressionLoop
 CARBON_PARSER_STATE(Expression)
 
-// Handles processing of an expression.
-CARBON_PARSER_STATE(ExpressionLoop)
-CARBON_PARSER_STATE(ExpressionLoopForBinary)
-CARBON_PARSER_STATE(ExpressionLoopForPrefix)
-
 // Handles the initial part of postfix expressions, such as an identifier or
 // literal value, then proceeds to the loop.
+//
+// If `Identifier` or literal (including type literals):
+//   1. ExpressionInPostfixLoop
+// If `OpenCurlyBrace`:
+//   1. BraceExpression
+//   2. ExpressionInPostfixLoop
+// If `OpenParen`:
+//   1. ParenExpression
+//   2. ExpressionInPostfixLoop
+// Else:
+//   (state done)
 CARBON_PARSER_STATE(ExpressionInPostfix)
 
 // Handles looping through elements following the initial postfix expression,
 // such as designators or parenthesized parameters.
+//
+// If `Period`:
+//   1. DesignatorAsExpression
+//   2. ExpressionInPostfixLoop
+// If `OpenParen`:
+//   1. CallExpression
+//   2. ExpressionInPostfixLoop
+// Else:
+//   (state done)
 CARBON_PARSER_STATE(ExpressionInPostfixLoop)
 
+// Handles processing of an expression.
+//
+// If binary operator:
+//   1. Expression
+//   2. ExpressionLoopForBinary
+// If postfix operator:
+//   1. ExpressionLoop
+// Else:
+//   (state done)
+CARBON_PARSER_STATE(ExpressionLoop)
+
+// Completes an ExpressionLoop pass by adding an infix operator, then goes back
+// to ExpressionLoop.
+//
+// Always:
+//   1. ExpressionLoop
+CARBON_PARSER_STATE(ExpressionLoopForBinary)
+
+// Completes an ExpressionLoop pass by adding a prefix operator, then goes back
+// to ExpressionLoop.
+//
+// Always:
+//   1. ExpressionLoop
+CARBON_PARSER_STATE(ExpressionLoopForPrefix)
+
 // Handles the `;` for an expression statement, which is different from most
 // keyword statements.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(ExpressionStatementFinish)
 
 // Handles processing of a function's `fn <name>(`, and enqueues parameter list
 // handling.
+//
+// If invalid:
+//   (state done)
+// If parenthesized parameters:
+//   1. PatternAsFunctionParameter
+//   2. FunctionParameterListFinish
+//   3. FunctionAfterParameterList
+// Else:
+//   1. FunctionParameterListFinish
+//   2. FunctionAfterParameterList
 CARBON_PARSER_STATE(FunctionIntroducer)
 
 // Handles processing of a function's parameter list `)`.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(FunctionParameterListFinish)
 
 // Handles processing of a function's syntax after `)`, primarily the
 // possibility a `->` return type is there. Always enqueues signature finish
 // handling.
+//
+// If `MinusGreater`:
+//   1. Expression
+//   2. FunctionReturnTypeFinish
+//   3. FunctionSignatureFinish
+// Else:
+//   1. FunctionSignatureFinish
 CARBON_PARSER_STATE(FunctionAfterParameterList)
 
 // Finishes a function return type.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(FunctionReturnTypeFinish)
 
 // Finishes a function signature. If it's a declaration, the function is done;
 // otherwise, this also starts definition processing.
+//
+// If `Semi`:
+//   (state done)
+// If `OpenCurlyBrace`:
+//   1. StatementScopeLoop
+//   2. FunctionDefinitionFinish
+// Else:
+//   (state done)
 CARBON_PARSER_STATE(FunctionSignatureFinish)
 
 // Finishes a function definition.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(FunctionDefinitionFinish)
 
+// Handles `package`.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(Package)
+
 // Handles the processing of a `(condition)` up through the expression.
+//
+// Always:
+//   1. Expression
+//   2. ParenConditionFinish
 CARBON_PARSER_STATE(ParenCondition)
 
 // Finishes the processing of a `(condition)` after the expression.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(ParenConditionFinish)
 
+// Handles the `(` of a parenthesized expression.
+//
+// If `CloseParen`:
+//   1. ParenExpressionFinishAsTuple
+// Else:
+//   1. Expression
+//   2. ParenExpressionParameterFinishAsUnknown
+//   3. ParenExpressionFinish
+CARBON_PARSER_STATE(ParenExpression)
+
+// Handles the end of a parenthesized expression's parameter. This will start as
+// AsUnknown on the first parameter; if there are more, it switches to AsTuple
+// processing.
+//
+// If `Comma` without `CloseParen`:
+//   1. Expression
+//   2. ParenExpressionParameterFinishAsTuple
+//   SPECIAL: Parent becomes ParenExpressionFinishAsTuple
+// If `Comma` with `CloseParen`:
+//   (state done)
+//   SPECIAL: Parent becomes ParenExpressionFinishAsTuple
+// Else `CloseParen`:
+//   (state done)
+CARBON_PARSER_STATE(ParenExpressionParameterFinishAsUnknown)
+CARBON_PARSER_STATE(ParenExpressionParameterFinishAsTuple)
+
+// Handles the `)` of a parenthesized expression.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(ParenExpressionFinish)
+CARBON_PARSER_STATE(ParenExpressionFinishAsTuple)
+
+// Handles pattern parsing for a function parameter, enqueuing type expression
+// processing. Proceeds to the matching Finish state when done.
+//
+// If valid:
+//   1. Expression
+//   2. PatternAsFunctionParameterFinish
+// Else:
+//   1. PatternAsFunctionParameterFinish
+CARBON_PARSER_STATE(PatternAsFunctionParameter)
+
+// Finishes function parameter processing, including `,`. If there are more
+// parameters, enqueues another parameter processing state.
+//
+// If `Comma` without `CloseParen`:
+//   1. PatternAsFunctionParameter
+// Else:
+//   (state done)
+CARBON_PARSER_STATE(PatternAsFunctionParameterFinish)
+
+// Handles pattern parsing for a `var` statement, enqueuing type expression
+// processing. Proceeds to the matching Finish state when done.
+//
+//
+// If valid:
+//   1. Expression
+//   2. PatternAsVariableFinish
+// Else:
+//   1. PatternAsVariableFinish
+CARBON_PARSER_STATE(PatternAsVariable)
+
+// Finishes `var` pattern processing.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(PatternAsVariableFinish)
+
+// Handles a single statement. While typically within a statement block, this
+// can also be used for error recovery where we expect a statement block and
+// are missing braces.
+//
+// If `Break`:
+//   1. StatementBreakFinish
+//   (state done)
+// If `Continue`:
+//   1. StatementContinueFinish
+//   (state done)
+// If `For`:
+//   1. StatementForHeader
+//   2. StatementForFinish
+// If `If`:
+//   1. StatementIf
+// If `Return`:
+//   1. StatementReturn
+// If `Var`:
+//   1. VarAsRequireSemicolon
+// If `While`:
+//   1. StatementWhile
+// Else:
+//   1. Expression
+//   2. ExpressionStatementFinish
+CARBON_PARSER_STATE(Statement)
+
 // Handles `break` processing at the `;`.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(StatementBreakFinish)
 
 // Handles `continue` processing at the `;`.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(StatementContinueFinish)
 
+// Handles `for` processing of `(var`, proceeding to a pattern before
+// continuing.
+//
+// If no `OpenParen`:
+//   1. CodeBlock
+// If `Var`:
+//   1. VarAsNoSemicolon
+//   2. StatementForHeaderIn
+// Else:
+//   1. StatementForHeaderIn
+CARBON_PARSER_STATE(StatementForHeader)
+
+// Handles `for` procesisng of `in`, proceeding to an expression before
+// continuing.
+//
+// If `In` or `Colon`:
+//   1. Expression
+//   2. StatementForHeaderFinish
+// Else:
+//   1. StatementForHeaderFinish
+CARBON_PARSER_STATE(StatementForHeaderIn)
+
+// Handles `for` processing of `)`, proceeding to the statement block.
+//
+// Always:
+//   1. CodeBlock
+CARBON_PARSER_STATE(StatementForHeaderFinish)
+
+// Handles `for` processing at the final `}`.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(StatementForFinish)
+
+// Handles `if` processing at the start.
+//
+// Always:
+//   1. ParenCondition
+//   2. StatementIfConditionFinish
+CARBON_PARSER_STATE(StatementIf)
+
 // Handles `if` processing between the condition and start of the first code
 // block.
+//
+// Always:
+//   1. CodeBlock
+//   2. StatementIfThenBlockFinish
 CARBON_PARSER_STATE(StatementIfConditionFinish)
 
 // Handles `if` processing after the end of the first code block, with the
 // optional `else`.
+//
+// If `Else` then `If`:
+//   1. CodeBlock
+//   2. StatementIfElseBlockFinish
+// If `Else`:
+//   1. StatementIf
+//   2. StatementIfElseBlockFinish
+// Else:
+//   (state done)
 CARBON_PARSER_STATE(StatementIfThenBlockFinish)
 
 // Handles `if` processing after a provided `else` code block.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(StatementIfElseBlockFinish)
 
-// Handles `return` processing at the `;`.
+// Handles `return` processing.
+//
+// If `Semi`:
+//   1. StatementReturnFinish
+// Else:
+//   1. Expression
+//   2. StatementReturnFinish
+CARBON_PARSER_STATE(StatementReturn)
+
+// Handles `return` processing at the `;` when there's an expression.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(StatementReturnFinish)
 
+// Handles processing of statements within a scope.
+//
+// If `CloseCurlyBrace`:
+//   (state done)
+// Else:
+//   1. Statement
+//   2. StatementScopeLoop
+CARBON_PARSER_STATE(StatementScopeLoop)
+
+// Handles `while` processing.
+//
+// Always:
+//   1. ParenCondition
+//   2. StatementWhileConditionFinish
+CARBON_PARSER_STATE(StatementWhile)
+
 // Handles `while` processing between the condition and start of the code block.
+//
+// Always:
+//   1. CodeBlock
+//   2. StatementWhileBlockFinish
 CARBON_PARSER_STATE(StatementWhileConditionFinish)
 
 // Handles `while` processing after the end of the code block.
+//
+// Always:
+//   (state done)
 CARBON_PARSER_STATE(StatementWhileBlockFinish)
 
-// Handles pattern parsing for a function parameter, enqueuing type expression
-// processing. Proceeds to the matching Finish state when done.
-CARBON_PARSER_STATE(PatternForFunctionParameter)
+// Handles the start of a `var`.
+//
+// Always:
+//   1. PatternAsVariable
+//   2. VarAfterPattern
+//   3. VarFinishAs(RequireSemicolon|NoSemicolon)
+CARBON_PARSER_STATE(VarAsRequireSemicolon)
+CARBON_PARSER_STATE(VarAsNoSemicolon)
 
-// Finishes function parameter processing, including `,`. If there are more
-// parameters, enqueues another parameter processing state.
-CARBON_PARSER_STATE(PatternForFunctionParameterFinish)
+// Handles `var` after the pattern, either followed by an initializer or the
+// semicolon.
+//
+// If `Equal`:
+//   1. Expression
+//   2. VarAfterInitializer
+// Else:
+//   (state done)
+CARBON_PARSER_STATE(VarAfterPattern)
 
-// Handles processing of statements within a scope.
-CARBON_PARSER_STATE(StatementScopeLoop)
+// Handles `var` after the initializer, wrapping up its subtree.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(VarAfterInitializer)
+
+// Handles `var` parsing at the end.
+//
+// Always:
+//   (state done)
+CARBON_PARSER_STATE(VarFinishAsRequireSemicolon)
+CARBON_PARSER_STATE(VarFinishAsNoSemicolon)
 
 #undef CARBON_PARSER_STATE

Някои файлове не бяха показани, защото твърде много файлове са промени