1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::lexer::token::TokenKind;
pub enum Associativity {
Non,
Left,
Right,
}
#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum Precedence {
Lowest,
Print,
Yield,
YieldFrom,
IncDec,
KeyOr,
KeyXor,
KeyAnd,
Assignment,
Ternary,
NullCoalesce,
Or,
And,
BitwiseOr,
BitwiseXor,
BitwiseAnd,
Equality,
LtGt,
Concat,
BitShift,
AddSub,
MulDivMod,
Bang,
Instanceof,
Prefix,
Pow,
CallDim,
ObjectAccess,
CloneOrNew,
}
impl Precedence {
pub fn infix(kind: &TokenKind) -> Self {
use TokenKind::*;
match kind {
Pow => Self::Pow,
Instanceof => Self::Instanceof,
Asterisk | Slash | Percent => Self::MulDivMod,
Plus | Minus => Self::AddSub,
LeftShift | RightShift => Self::BitShift,
Dot => Self::Concat,
LessThan | LessThanEquals | GreaterThan | GreaterThanEquals => Self::LtGt,
DoubleEquals | BangEquals | TripleEquals | BangDoubleEquals | AngledLeftRight
| Spaceship => Self::Equality,
Ampersand => Self::BitwiseAnd,
Caret => Self::BitwiseXor,
Pipe => Self::BitwiseOr,
BooleanAnd => Self::And,
BooleanOr => Self::Or,
DoubleQuestion => Self::NullCoalesce,
Question | QuestionColon => Self::Ternary,
Equals | PlusEquals | MinusEquals | AsteriskEquals | PowEquals | SlashEquals
| DotEquals | AndEquals | DoubleQuestionEquals | PercentEquals | AmpersandEquals
| PipeEquals | CaretEquals | LeftShiftEquals | RightShiftEquals => Self::Assignment,
Yield => Self::Yield,
LogicalAnd => Self::KeyAnd,
LogicalOr => Self::KeyOr,
LogicalXor => Self::KeyXor,
_ => unimplemented!("precedence for op {:?}", kind),
}
}
pub fn postfix(kind: &TokenKind) -> Self {
use TokenKind::*;
match kind {
DoubleQuestion => Self::NullCoalesce,
Increment | Decrement => Self::IncDec,
LeftParen | LeftBracket => Self::CallDim,
Arrow | QuestionArrow | DoubleColon => Self::ObjectAccess,
_ => unimplemented!("postfix precedence for op {:?}", kind),
}
}
pub fn associativity(&self) -> Option<Associativity> {
Some(match self {
Self::Instanceof
| Self::MulDivMod
| Self::AddSub
| Self::BitShift
| Self::Concat
| Self::BitwiseAnd
| Self::BitwiseOr
| Self::BitwiseXor
| Self::And
| Self::Or
| Self::KeyAnd
| Self::KeyOr
| Self::KeyXor => Associativity::Left,
Self::Pow | Self::NullCoalesce | Self::Assignment => Associativity::Right,
Self::Ternary | Self::Equality | Self::LtGt => Associativity::Non,
_ => return None,
})
}
}