mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Parsing for pointer types and pointer operators. (#3026)
This provides parsing support for the functionality added in #2006.
This commit is contained in:
@@ -29,6 +29,7 @@ enum PrecedenceLevel : int8_t {
|
||||
BitwiseXor,
|
||||
BitShift,
|
||||
// Type formation.
|
||||
TypePrefix,
|
||||
TypePostfix,
|
||||
// Sentinel representing a type context.
|
||||
Type,
|
||||
@@ -55,21 +56,26 @@ struct OperatorPriorityTable {
|
||||
// relationships.
|
||||
MarkHigherThan({Highest}, {TermPrefix});
|
||||
MarkHigherThan({TermPrefix}, {NumericPrefix, BitwisePrefix, LogicalPrefix,
|
||||
NumericPostfix, TypePostfix});
|
||||
NumericPostfix});
|
||||
MarkHigherThan({NumericPrefix, NumericPostfix},
|
||||
{Modulo, Multiplicative, BitShift});
|
||||
MarkHigherThan({Multiplicative}, {Additive});
|
||||
MarkHigherThan({BitwisePrefix},
|
||||
{BitwiseAnd, BitwiseOr, BitwiseXor, BitShift});
|
||||
MarkHigherThan({TypePostfix}, {Type});
|
||||
MarkHigherThan(
|
||||
{Modulo, Additive, BitwiseAnd, BitwiseOr, BitwiseXor, BitShift, Type},
|
||||
{Modulo, Additive, BitwiseAnd, BitwiseOr, BitwiseXor, BitShift},
|
||||
{Relational});
|
||||
MarkHigherThan({Relational, LogicalPrefix}, {LogicalAnd, LogicalOr});
|
||||
MarkHigherThan({LogicalAnd, LogicalOr}, {If});
|
||||
MarkHigherThan({If}, {SimpleAssignment, CompoundAssignment});
|
||||
MarkHigherThan({SimpleAssignment, CompoundAssignment}, {Lowest});
|
||||
|
||||
// Types are mostly a separate precedence graph.
|
||||
MarkHigherThan({Highest}, {TypePrefix});
|
||||
MarkHigherThan({TypePrefix}, {TypePostfix});
|
||||
MarkHigherThan({TypePostfix}, {Type});
|
||||
MarkHigherThan({Type}, {If});
|
||||
|
||||
// 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`,
|
||||
// then we will parse `a $ b @ c % d` as `((a $ b) @ c) % d` and should
|
||||
@@ -137,7 +143,9 @@ struct OperatorPriorityTable {
|
||||
|
||||
// For prefix operators, RightFirst would mean `@@x` is `@(@x)` and
|
||||
// Ambiguous would mean it's an error. LeftFirst is meaningless. For now we
|
||||
// allow all prefix operators to be repeated.
|
||||
// allow all prefix operators other than `const` to be repeated.
|
||||
//
|
||||
// TODO: The design does not permit repeating most unary operators.
|
||||
for (PrecedenceLevel prefix :
|
||||
{TermPrefix, NumericPrefix, BitwisePrefix, LogicalPrefix, If}) {
|
||||
table[prefix][prefix] = OperatorPriority::RightFirst;
|
||||
@@ -199,6 +207,7 @@ auto PrecedenceGroup::ForLeading(TokenKind kind)
|
||||
-> std::optional<PrecedenceGroup> {
|
||||
switch (kind) {
|
||||
case TokenKind::Star:
|
||||
case TokenKind::Amp:
|
||||
return PrecedenceGroup(TermPrefix);
|
||||
|
||||
case TokenKind::Not:
|
||||
@@ -215,6 +224,9 @@ auto PrecedenceGroup::ForLeading(TokenKind kind)
|
||||
case TokenKind::If:
|
||||
return PrecedenceGroup(If);
|
||||
|
||||
case TokenKind::Const:
|
||||
return PrecedenceGroup(TypePrefix);
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -288,6 +300,7 @@ auto PrecedenceGroup::ForTrailing(TokenKind kind, bool infix)
|
||||
|
||||
// Prefix-only operators.
|
||||
case TokenKind::Not:
|
||||
case TokenKind::Const:
|
||||
break;
|
||||
|
||||
// Symbolic tokens that might be operators eventually.
|
||||
|
||||
Reference in New Issue
Block a user