mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 08:41:03 +01:00
Parsing support for if expressions. (#2883)
We model `if a then b else` as a prefix operator for parsing precedence purposes. The rule that a statement starting with `if` is never an `if` expression is handled implicitly because the statement parser never invokes the expression parser for a statement starting with `if`. This exposed a bug in our diagnosis of the whitespace rule for prefix operators, which was incorrectly being applied to non-symbolic operators in some cases, and was producing a bogus second diagnostic in some cases, which is also fixed here.
This commit is contained in:
@@ -37,6 +37,8 @@ enum PrecedenceLevel : int8_t {
|
||||
Relational,
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
// Conditional.
|
||||
If,
|
||||
// Assignment.
|
||||
SimpleAssignment,
|
||||
CompoundAssignment,
|
||||
@@ -62,11 +64,11 @@ struct OperatorPriorityTable {
|
||||
MarkHigherThan({TypePostfix}, {Type});
|
||||
MarkHigherThan(
|
||||
{Modulo, Additive, BitwiseAnd, BitwiseOr, BitwiseXor, BitShift, Type},
|
||||
{SimpleAssignment, CompoundAssignment, Relational});
|
||||
{Relational});
|
||||
MarkHigherThan({Relational, LogicalPrefix}, {LogicalAnd, LogicalOr});
|
||||
MarkHigherThan(
|
||||
{SimpleAssignment, CompoundAssignment, LogicalAnd, LogicalOr},
|
||||
{Lowest});
|
||||
MarkHigherThan({LogicalAnd, LogicalOr}, {If});
|
||||
MarkHigherThan({If}, {SimpleAssignment, CompoundAssignment});
|
||||
MarkHigherThan({SimpleAssignment, CompoundAssignment}, {Lowest});
|
||||
|
||||
// Compute the transitive closure of the above relationships: if we parse
|
||||
// `a $ b @ c` as `(a $ b) @ c` and parse `b @ c % d` as `(b @ c) % d`,
|
||||
@@ -137,7 +139,7 @@ struct OperatorPriorityTable {
|
||||
// Ambiguous would mean it's an error. LeftFirst is meaningless. For now we
|
||||
// allow all prefix operators to be repeated.
|
||||
for (PrecedenceLevel prefix :
|
||||
{TermPrefix, NumericPrefix, BitwisePrefix, LogicalPrefix}) {
|
||||
{TermPrefix, NumericPrefix, BitwisePrefix, LogicalPrefix, If}) {
|
||||
table[prefix][prefix] = OperatorPriority::RightFirst;
|
||||
}
|
||||
|
||||
@@ -210,6 +212,9 @@ auto PrecedenceGroup::ForLeading(TokenKind kind)
|
||||
case TokenKind::Tilde:
|
||||
return PrecedenceGroup(BitwisePrefix);
|
||||
|
||||
case TokenKind::If:
|
||||
return PrecedenceGroup(If);
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user