Parser for array type. (#3075)

Co-authored-by: Farzana Ahmed Siddique <fasiddique@google.com>
This commit is contained in:
Farzana Ahmed Siddique
2023-08-09 19:04:44 +00:00
committed by GitHub
co-authored by Farzana Ahmed Siddique
parent 2f70c7d8bb
commit a67aeb5724
10 changed files with 211 additions and 2 deletions
@@ -50,6 +50,7 @@ CARBON_DIAGNOSTIC_KIND(WrongRealLiteralExponent)
// ============================================================================
CARBON_DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace)
CARBON_DIAGNOSTIC_KIND(ExpectedArraySemi)
CARBON_DIAGNOSTIC_KIND(ExpectedCloseSymbol)
CARBON_DIAGNOSTIC_KIND(ExpectedCodeBlock)
CARBON_DIAGNOSTIC_KIND(ExpectedExpression)
+12
View File
@@ -115,6 +115,18 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListComma, 0)
CARBON_PARSE_NODE_KIND_BRACKET(ParameterList, ParameterListStart)
CARBON_PARSE_NODE_KIND_BRACKET(DeducedParameterList, DeducedParameterListStart)
// An array type, such as `[i32; 3]` or `[i32;]`:
// ArrayExpressionStart
// _external_: type expression
// ArrayExpressionSemi
// _external_: expression
// ArrayExpression
//
// The bound expression is optional.
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExpressionStart, 0)
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExpressionSemi, 2)
CARBON_PARSE_NODE_KIND_BRACKET(ArrayExpression, ArrayExpressionSemi)
// A pattern binding, such as `name: Type`:
// Name
// _external_: type expression
@@ -0,0 +1,50 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/lexer/token_kind.h"
#include "toolchain/lexer/tokenized_buffer.h"
#include "toolchain/parser/parse_node_kind.h"
#include "toolchain/parser/parser_context.h"
#include "toolchain/parser/parser_state.h"
namespace Carbon {
auto ParserHandleArrayExpression(ParserContext& context) -> void {
auto state = context.PopState();
state.state = ParserState::ArrayExpressionSemi;
context.AddLeafNode(ParseNodeKind::ArrayExpressionStart,
context.ConsumeChecked(TokenKind::OpenSquareBracket),
state.has_error);
context.PushState(state);
context.PushState(ParserState::Expression);
}
auto ParserHandleArrayExpressionSemi(ParserContext& context) -> void {
auto state = context.PopState();
auto semi = context.ConsumeIf(TokenKind::Semi);
if (!semi) {
context.AddNode(ParseNodeKind::ArrayExpressionSemi, *context.position(),
state.subtree_start, true);
CARBON_DIAGNOSTIC(ExpectedArraySemi, Error, "Expected `;` in array type.");
context.emitter().Emit(*context.position(), ExpectedArraySemi);
state.has_error = true;
} else {
context.AddNode(ParseNodeKind::ArrayExpressionSemi, *semi,
state.subtree_start, state.has_error);
}
state.state = ParserState::ArrayExpressionFinish;
context.PushState(state);
if (!context.PositionIs(TokenKind::CloseSquareBracket)) {
context.PushState(ParserState::Expression);
}
}
auto ParserHandleArrayExpressionFinish(ParserContext& context) -> void {
auto state = context.PopState();
context.ConsumeAndAddCloseSymbol(
*(TokenizedBuffer::TokenIterator(state.token)), state,
ParseNodeKind::ArrayExpression);
}
} // namespace Carbon
@@ -88,6 +88,11 @@ auto ParserHandleExpressionInPostfix(ParserContext& context) -> void {
context.PushState(ParserState::ParenExpression);
break;
}
case TokenKind::OpenSquareBracket: {
context.PushState(state);
context.PushState(ParserState::ArrayExpression);
break;
}
case TokenKind::SelfValueIdentifier: {
context.AddLeafNode(ParseNodeKind::SelfValueName, context.Consume());
context.PushState(state);
@@ -115,9 +120,7 @@ auto ParserHandleExpressionInPostfixLoop(ParserContext& context) -> void {
// This is a cyclic state that repeats, so this state is typically pushed back
// on.
auto state = context.PopState();
state.token = *context.position();
switch (context.PositionKind()) {
case TokenKind::Period: {
context.PushState(state);
+25
View File
@@ -52,6 +52,28 @@ CARBON_PARSER_STATE(IndexExpression)
// (state done)
CARBON_PARSER_STATE(IndexExpressionFinish)
// Handles an array expression `[T; N]`.
//
// Always:
// 1. Expression
// 2. ArrayExpressionSemi
CARBON_PARSER_STATE(ArrayExpression)
// Handles ';' in an array expression `[T; N]`.
//
// If `CloseSquareBracket`:
// 1. ArrayExpressionFinish
// Else:
// 1. Expression
// 2. ArrayExpressionFinish
CARBON_PARSER_STATE(ArrayExpressionSemi)
// Handles finishing the array expression.
//
// Always:
// (state done)
CARBON_PARSER_STATE(ArrayExpressionFinish)
// Handles the `{` of a brace expression.
//
// If `CloseCurlyBrace`:
@@ -260,6 +282,9 @@ CARBON_PARSER_STATE(Expression)
// If `OpenParen`:
// 1. ParenExpression
// 2. ExpressionInPostfixLoop
// If `OpenSquareBracket`:
// 1. ArrayExpression
// 2. ExpressionInPostfixLoop
// Else:
// (state done)
CARBON_PARSER_STATE(ExpressionInPostfix)
@@ -0,0 +1,33 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// TODO: It should emit only one error message.
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+9]]:8: Closing symbol does not match most recent opening symbol.
// CHECK:STDERR: var x: [i32;;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+6]]:13: Expected expression.
// CHECK:STDERR: var x: [i32;;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+3]]:13: Unexpected tokens before `]`.
// CHECK:STDERR: var x: [i32;;
// CHECK:STDERR: ^
var x: [i32;;
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+14]]:19: `var` declarations must end with a `;`.
// CHECK:STDERR: // CHECK:STDOUT: ]
// CHECK:STDERR: ^
// CHECK:STDOUT: [
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', has_error: yes, subtree_size: 5},
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', has_error: yes, subtree_size: 9},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,22 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// CHECK:STDERR: fail_require_semi.carbon:[[@LINE+3]]:12: Expected `;` in array type.
// CHECK:STDERR: var x: [i32];
// CHECK:STDERR: ^
var x: [i32];
// CHECK:STDOUT: [
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ']', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', has_error: yes, subtree_size: 4},
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 6},
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+20
View File
@@ -0,0 +1,20 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
var x: [i32; 10];
// CHECK:STDOUT: [
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'Literal', text: '10'},
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', subtree_size: 5},
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 9},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+19
View File
@@ -0,0 +1,19 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
var x: [i32;];
// CHECK:STDOUT: [
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', subtree_size: 4},
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 6},
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,24 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/semantics/semantics_context.h"
namespace Carbon {
auto SemanticsHandleArrayExpressionStart(SemanticsContext& context,
ParseTree::Node parse_node) -> bool {
return context.TODO(parse_node, "HandleArrayExpressionStart");
}
auto SemanticsHandleArrayExpressionSemi(SemanticsContext& context,
ParseTree::Node parse_node) -> bool {
return context.TODO(parse_node, "HandleArrayExpressionSemi");
}
auto SemanticsHandleArrayExpression(SemanticsContext& context,
ParseTree::Node parse_node) -> bool {
return context.TODO(parse_node, "HandleArrayExpression");
}
} // namespace Carbon