mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 10:54:49 +01:00
Rename Parser2 to Parser, and delete the original (#2383)
This commit is contained in:
+2
-21
@@ -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
|
||||
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
@@ -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_
|
||||
Reference in New Issue
Block a user