mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 16:15:01 +01:00
Update precedence rules to match design. (#3081)
- Only allow assignment at the top level in an expression statement. - Allow both negation and complement as subexpressions of both bitwise and numeric operators. - Remove parsing support for postincrement and postdecrement. - Add parsing support for `as` operator. - Use the same ambient precedence for types and non-type expressions. --------- Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Chandler Carruth
parent
3cca175a57
commit
fc5a9541ce
@@ -6,6 +6,15 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
static auto DiagnoseStatementOperatorAsSubexpression(ParserContext& context)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(StatementOperatorAsSubexpression, Error,
|
||||
"Operator `{0}` can only be used as a complete statement.",
|
||||
TokenKind);
|
||||
context.emitter().Emit(*context.position(), StatementOperatorAsSubexpression,
|
||||
context.PositionKind());
|
||||
}
|
||||
|
||||
auto ParserHandleExpression(ParserContext& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
@@ -17,13 +26,20 @@ auto ParserHandleExpression(ParserContext& context) -> void {
|
||||
OperatorPriority::RightFirst) {
|
||||
// The precedence rules don't permit this prefix operator in this
|
||||
// context. Diagnose this, but carry on and parse it anyway.
|
||||
CARBON_DIAGNOSTIC(
|
||||
UnaryOperatorRequiresParentheses, Error,
|
||||
"Parentheses are required around this unary `{0}` operator.",
|
||||
TokenKind);
|
||||
context.emitter().Emit(*context.position(),
|
||||
UnaryOperatorRequiresParentheses,
|
||||
context.PositionKind());
|
||||
if (PrecedenceGroup::GetPriority(PrecedenceGroup::ForTopLevelExpression(),
|
||||
*operator_precedence) ==
|
||||
OperatorPriority::RightFirst) {
|
||||
CARBON_DIAGNOSTIC(
|
||||
UnaryOperatorRequiresParentheses, Error,
|
||||
"Parentheses are required around this unary `{0}` operator.",
|
||||
TokenKind);
|
||||
context.emitter().Emit(*context.position(),
|
||||
UnaryOperatorRequiresParentheses,
|
||||
context.PositionKind());
|
||||
} else {
|
||||
// This operator wouldn't be allowed even if parenthesized.
|
||||
DiagnoseStatementOperatorAsSubexpression(context);
|
||||
}
|
||||
} else {
|
||||
// Check that this operator follows the proper whitespace rules.
|
||||
context.DiagnoseOperatorFixity(ParserContext::OperatorFixity::Prefix);
|
||||
@@ -188,10 +204,17 @@ auto ParserHandleExpressionLoop(ParserContext& context) -> void {
|
||||
// Either the LHS operator and this operator are ambiguous, or the
|
||||
// LHS operator is a unary operator that can't be nested within
|
||||
// this operator. Either way, parentheses are required.
|
||||
CARBON_DIAGNOSTIC(
|
||||
OperatorRequiresParentheses, Error,
|
||||
"Parentheses are required to disambiguate operator precedence.");
|
||||
context.emitter().Emit(*context.position(), OperatorRequiresParentheses);
|
||||
if (PrecedenceGroup::GetPriority(PrecedenceGroup::ForTopLevelExpression(),
|
||||
operator_precedence) ==
|
||||
OperatorPriority::RightFirst) {
|
||||
CARBON_DIAGNOSTIC(
|
||||
OperatorRequiresParentheses, Error,
|
||||
"Parentheses are required to disambiguate operator precedence.");
|
||||
context.emitter().Emit(*context.position(), OperatorRequiresParentheses);
|
||||
} else {
|
||||
// This operator wouldn't be allowed even if parenthesized.
|
||||
DiagnoseStatementOperatorAsSubexpression(context);
|
||||
}
|
||||
state.has_error = true;
|
||||
} else {
|
||||
context.DiagnoseOperatorFixity(
|
||||
|
||||
Reference in New Issue
Block a user