Rename Parser2 to Parser, and delete the original (#2383)

This commit is contained in:
Jon Ross-Perkins
2022-11-11 13:35:45 -08:00
committed by GitHub
parent cd93ae6618
commit 6433a1bab6
8 changed files with 128 additions and 1808 deletions
+2 -21
View File
@@ -50,7 +50,7 @@ token has a matching closing bracket token.
## Parsing
The [ParseTree](parser/parse_tree.h) is the output of parsing, but most logic is
in [ParserImpl](parser/parser_impl.h).
in [Parser](parser/parser.h).
The parse tree faithfully represents the tree structure of the source program,
interpreted according to the Carbon grammar. No semantics are associated with
@@ -65,14 +65,6 @@ did not match the grammar, but we were still able to parse some subexpressions,
as an aid for non-compiler tools such as syntax highlighters or refactoring
tools.
Many functions in the parser return `llvm::Optional<T>`. A return value of
`llvm::None` indicates that parsing has failed and an error diagnostic has
already been produced, and that the current region of the parse tree might not
meet its invariants so that the caller should create an invalid parse tree node.
Other return values indicate that parsing was either successful or that any
encountered errors have been recovered from, so the caller can create a valid
parse tree node.
The produced `ParseTree` is in postorder. For example, given the code:
```carbon
@@ -108,18 +100,7 @@ grammatical construct that is the parent: this is so that a postorder traversal
of the tree can see the kind of grammatical construct being built first, and
handle child nodes taking that into account.
### Stack overflow
The `ParseTree` has been prone to stack overflows. As a consequence,
`CARBON_RETURN_IF_STACK_LIMITED` is checked at the start of most functions in
order to avoid errors. This manages depth increments and, when the scope exits,
decrements.
#### Future work
We are interested in eventually exploring ways to adjust the parser design to be
non-recursive and remove this limitation, but it hasn't yet been a priority and
keeping the code simple seems better until the language design stabilizes.
TODO: Document flow.
## Semantics
+2 -4
View File
@@ -56,10 +56,8 @@ cc_library(
name = "parse_tree",
srcs = [
"parse_tree.cpp",
"parser_impl.cpp",
"parser_impl.h",
"parser2.cpp",
"parser2.h",
"parser.cpp",
"parser.h",
],
hdrs = ["parse_tree.h"],
deps = [
+2 -3
View File
@@ -16,8 +16,7 @@
#include "llvm/Support/raw_ostream.h"
#include "toolchain/lexer/token_kind.h"
#include "toolchain/parser/parse_node_kind.h"
#include "toolchain/parser/parser2.h"
#include "toolchain/parser/parser_impl.h"
#include "toolchain/parser/parser.h"
namespace Carbon {
@@ -28,7 +27,7 @@ auto ParseTree::Parse(TokenizedBuffer& tokens, DiagnosticConsumer& consumer)
TokenDiagnosticEmitter emitter(translator, consumer);
// Delegate to the parser.
return Parser2::Parse(tokens, emitter);
return Parser::Parse(tokens, emitter);
}
auto ParseTree::postorder() const -> llvm::iterator_range<PostorderIterator> {
+1 -15
View File
@@ -46,11 +46,6 @@ class ParseTree {
class PostorderIterator;
class SiblingIterator;
// The maximum stack depth allowed while recursing the parse tree.
// This is meant to approximate system stack limits, but we may need to find a
// better way to track what the system is enforcing.
static constexpr int StackDepthLimit = 200;
// Parses the token buffer into a `ParseTree`.
//
// This is the factory function which is used to build parse trees.
@@ -155,19 +150,11 @@ class ParseTree {
[[nodiscard]] auto Verify() const -> bool;
private:
class Parser;
friend Parser;
friend class Parser2;
friend class Parser;
// The in-memory representation of data used for a particular node in the
// tree.
struct NodeImpl {
explicit NodeImpl(ParseNodeKind k, TokenizedBuffer::Token t,
int subtree_size_arg)
: kind(k), token(t), subtree_size(subtree_size_arg) {}
// TODO: Parser2 only uses this construct. Can remove the other if we
// switch.
NodeImpl(ParseNodeKind kind, bool has_error, TokenizedBuffer::Token token,
int subtree_size)
: kind(kind),
@@ -294,7 +281,6 @@ class ParseTree::Node {
private:
friend ParseTree;
friend Parser;
friend PostorderIterator;
friend SiblingIterator;
@@ -2,7 +2,7 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/parser/parser2.h"
#include "toolchain/parser/parser.h"
#include <cstdlib>
#include <memory>
@@ -49,10 +49,9 @@ static auto operator<<(llvm::raw_ostream& out, RelativeLocation loc)
return out;
}
class Parser2::PrettyStackTraceParseState : public llvm::PrettyStackTraceEntry {
class Parser::PrettyStackTraceParseState : public llvm::PrettyStackTraceEntry {
public:
explicit PrettyStackTraceParseState(const Parser2* parser)
: parser_(parser) {}
explicit PrettyStackTraceParseState(const Parser* parser) : parser_(parser) {}
~PrettyStackTraceParseState() override = default;
auto print(llvm::raw_ostream& output) const -> void override {
@@ -76,11 +75,11 @@ class Parser2::PrettyStackTraceParseState : public llvm::PrettyStackTraceEntry {
<< parser_->tokens_.GetKind(token).Name() << "\n";
}
const Parser2* parser_;
const Parser* parser_;
};
Parser2::Parser2(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
TokenDiagnosticEmitter& emitter)
Parser::Parser(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
TokenDiagnosticEmitter& emitter)
: tree_(tree_arg),
tokens_(tokens_arg),
emitter_(emitter),
@@ -93,8 +92,8 @@ Parser2::Parser2(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
<< tokens_.GetKind(*end_).Name();
}
auto Parser2::AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
bool has_error) -> void {
auto Parser::AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
bool has_error) -> void {
tree_.node_impls_.push_back(
ParseTree::NodeImpl(kind, has_error, token, /*subtree_size=*/1));
if (has_error) {
@@ -102,8 +101,8 @@ auto Parser2::AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
}
}
auto Parser2::AddNode(ParseNodeKind kind, TokenizedBuffer::Token token,
int subtree_start, bool has_error) -> void {
auto Parser::AddNode(ParseNodeKind kind, TokenizedBuffer::Token token,
int subtree_start, bool has_error) -> void {
int subtree_size = tree_.size() - subtree_start + 1;
tree_.node_impls_.push_back(
ParseTree::NodeImpl(kind, has_error, token, subtree_size));
@@ -112,8 +111,8 @@ auto Parser2::AddNode(ParseNodeKind kind, TokenizedBuffer::Token token,
}
}
auto Parser2::ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren,
ParseNodeKind close_kind) -> bool {
auto Parser::ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren,
ParseNodeKind close_kind) -> bool {
if (ConsumeAndAddLeafNodeIf(TokenKind::CloseParen(), close_kind)) {
return true;
}
@@ -128,8 +127,8 @@ auto Parser2::ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren,
return false;
}
auto Parser2::ConsumeAndAddLeafNodeIf(TokenKind token_kind,
ParseNodeKind node_kind) -> bool {
auto Parser::ConsumeAndAddLeafNodeIf(TokenKind token_kind,
ParseNodeKind node_kind) -> bool {
auto token = ConsumeIf(token_kind);
if (!token) {
return false;
@@ -139,7 +138,7 @@ auto Parser2::ConsumeAndAddLeafNodeIf(TokenKind token_kind,
return true;
}
auto Parser2::ConsumeIf(TokenKind kind)
auto Parser::ConsumeIf(TokenKind kind)
-> llvm::Optional<TokenizedBuffer::Token> {
if (!PositionIs(kind)) {
return llvm::None;
@@ -149,7 +148,7 @@ auto Parser2::ConsumeIf(TokenKind kind)
return token;
}
auto Parser2::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
auto Parser::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
-> llvm::Optional<TokenizedBuffer::Token> {
auto new_position = position_;
while (true) {
@@ -174,7 +173,7 @@ auto Parser2::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
}
}
auto Parser2::SkipMatchingGroup() -> bool {
auto Parser::SkipMatchingGroup() -> bool {
if (!PositionKind().IsOpeningSymbol()) {
return false;
}
@@ -184,7 +183,7 @@ auto Parser2::SkipMatchingGroup() -> bool {
return true;
}
auto Parser2::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
auto Parser::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
-> llvm::Optional<TokenizedBuffer::Token> {
if (position_ == end_) {
return llvm::None;
@@ -231,14 +230,14 @@ auto Parser2::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
return llvm::None;
}
auto Parser2::SkipTo(TokenizedBuffer::Token t) -> void {
auto Parser::SkipTo(TokenizedBuffer::Token t) -> void {
CARBON_CHECK(t >= *position_) << "Tried to skip backwards from " << position_
<< " to " << TokenizedBuffer::TokenIterator(t);
position_ = TokenizedBuffer::TokenIterator(t);
CARBON_CHECK(position_ != end_) << "Skipped past EOF.";
}
auto Parser2::HandleCodeBlockState() -> void {
auto Parser::HandleCodeBlockState() -> void {
PopAndDiscardState();
PushState(ParserState::CodeBlockFinish());
@@ -283,7 +282,7 @@ static auto IsPossibleStartOfOperand(TokenKind kind) -> bool {
TokenKind::Semi(), TokenKind::Colon()});
}
auto Parser2::IsLexicallyValidInfixOperator() -> bool {
auto Parser::IsLexicallyValidInfixOperator() -> bool {
CARBON_CHECK(position_ != end_) << "Expected an operator token.";
bool leading_space = tokens_.HasLeadingWhitespace(*position_);
@@ -311,7 +310,7 @@ auto Parser2::IsLexicallyValidInfixOperator() -> bool {
return true;
}
auto Parser2::IsTrailingOperatorInfix() -> bool {
auto Parser::IsTrailingOperatorInfix() -> bool {
if (position_ == end_) {
return false;
}
@@ -335,7 +334,7 @@ auto Parser2::IsTrailingOperatorInfix() -> bool {
return false;
}
auto Parser2::DiagnoseOperatorFixity(OperatorFixity fixity) -> void {
auto Parser::DiagnoseOperatorFixity(OperatorFixity fixity) -> void {
if (fixity == OperatorFixity::Infix) {
// Infix operators must satisfy the infix operator rules.
if (!IsLexicallyValidInfixOperator()) {
@@ -376,8 +375,8 @@ auto Parser2::DiagnoseOperatorFixity(OperatorFixity fixity) -> void {
}
}
auto Parser2::ConsumeListToken(ParseNodeKind comma_kind, TokenKind close_kind,
bool already_has_error) -> ListTokenKind {
auto Parser::ConsumeListToken(ParseNodeKind comma_kind, TokenKind close_kind,
bool already_has_error) -> ListTokenKind {
if (!PositionIs(TokenKind::Comma()) && !PositionIs(close_kind)) {
// Don't error a second time on the same element.
if (!already_has_error) {
@@ -406,7 +405,7 @@ auto Parser2::ConsumeListToken(ParseNodeKind comma_kind, TokenKind close_kind,
}
}
auto Parser2::Parse() -> void {
auto Parser::Parse() -> void {
// Traces state_stack_. This runs even in opt because it's low overhead.
PrettyStackTraceParseState pretty_stack(this);
@@ -424,7 +423,7 @@ auto Parser2::Parse() -> void {
AddLeafNode(ParseNodeKind::FileEnd(), *position_);
}
auto Parser2::HandleBraceExpressionState() -> void {
auto Parser::HandleBraceExpressionState() -> void {
auto state = PopState();
state.state = ParserState::BraceExpressionFinishAsUnknown();
@@ -441,10 +440,10 @@ auto Parser2::HandleBraceExpressionState() -> void {
}
}
auto Parser2::BraceExpressionKindToParserState(BraceExpressionKind kind,
ParserState type,
ParserState value,
ParserState unknown)
auto Parser::BraceExpressionKindToParserState(BraceExpressionKind kind,
ParserState type,
ParserState value,
ParserState unknown)
-> ParserState {
switch (kind) {
case BraceExpressionKind::Type: {
@@ -459,8 +458,8 @@ auto Parser2::BraceExpressionKindToParserState(BraceExpressionKind kind,
}
}
auto Parser2::HandleBraceExpressionParameterError(StateStackEntry state,
BraceExpressionKind kind)
auto Parser::HandleBraceExpressionParameterError(StateStackEntry state,
BraceExpressionKind kind)
-> void {
CARBON_DIAGNOSTIC(ExpectedStructLiteralField, Error, "Expected {0}{1}{2}.",
llvm::StringRef, llvm::StringRef, llvm::StringRef);
@@ -479,7 +478,7 @@ auto Parser2::HandleBraceExpressionParameterError(StateStackEntry state,
PushState(state);
}
auto Parser2::HandleBraceExpressionParameter(BraceExpressionKind kind) -> void {
auto Parser::HandleBraceExpressionParameter(BraceExpressionKind kind) -> void {
auto state = PopState();
if (!PositionIs(TokenKind::Period())) {
@@ -495,19 +494,19 @@ auto Parser2::HandleBraceExpressionParameter(BraceExpressionKind kind) -> void {
PushState(ParserState::DesignatorAsStruct());
}
auto Parser2::HandleBraceExpressionParameterAsTypeState() -> void {
auto Parser::HandleBraceExpressionParameterAsTypeState() -> void {
HandleBraceExpressionParameter(BraceExpressionKind::Type);
}
auto Parser2::HandleBraceExpressionParameterAsValueState() -> void {
auto Parser::HandleBraceExpressionParameterAsValueState() -> void {
HandleBraceExpressionParameter(BraceExpressionKind::Value);
}
auto Parser2::HandleBraceExpressionParameterAsUnknownState() -> void {
auto Parser::HandleBraceExpressionParameterAsUnknownState() -> void {
HandleBraceExpressionParameter(BraceExpressionKind::Unknown);
}
auto Parser2::HandleBraceExpressionParameterAfterDesignator(
auto Parser::HandleBraceExpressionParameterAfterDesignator(
BraceExpressionKind kind) -> void {
auto state = PopState();
@@ -565,22 +564,22 @@ auto Parser2::HandleBraceExpressionParameterAfterDesignator(
PushState(ParserState::Expression());
}
auto Parser2::HandleBraceExpressionParameterAfterDesignatorAsTypeState()
auto Parser::HandleBraceExpressionParameterAfterDesignatorAsTypeState()
-> void {
HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Type);
}
auto Parser2::HandleBraceExpressionParameterAfterDesignatorAsValueState()
auto Parser::HandleBraceExpressionParameterAfterDesignatorAsValueState()
-> void {
HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Value);
}
auto Parser2::HandleBraceExpressionParameterAfterDesignatorAsUnknownState()
auto Parser::HandleBraceExpressionParameterAfterDesignatorAsUnknownState()
-> void {
HandleBraceExpressionParameterAfterDesignator(BraceExpressionKind::Unknown);
}
auto Parser2::HandleBraceExpressionParameterFinish(BraceExpressionKind kind)
auto Parser::HandleBraceExpressionParameterFinish(BraceExpressionKind kind)
-> void {
auto state = PopState();
@@ -598,19 +597,19 @@ auto Parser2::HandleBraceExpressionParameterFinish(BraceExpressionKind kind)
}
}
auto Parser2::HandleBraceExpressionParameterFinishAsTypeState() -> void {
auto Parser::HandleBraceExpressionParameterFinishAsTypeState() -> void {
HandleBraceExpressionParameterFinish(BraceExpressionKind::Type);
}
auto Parser2::HandleBraceExpressionParameterFinishAsValueState() -> void {
auto Parser::HandleBraceExpressionParameterFinishAsValueState() -> void {
HandleBraceExpressionParameterFinish(BraceExpressionKind::Value);
}
auto Parser2::HandleBraceExpressionParameterFinishAsUnknownState() -> void {
auto Parser::HandleBraceExpressionParameterFinishAsUnknownState() -> void {
HandleBraceExpressionParameterFinish(BraceExpressionKind::Unknown);
}
auto Parser2::HandleBraceExpressionFinish(BraceExpressionKind kind) -> void {
auto Parser::HandleBraceExpressionFinish(BraceExpressionKind kind) -> void {
auto state = PopState();
AddLeafNode(ParseNodeKind::StructEnd(), Consume());
@@ -619,19 +618,19 @@ auto Parser2::HandleBraceExpressionFinish(BraceExpressionKind kind) -> void {
state.token, state.subtree_start, state.has_error);
}
auto Parser2::HandleBraceExpressionFinishAsTypeState() -> void {
auto Parser::HandleBraceExpressionFinishAsTypeState() -> void {
HandleBraceExpressionFinish(BraceExpressionKind::Type);
}
auto Parser2::HandleBraceExpressionFinishAsValueState() -> void {
auto Parser::HandleBraceExpressionFinishAsValueState() -> void {
HandleBraceExpressionFinish(BraceExpressionKind::Value);
}
auto Parser2::HandleBraceExpressionFinishAsUnknownState() -> void {
auto Parser::HandleBraceExpressionFinishAsUnknownState() -> void {
HandleBraceExpressionFinish(BraceExpressionKind::Unknown);
}
auto Parser2::HandleCallExpressionState() -> void {
auto Parser::HandleCallExpressionState() -> void {
auto state = PopState();
// TODO: When swapping () start/end, this should AddLeafNode the open before
@@ -646,7 +645,7 @@ auto Parser2::HandleCallExpressionState() -> void {
}
}
auto Parser2::HandleCallExpressionParameterFinishState() -> void {
auto Parser::HandleCallExpressionParameterFinishState() -> void {
auto state = PopState();
if (state.has_error) {
@@ -661,7 +660,7 @@ auto Parser2::HandleCallExpressionParameterFinishState() -> void {
}
}
auto Parser2::HandleCallExpressionFinishState() -> void {
auto Parser::HandleCallExpressionFinishState() -> void {
auto state = PopState();
AddLeafNode(ParseNodeKind::CallExpressionEnd(), Consume());
@@ -669,7 +668,7 @@ auto Parser2::HandleCallExpressionFinishState() -> void {
state.has_error);
}
auto Parser2::HandleCodeBlockFinishState() -> void {
auto Parser::HandleCodeBlockFinishState() -> void {
auto state = PopState();
// If the block started with an open curly, this is a close curly.
@@ -683,7 +682,7 @@ auto Parser2::HandleCodeBlockFinishState() -> void {
}
}
auto Parser2::HandleDeclarationLoopState() -> void {
auto Parser::HandleDeclarationLoopState() -> void {
// This maintains the current state unless we're at the end of the file.
switch (PositionKind()) {
@@ -725,7 +724,7 @@ auto Parser2::HandleDeclarationLoopState() -> void {
}
}
auto Parser2::HandleDesignator(bool as_struct) -> void {
auto Parser::HandleDesignator(bool as_struct) -> void {
auto state = PopState();
// `.` identifier
@@ -753,15 +752,15 @@ auto Parser2::HandleDesignator(bool as_struct) -> void {
*dot, state.subtree_start, state.has_error);
}
auto Parser2::HandleDesignatorAsExpressionState() -> void {
auto Parser::HandleDesignatorAsExpressionState() -> void {
HandleDesignator(/*as_struct=*/false);
}
auto Parser2::HandleDesignatorAsStructState() -> void {
auto Parser::HandleDesignatorAsStructState() -> void {
HandleDesignator(/*as_struct=*/true);
}
auto Parser2::HandleExpressionState() -> void {
auto Parser::HandleExpressionState() -> void {
auto state = PopState();
// Check for a prefix operator.
@@ -789,7 +788,7 @@ auto Parser2::HandleExpressionState() -> void {
}
}
auto Parser2::HandleExpressionInPostfixState() -> void {
auto Parser::HandleExpressionInPostfixState() -> void {
auto state = PopState();
// Continue to the loop state.
@@ -833,7 +832,7 @@ auto Parser2::HandleExpressionInPostfixState() -> void {
}
}
auto Parser2::HandleExpressionInPostfixLoopState() -> void {
auto Parser::HandleExpressionInPostfixLoopState() -> void {
// This is a cyclic state that repeats, so this state is typically pushed back
// on.
auto state = PopState();
@@ -862,7 +861,7 @@ auto Parser2::HandleExpressionInPostfixLoopState() -> void {
}
}
auto Parser2::HandleExpressionLoopState() -> void {
auto Parser::HandleExpressionLoopState() -> void {
auto state = PopState();
auto trailing_operator =
@@ -916,7 +915,7 @@ auto Parser2::HandleExpressionLoopState() -> void {
}
}
auto Parser2::HandleExpressionLoopForBinaryState() -> void {
auto Parser::HandleExpressionLoopForBinaryState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::InfixOperator(), state.token, state.subtree_start,
@@ -926,7 +925,7 @@ auto Parser2::HandleExpressionLoopForBinaryState() -> void {
PushState(state);
}
auto Parser2::HandleExpressionLoopForPrefixState() -> void {
auto Parser::HandleExpressionLoopForPrefixState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::PrefixOperator(), state.token, state.subtree_start,
@@ -936,7 +935,7 @@ auto Parser2::HandleExpressionLoopForPrefixState() -> void {
PushState(state);
}
auto Parser2::HandleExpressionStatementFinishState() -> void {
auto Parser::HandleExpressionStatementFinishState() -> void {
auto state = PopState();
if (auto semi = ConsumeIf(TokenKind::Semi())) {
@@ -960,8 +959,8 @@ auto Parser2::HandleExpressionStatementFinishState() -> void {
ReturnErrorOnState();
}
auto Parser2::HandleFunctionError(StateStackEntry state,
bool skip_past_likely_end) -> void {
auto Parser::HandleFunctionError(StateStackEntry state,
bool skip_past_likely_end) -> void {
auto token = state.token;
if (skip_past_likely_end) {
if (auto semi = SkipPastLikelyEnd(token)) {
@@ -972,7 +971,7 @@ auto Parser2::HandleFunctionError(StateStackEntry state,
/*has_error=*/true);
}
auto Parser2::HandleFunctionIntroducerState() -> void {
auto Parser::HandleFunctionIntroducerState() -> void {
auto state = PopState();
if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier(),
@@ -1009,7 +1008,7 @@ auto Parser2::HandleFunctionIntroducerState() -> void {
}
}
auto Parser2::HandleFunctionParameterListFinishState() -> void {
auto Parser::HandleFunctionParameterListFinishState() -> void {
auto state = PopState();
CARBON_CHECK(ConsumeAndAddLeafNodeIf(TokenKind::CloseParen(),
@@ -1019,7 +1018,7 @@ auto Parser2::HandleFunctionParameterListFinishState() -> void {
state.has_error);
}
auto Parser2::HandleFunctionAfterParameterListState() -> void {
auto Parser::HandleFunctionAfterParameterListState() -> void {
auto state = PopState();
// Regardless of whether there's a return type, we'll finish the signature.
@@ -1035,14 +1034,14 @@ auto Parser2::HandleFunctionAfterParameterListState() -> void {
}
}
auto Parser2::HandleFunctionReturnTypeFinishState() -> void {
auto Parser::HandleFunctionReturnTypeFinishState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::ReturnType(), state.token, state.subtree_start,
state.has_error);
}
auto Parser2::HandleFunctionSignatureFinishState() -> void {
auto Parser::HandleFunctionSignatureFinishState() -> void {
auto state = PopState();
switch (PositionKind()) {
@@ -1075,13 +1074,13 @@ auto Parser2::HandleFunctionSignatureFinishState() -> void {
}
}
auto Parser2::HandleFunctionDefinitionFinishState() -> void {
auto Parser::HandleFunctionDefinitionFinishState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::FunctionDefinition(), Consume(), state.subtree_start,
state.has_error);
}
auto Parser2::HandlePackageState() -> void {
auto Parser::HandlePackageState() -> void {
auto state = PopState();
auto exit_on_parse_error = [&]() {
@@ -1160,7 +1159,7 @@ auto Parser2::HandlePackageState() -> void {
/*has_error=*/false);
}
auto Parser2::HandleParenConditionState() -> void {
auto Parser::HandleParenConditionState() -> void {
auto state = PopState();
auto open_paren = ConsumeIf(TokenKind::OpenParen());
@@ -1179,7 +1178,7 @@ auto Parser2::HandleParenConditionState() -> void {
PushState(ParserState::Expression());
}
auto Parser2::HandleParenConditionFinishState() -> void {
auto Parser::HandleParenConditionFinishState() -> void {
auto state = PopState();
if (tokens_.GetKind(state.token) != TokenKind::OpenParen()) {
@@ -1197,7 +1196,7 @@ auto Parser2::HandleParenConditionFinishState() -> void {
/*has_error=*/state.has_error || !close_paren);
}
auto Parser2::HandleParenExpressionState() -> void {
auto Parser::HandleParenExpressionState() -> void {
auto state = PopState();
// TODO: When swapping () start/end, this should AddLeafNode the open before
@@ -1217,7 +1216,7 @@ auto Parser2::HandleParenExpressionState() -> void {
}
}
auto Parser2::HandleParenExpressionParameterFinish(bool as_tuple) -> void {
auto Parser::HandleParenExpressionParameterFinish(bool as_tuple) -> void {
auto state = PopState();
auto list_token_kind =
@@ -1247,15 +1246,15 @@ auto Parser2::HandleParenExpressionParameterFinish(bool as_tuple) -> void {
}
}
auto Parser2::HandleParenExpressionParameterFinishAsUnknownState() -> void {
auto Parser::HandleParenExpressionParameterFinishAsUnknownState() -> void {
HandleParenExpressionParameterFinish(/*as_tuple=*/false);
}
auto Parser2::HandleParenExpressionParameterFinishAsTupleState() -> void {
auto Parser::HandleParenExpressionParameterFinishAsTupleState() -> void {
HandleParenExpressionParameterFinish(/*as_tuple=*/true);
}
auto Parser2::HandleParenExpressionFinishState() -> void {
auto Parser::HandleParenExpressionFinishState() -> void {
auto state = PopState();
AddLeafNode(ParseNodeKind::ParenExpressionEnd(), Consume());
@@ -1263,7 +1262,7 @@ auto Parser2::HandleParenExpressionFinishState() -> void {
state.has_error);
}
auto Parser2::HandleParenExpressionFinishAsTupleState() -> void {
auto Parser::HandleParenExpressionFinishAsTupleState() -> void {
auto state = PopState();
AddLeafNode(ParseNodeKind::TupleLiteralEnd(), Consume());
@@ -1271,7 +1270,7 @@ auto Parser2::HandleParenExpressionFinishAsTupleState() -> void {
state.has_error);
}
auto Parser2::HandlePatternStart(PatternKind pattern_kind) -> void {
auto Parser::HandlePatternStart(PatternKind pattern_kind) -> void {
auto state = PopState();
// Ensure the finish state always follows.
@@ -1317,7 +1316,7 @@ auto Parser2::HandlePatternStart(PatternKind pattern_kind) -> void {
position_ += 2;
}
auto Parser2::HandlePatternFinish() -> bool {
auto Parser::HandlePatternFinish() -> bool {
auto state = PopState();
// If an error was encountered, propagate it without adding a node.
@@ -1332,11 +1331,11 @@ auto Parser2::HandlePatternFinish() -> bool {
return false;
}
auto Parser2::HandlePatternAsFunctionParameterState() -> void {
auto Parser::HandlePatternAsFunctionParameterState() -> void {
HandlePatternStart(PatternKind::Parameter);
}
auto Parser2::HandlePatternAsFunctionParameterFinishState() -> void {
auto Parser::HandlePatternAsFunctionParameterFinishState() -> void {
bool has_error = HandlePatternFinish();
if (ConsumeListToken(ParseNodeKind::ParameterListComma(),
@@ -1346,15 +1345,15 @@ auto Parser2::HandlePatternAsFunctionParameterFinishState() -> void {
}
}
auto Parser2::HandlePatternAsVariableState() -> void {
auto Parser::HandlePatternAsVariableState() -> void {
HandlePatternStart(PatternKind::Variable);
}
auto Parser2::HandlePatternAsVariableFinishState() -> void {
auto Parser::HandlePatternAsVariableFinishState() -> void {
HandlePatternFinish();
}
auto Parser2::HandleStatementState() -> void {
auto Parser::HandleStatementState() -> void {
PopAndDiscardState();
switch (PositionKind()) {
@@ -1401,17 +1400,17 @@ auto Parser2::HandleStatementState() -> void {
}
}
auto Parser2::HandleStatementBreakFinishState() -> void {
auto Parser::HandleStatementBreakFinishState() -> void {
HandleStatementKeywordFinish(TokenKind::Break(),
ParseNodeKind::BreakStatement());
}
auto Parser2::HandleStatementContinueFinishState() -> void {
auto Parser::HandleStatementContinueFinishState() -> void {
HandleStatementKeywordFinish(TokenKind::Continue(),
ParseNodeKind::ContinueStatement());
}
auto Parser2::HandleStatementForHeaderState() -> void {
auto Parser::HandleStatementForHeaderState() -> void {
auto state = PopState();
auto open_paren = ConsumeIf(TokenKind::OpenParen());
@@ -1449,7 +1448,7 @@ auto Parser2::HandleStatementForHeaderState() -> void {
}
}
auto Parser2::HandleStatementForHeaderInState() -> void {
auto Parser::HandleStatementForHeaderInState() -> void {
auto state = PopState();
state.state = ParserState::StatementForHeaderFinish();
@@ -1477,7 +1476,7 @@ auto Parser2::HandleStatementForHeaderInState() -> void {
PushState(ParserState::Expression());
}
auto Parser2::HandleStatementForHeaderFinishState() -> void {
auto Parser::HandleStatementForHeaderFinishState() -> void {
auto state = PopState();
if (!ConsumeAndAddCloseParen(state.token, ParseNodeKind::ForHeaderEnd())) {
@@ -1490,14 +1489,14 @@ auto Parser2::HandleStatementForHeaderFinishState() -> void {
PushState(ParserState::CodeBlock());
}
auto Parser2::HandleStatementForFinishState() -> void {
auto Parser::HandleStatementForFinishState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::ForStatement(), state.token, state.subtree_start,
state.has_error);
}
auto Parser2::HandleStatementIfState() -> void {
auto Parser::HandleStatementIfState() -> void {
PopAndDiscardState();
PushState(ParserState::StatementIfConditionFinish());
@@ -1505,7 +1504,7 @@ auto Parser2::HandleStatementIfState() -> void {
++position_;
}
auto Parser2::HandleStatementIfConditionFinishState() -> void {
auto Parser::HandleStatementIfConditionFinishState() -> void {
auto state = PopState();
state.state = ParserState::StatementIfThenBlockFinish();
@@ -1513,7 +1512,7 @@ auto Parser2::HandleStatementIfConditionFinishState() -> void {
PushState(ParserState::CodeBlock());
}
auto Parser2::HandleStatementIfThenBlockFinishState() -> void {
auto Parser::HandleStatementIfThenBlockFinishState() -> void {
auto state = PopState();
if (ConsumeAndAddLeafNodeIf(TokenKind::Else(),
@@ -1529,14 +1528,14 @@ auto Parser2::HandleStatementIfThenBlockFinishState() -> void {
}
}
auto Parser2::HandleStatementIfElseBlockFinishState() -> void {
auto Parser::HandleStatementIfElseBlockFinishState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::IfStatement(), state.token, state.subtree_start,
state.has_error);
}
auto Parser2::HandleStatementKeywordFinish(TokenKind token_kind,
ParseNodeKind node_kind) -> void {
auto Parser::HandleStatementKeywordFinish(TokenKind token_kind,
ParseNodeKind node_kind) -> void {
auto state = PopState();
if (!ConsumeAndAddLeafNodeIf(TokenKind::Semi(),
@@ -1552,7 +1551,7 @@ auto Parser2::HandleStatementKeywordFinish(TokenKind token_kind,
AddNode(node_kind, state.token, state.subtree_start, state.has_error);
}
auto Parser2::HandleStatementReturnState() -> void {
auto Parser::HandleStatementReturnState() -> void {
auto state = PopState();
state.state = ParserState::StatementReturnFinish();
@@ -1563,12 +1562,12 @@ auto Parser2::HandleStatementReturnState() -> void {
}
}
auto Parser2::HandleStatementReturnFinishState() -> void {
auto Parser::HandleStatementReturnFinishState() -> void {
HandleStatementKeywordFinish(TokenKind::Return(),
ParseNodeKind::ReturnStatement());
}
auto Parser2::HandleStatementScopeLoopState() -> void {
auto Parser::HandleStatementScopeLoopState() -> void {
// This maintains the current state until we're at the end of the scope.
auto token_kind = PositionKind();
@@ -1582,7 +1581,7 @@ auto Parser2::HandleStatementScopeLoopState() -> void {
}
}
auto Parser2::HandleStatementWhileState() -> void {
auto Parser::HandleStatementWhileState() -> void {
PopAndDiscardState();
PushState(ParserState::StatementWhileConditionFinish());
@@ -1590,7 +1589,7 @@ auto Parser2::HandleStatementWhileState() -> void {
++position_;
}
auto Parser2::HandleStatementWhileConditionFinishState() -> void {
auto Parser::HandleStatementWhileConditionFinishState() -> void {
auto state = PopState();
state.state = ParserState::StatementWhileBlockFinish();
@@ -1598,14 +1597,14 @@ auto Parser2::HandleStatementWhileConditionFinishState() -> void {
PushState(ParserState::CodeBlock());
}
auto Parser2::HandleStatementWhileBlockFinishState() -> void {
auto Parser::HandleStatementWhileBlockFinishState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::WhileStatement(), state.token, state.subtree_start,
state.has_error);
}
auto Parser2::HandleVar(bool require_semicolon) -> void {
auto Parser::HandleVar(bool require_semicolon) -> void {
PopAndDiscardState();
PushState(require_semicolon ? ParserState::VarFinishAsRequireSemicolon()
@@ -1615,15 +1614,15 @@ auto Parser2::HandleVar(bool require_semicolon) -> void {
PushState(ParserState::PatternAsVariable());
}
auto Parser2::HandleVarAsRequireSemicolonState() -> void {
auto Parser::HandleVarAsRequireSemicolonState() -> void {
HandleVar(/*require_semicolon=*/true);
}
auto Parser2::HandleVarAsNoSemicolonState() -> void {
auto Parser::HandleVarAsNoSemicolonState() -> void {
HandleVar(/*require_semicolon=*/false);
}
auto Parser2::HandleVarAfterPatternState() -> void {
auto Parser::HandleVarAfterPatternState() -> void {
auto state = PopState();
if (state.has_error) {
@@ -1641,14 +1640,14 @@ auto Parser2::HandleVarAfterPatternState() -> void {
}
}
auto Parser2::HandleVarAfterInitializerState() -> void {
auto Parser::HandleVarAfterInitializerState() -> void {
auto state = PopState();
AddNode(ParseNodeKind::VariableInitializer(), state.token,
state.subtree_start, state.has_error);
}
auto Parser2::HandleVarFinish(bool require_semicolon) -> void {
auto Parser::HandleVarFinish(bool require_semicolon) -> void {
auto state = PopState();
if (require_semicolon) {
@@ -1669,11 +1668,11 @@ auto Parser2::HandleVarFinish(bool require_semicolon) -> void {
state.subtree_start, state.has_error);
}
auto Parser2::HandleVarFinishAsRequireSemicolonState() -> void {
auto Parser::HandleVarFinishAsRequireSemicolonState() -> void {
HandleVarFinish(/*require_semicolon=*/true);
}
auto Parser2::HandleVarFinishAsNoSemicolonState() -> void {
auto Parser::HandleVarFinishAsNoSemicolonState() -> void {
HandleVarFinish(/*require_semicolon=*/false);
}
@@ -2,8 +2,8 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CARBON_TOOLCHAIN_PARSER_PARSER2_H_
#define CARBON_TOOLCHAIN_PARSER_PARSER2_H_
#ifndef CARBON_TOOLCHAIN_PARSER_PARSER_H_
#define CARBON_TOOLCHAIN_PARSER_PARSER_H_
#include "common/check.h"
#include "llvm/ADT/Optional.h"
@@ -16,7 +16,7 @@
namespace Carbon {
class Parser2 {
class Parser {
public:
// Parses the tokens into a parse tree, emitting any errors encountered.
//
@@ -24,7 +24,7 @@ class Parser2 {
static auto Parse(TokenizedBuffer& tokens, TokenDiagnosticEmitter& emitter)
-> ParseTree {
ParseTree tree(tokens);
Parser2 parser(tree, tokens, emitter);
Parser parser(tree, tokens, emitter);
parser.Parse();
return tree;
}
@@ -99,8 +99,8 @@ class Parser2 {
// The kind of brace expression being evaluated.
enum class BraceExpressionKind { Unknown, Value, Type };
Parser2(ParseTree& tree, TokenizedBuffer& tokens,
TokenDiagnosticEmitter& emitter);
Parser(ParseTree& tree, TokenizedBuffer& tokens,
TokenDiagnosticEmitter& emitter);
auto Parse() -> void;
@@ -305,4 +305,4 @@ class Parser2 {
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_PARSER_PARSER2_H_
#endif // CARBON_TOOLCHAIN_PARSER_PARSER_H_
File diff suppressed because it is too large Load Diff
-301
View File
@@ -1,301 +0,0 @@
// 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
#ifndef CARBON_TOOLCHAIN_PARSER_PARSER_IMPL_H_
#define CARBON_TOOLCHAIN_PARSER_PARSER_IMPL_H_
#include "llvm/ADT/Optional.h"
#include "toolchain/diagnostics/diagnostic_emitter.h"
#include "toolchain/lexer/token_kind.h"
#include "toolchain/lexer/tokenized_buffer.h"
#include "toolchain/parser/parse_node_kind.h"
#include "toolchain/parser/parse_tree.h"
#include "toolchain/parser/precedence.h"
namespace Carbon {
class ParseTree::Parser {
public:
// Parses the tokens into a parse tree, emitting any errors encountered.
//
// This is the entry point to the parser implementation.
static auto Parse(TokenizedBuffer& tokens, TokenDiagnosticEmitter& emitter)
-> ParseTree;
private:
class ScopedStackStep;
struct SubtreeStart;
explicit Parser(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
TokenDiagnosticEmitter& emitter);
auto AtEndOfFile() -> bool {
return tokens_.GetKind(*position_) == TokenKind::EndOfFile();
}
// Gets the kind of the next token to be consumed.
[[nodiscard]] auto NextTokenKind() const -> TokenKind {
return tokens_.GetKind(*position_);
}
// Tests whether the next token to be consumed is of the specified kind.
[[nodiscard]] auto NextTokenIs(TokenKind kind) const -> bool {
return NextTokenKind() == kind;
}
// Tests whether the next token to be consumed is of any of the specified
// kinds.
[[nodiscard]] auto NextTokenIsOneOf(
std::initializer_list<TokenKind> kinds) const -> bool {
return NextTokenKind().IsOneOf(kinds);
}
// Requires (and asserts) that the current position matches the provided
// `Kind`. Returns the current token and advances to the next position.
auto Consume(TokenKind kind) -> TokenizedBuffer::Token;
// If the current position's token matches this `Kind`, returns it and
// advances to the next position. Otherwise returns an empty optional.
auto ConsumeIf(TokenKind kind) -> llvm::Optional<TokenizedBuffer::Token>;
// 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.
auto AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
bool has_error = false) -> Node;
// Composes `ConsumeIf` and `AddLeafNode`, propagating the failure case
// through the optional.
auto ConsumeAndAddLeafNodeIf(TokenKind t_kind, ParseNodeKind n_kind)
-> llvm::Optional<Node>;
// Marks the node `n` as having some parse errors and that the tree contains
// a node with a parse error.
auto MarkNodeError(Node n) -> void;
// Tracks the current location as a potential start of a subtree.
//
// This returns a marker representing the current position, which can later
// be used in a call to `AddNode` to mark all nodes created since this
// position as children of the added node.
auto GetSubtreeStartPosition() -> SubtreeStart;
// Add a node to the parse tree that potentially has a subtree larger than
// itself.
//
// Requires a start marker be passed to compute the size of the subtree rooted
// at this node.
auto AddNode(ParseNodeKind n_kind, TokenizedBuffer::Token t,
SubtreeStart start, bool has_error = false) -> Node;
// If the current token is an opening symbol for a matched group, skips
// forward to one past the matched closing symbol and returns true. Otherwise,
// returns false.
auto SkipMatchingGroup() -> bool;
// Skip forward to the given token.
auto SkipTo(TokenizedBuffer::Token t) -> void;
// Find the next token of any of the given kinds at the current bracketing
// level.
auto FindNextOf(std::initializer_list<TokenKind> desired_kinds)
-> llvm::Optional<TokenizedBuffer::Token>;
// Callback used if we find a semicolon when skipping to the end of a
// declaration or statement.
using SemiHandler = llvm::function_ref<
auto(TokenizedBuffer::Token semi)->llvm::Optional<Node>>;
// Skips forward to move past the likely end of a declaration or statement.
//
// Looks forward, skipping over any matched symbol groups, to find the next
// position that is likely past the end of a declaration or statement. This
// is a heuristic and should only be called when skipping past parse errors.
//
// The strategy for recognizing when we have likely passed the end of a
// declaration or statement:
// - If we get to a close curly brace, we likely ended the entire context.
// - If we get to a semicolon, that should have ended the declaration or
// statement.
// - If we get to a new line from the `SkipRoot` token, but with the same or
// less indentation, there is likely a missing semicolon. Continued
// declarations or statements across multiple lines should be indented.
//
// If we find a semicolon based on this skipping, we return that token.
// Otherwise we will return an empty optional.
auto SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
-> llvm::Optional<TokenizedBuffer::Token>;
// Parses a close paren token corresponding to the given open paren token,
// possibly skipping forward and diagnosing if necessary. Creates and returns
// a parse node of the specified kind if successful.
auto ParseCloseParen(TokenizedBuffer::Token open_paren, ParseNodeKind kind)
-> llvm::Optional<Node>;
// Parses a comma-separated list with the given delimiters.
template <typename ListElementParser, typename ListCompletionHandler>
auto ParseList(TokenKind open, TokenKind close,
ListElementParser list_element_parser,
ParseNodeKind comma_kind, ListCompletionHandler list_handler,
bool allow_trailing_comma = false) -> llvm::Optional<Node>;
// Parses a parenthesized, comma-separated list.
template <typename ListElementParser, typename ListCompletionHandler>
auto ParseParenList(ListElementParser list_element_parser,
ParseNodeKind comma_kind,
ListCompletionHandler list_handler,
bool allow_trailing_comma = false)
-> llvm::Optional<Node> {
return ParseList(TokenKind::OpenParen(), TokenKind::CloseParen(),
list_element_parser, comma_kind, list_handler,
allow_trailing_comma);
}
// Parses a single function parameter declaration.
auto ParseFunctionParameter() -> llvm::Optional<Node>;
// Parses the signature of the function, consisting of a parameter list and an
// optional return type. Returns the root node of the signature which must be
// based on the open parenthesis of the parameter list.
auto ParseFunctionSignature() -> bool;
// Parses a block of code: `{ ... }`.
//
// These contain variable declarations and statements.
auto ParseCodeBlock() -> llvm::Optional<Node>;
// Similar to ParseCodeBlock(), but supports different ParseNodeKinds because
// function definitions are represented differently from other code blocks.
// If subtree_start is before start_kind, earlier nodes will be treated as
// children of the start_kind node.
auto ParseCodeBlock(SubtreeStart subtree_start, ParseNodeKind start_kind,
ParseNodeKind end_kind) -> llvm::Optional<Node>;
// Parses a function declaration with an optional definition. Returns the
// function parse node which is based on the `fn` introducer keyword.
auto ParseFunctionDeclaration() -> Node;
// Parses a variable declaration with an optional initializer.
auto ParseVariableDeclaration() -> Node;
// Parses and returns an empty declaration node from a single semicolon token.
auto ParseEmptyDeclaration() -> Node;
// Parses a package directive.
auto ParsePackageDirective() -> Node;
// Tries to parse a declaration. If a declaration, even an empty one after
// skipping errors, can be parsed, it is returned. There may be parse errors
// even when a node is returned.
auto ParseDeclaration() -> llvm::Optional<Node>;
// Parses a parenthesized expression.
auto ParseParenExpression() -> llvm::Optional<Node>;
// Parses a braced expression.
auto ParseBraceExpression() -> llvm::Optional<Node>;
// Parses a primary expression, which is either a terminal portion of an
// expression tree, such as an identifier or literal, or a parenthesized
// expression.
auto ParsePrimaryExpression() -> llvm::Optional<Node>;
// Parses a designator expression suffix starting with `.`.
auto ParseDesignatorExpression(SubtreeStart start, ParseNodeKind kind,
bool has_errors) -> llvm::Optional<Node>;
// Parses a call expression suffix starting with `(`.
auto ParseCallExpression(SubtreeStart start, bool has_errors)
-> llvm::Optional<Node>;
// Parses a postfix expression, which is a primary expression followed by
// zero or more of the following:
//
// - function applications
// - array indexes (TODO)
// - designators
auto ParsePostfixExpression() -> llvm::Optional<Node>;
enum class OperatorFixity { Prefix, Infix, Postfix };
// Determines whether the current token satisfies the lexical validity rules
// for an infix operator.
auto IsLexicallyValidInfixOperator() -> bool;
// Diagnoses if the current token is not written properly for the given
// fixity, for example because mandatory whitespace is missing.
auto DiagnoseOperatorFixity(OperatorFixity fixity) -> void;
// Determines whether the current trailing operator should be treated as
// infix.
auto IsTrailingOperatorInfix() -> bool;
// Parses an expression involving operators, in a context with the given
// precedence.
auto ParseOperatorExpression(PrecedenceGroup precedence)
-> llvm::Optional<Node>;
// Parses an expression.
auto ParseExpression() -> llvm::Optional<Node>;
// Parses a type expression.
auto ParseType() -> llvm::Optional<Node>;
// Parses an expression statement: an expression followed by a semicolon.
auto ParseExpressionStatement() -> llvm::Optional<Node>;
// Parses the parenthesized condition in an if-statement.
auto ParseParenCondition(TokenKind introducer) -> llvm::Optional<Node>;
// Parses an if-statement.
auto ParseIfStatement() -> llvm::Optional<Node>;
// Parses a while-statement.
auto ParseWhileStatement() -> llvm::Optional<Node>;
// Parses a for-statement.
auto ParseForStatement() -> llvm::Optional<Node>;
enum class KeywordStatementArgument {
None,
Optional,
Mandatory,
};
// Parses a statement of the form `keyword;` such as `break;` or `continue;`.
auto ParseKeywordStatement(ParseNodeKind kind,
KeywordStatementArgument argument)
-> llvm::Optional<Node>;
// Parses a statement.
auto ParseStatement() -> llvm::Optional<Node>;
enum class PatternKind {
Parameter,
Variable,
};
// Parses a pattern.
auto ParsePattern(PatternKind kind) -> llvm::Optional<Node>;
ParseTree& tree_;
TokenizedBuffer& tokens_;
TokenDiagnosticEmitter& emitter_;
// The current position within the token buffer. Never equal to `end`.
TokenizedBuffer::TokenIterator position_;
// The end position of the token buffer. There will always be an `EndOfFile`
// token between `position` (inclusive) and `end` (exclusive).
TokenizedBuffer::TokenIterator end_;
// Managed through RETURN_IF_STACK_LIMITED, which should be invoked by all
// functions.
int stack_depth_ = 0;
};
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_PARSER_PARSER_IMPL_H_