mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-02 14:15:50 +01:00
Parsing for generic and template parameters. (#2685)
Also cleans up some comments about related parse nodes. Currently basic and not heavily validated. Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
7d553107dd
commit
d7ab71ba7d
+47
-19
@@ -1451,23 +1451,26 @@ auto Parser::HandleParenExpressionFinishAsTupleState() -> void {
|
||||
state.has_error);
|
||||
}
|
||||
|
||||
auto Parser::ConsumeIfPatternKeyword(TokenKind keyword_token,
|
||||
ParserState keyword_state,
|
||||
int subtree_start) -> void {
|
||||
if (auto token = ConsumeIf(keyword_token)) {
|
||||
PushState(StateStackEntry(
|
||||
keyword_state, PrecedenceGroup::ForTopLevelExpression(),
|
||||
PrecedenceGroup::ForTopLevelExpression(), *token, subtree_start));
|
||||
}
|
||||
}
|
||||
|
||||
auto Parser::HandlePattern(PatternKind pattern_kind) -> void {
|
||||
auto state = PopState();
|
||||
|
||||
// Ensure the finish state always follows, including for errors.
|
||||
state.state = ParserState::PatternFinish;
|
||||
|
||||
// Parameters may have an `addr` keyword prefixing the pattern. This becomes
|
||||
// the parent for the full PatternBinding.
|
||||
// Parameters may have keywords prefixing the pattern. They become the parent
|
||||
// for the full PatternBinding.
|
||||
if (pattern_kind != PatternKind::Variable) {
|
||||
if (auto addr = ConsumeIf(TokenKind::Addr)) {
|
||||
// Mirror information including subtree_size, but we need to change a copy
|
||||
// to avoid affecting the token.
|
||||
auto addr_state = state;
|
||||
addr_state.state = ParserState::PatternAddress;
|
||||
addr_state.token = *addr;
|
||||
PushState(addr_state);
|
||||
}
|
||||
ConsumeIfPatternKeyword(TokenKind::Template, ParserState::PatternTemplate,
|
||||
state.subtree_start);
|
||||
ConsumeIfPatternKeyword(TokenKind::Addr, ParserState::PatternAddress,
|
||||
state.subtree_start);
|
||||
}
|
||||
|
||||
// Handle an invalid pattern introducer for parameters and variables.
|
||||
@@ -1487,6 +1490,8 @@ auto Parser::HandlePattern(PatternKind pattern_kind) -> void {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Still use the finish state for errors.
|
||||
state.state = ParserState::PatternFinishAsRegular;
|
||||
state.has_error = true;
|
||||
PushState(state);
|
||||
};
|
||||
@@ -1506,9 +1511,13 @@ auto Parser::HandlePattern(PatternKind pattern_kind) -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto colon = ConsumeIf(TokenKind::Colon)) {
|
||||
// Use the colon for the root node.
|
||||
state.token = *colon;
|
||||
if (auto kind = PositionKind();
|
||||
kind == TokenKind::Colon || kind == TokenKind::ColonExclaim) {
|
||||
state.state = kind == TokenKind::Colon
|
||||
? ParserState::PatternFinishAsRegular
|
||||
: ParserState::PatternFinishAsGeneric;
|
||||
// Use the `:` or `:!` for the root node.
|
||||
state.token = Consume();
|
||||
PushState(state);
|
||||
PushStateForExpression(PrecedenceGroup::ForType());
|
||||
} else {
|
||||
@@ -1529,7 +1538,7 @@ auto Parser::HandlePatternAsVariableState() -> void {
|
||||
HandlePattern(PatternKind::Variable);
|
||||
}
|
||||
|
||||
auto Parser::HandlePatternFinishState() -> void {
|
||||
auto Parser::HandlePatternFinish(ParseNodeKind node_kind) -> void {
|
||||
auto state = PopState();
|
||||
|
||||
// If an error was encountered, propagate it without adding a node.
|
||||
@@ -1539,8 +1548,15 @@ auto Parser::HandlePatternFinishState() -> void {
|
||||
}
|
||||
|
||||
// TODO: may need to mark has_error if !type.
|
||||
AddNode(ParseNodeKind::PatternBinding, state.token, state.subtree_start,
|
||||
/*has_error=*/false);
|
||||
AddNode(node_kind, state.token, state.subtree_start, /*has_error=*/false);
|
||||
}
|
||||
|
||||
auto Parser::HandlePatternFinishAsGenericState() -> void {
|
||||
HandlePatternFinish(ParseNodeKind::GenericPatternBinding);
|
||||
}
|
||||
|
||||
auto Parser::HandlePatternFinishAsRegularState() -> void {
|
||||
HandlePatternFinish(ParseNodeKind::PatternBinding);
|
||||
}
|
||||
|
||||
auto Parser::HandlePatternAddressState() -> void {
|
||||
@@ -1555,6 +1571,18 @@ auto Parser::HandlePatternAddressState() -> void {
|
||||
}
|
||||
}
|
||||
|
||||
auto Parser::HandlePatternTemplateState() -> void {
|
||||
auto state = PopState();
|
||||
|
||||
AddNode(ParseNodeKind::Template, state.token, state.subtree_start,
|
||||
state.has_error);
|
||||
|
||||
// If an error was encountered, propagate it while adding a node.
|
||||
if (state.has_error) {
|
||||
ReturnErrorOnState();
|
||||
}
|
||||
}
|
||||
|
||||
auto Parser::HandleStatementState() -> void {
|
||||
PopAndDiscardState();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user