]> git.proxmox.com Git - rustc.git/blame - src/libsyntax/util/parser.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libsyntax / util / parser.rs
CommitLineData
92a42be0
SL
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10use parse::token::{Token, BinOpToken, keywords};
7453a54e 11use ast::BinOpKind;
92a42be0
SL
12
13/// Associative operator with precedence.
14///
15/// This is the enum which specifies operator precedence and fixity to the parser.
16#[derive(Debug, PartialEq, Eq)]
17pub enum AssocOp {
18 /// `+`
19 Add,
20 /// `-`
21 Subtract,
22 /// `*`
23 Multiply,
24 /// `/`
25 Divide,
26 /// `%`
27 Modulus,
28 /// `&&`
29 LAnd,
30 /// `||`
31 LOr,
32 /// `^`
33 BitXor,
34 /// `&`
35 BitAnd,
36 /// `|`
37 BitOr,
38 /// `<<`
39 ShiftLeft,
40 /// `>>`
41 ShiftRight,
42 /// `==`
43 Equal,
44 /// `<`
45 Less,
46 /// `<=`
47 LessEqual,
48 /// `!=`
49 NotEqual,
50 /// `>`
51 Greater,
52 /// `>=`
53 GreaterEqual,
54 /// `=`
55 Assign,
56 /// `<-`
57 Inplace,
58 /// `?=` where ? is one of the BinOpToken
59 AssignOp(BinOpToken),
60 /// `as`
61 As,
62 /// `..` range
9cc50fc6 63 DotDot,
54a0048b
SL
64 /// `...` range
65 DotDotDot,
9cc50fc6
SL
66 /// `:`
67 Colon,
92a42be0
SL
68}
69
70#[derive(Debug, PartialEq, Eq)]
71pub enum Fixity {
72 /// The operator is left-associative
73 Left,
74 /// The operator is right-associative
75 Right,
76 /// The operator is not associative
77 None
78}
79
80impl AssocOp {
81 /// Create a new AssocOP from a token
82 pub fn from_token(t: &Token) -> Option<AssocOp> {
83 use self::AssocOp::*;
84 match *t {
85 Token::BinOpEq(k) => Some(AssignOp(k)),
86 Token::LArrow => Some(Inplace),
87 Token::Eq => Some(Assign),
88 Token::BinOp(BinOpToken::Star) => Some(Multiply),
89 Token::BinOp(BinOpToken::Slash) => Some(Divide),
90 Token::BinOp(BinOpToken::Percent) => Some(Modulus),
91 Token::BinOp(BinOpToken::Plus) => Some(Add),
92 Token::BinOp(BinOpToken::Minus) => Some(Subtract),
93 Token::BinOp(BinOpToken::Shl) => Some(ShiftLeft),
94 Token::BinOp(BinOpToken::Shr) => Some(ShiftRight),
95 Token::BinOp(BinOpToken::And) => Some(BitAnd),
96 Token::BinOp(BinOpToken::Caret) => Some(BitXor),
97 Token::BinOp(BinOpToken::Or) => Some(BitOr),
98 Token::Lt => Some(Less),
99 Token::Le => Some(LessEqual),
100 Token::Ge => Some(GreaterEqual),
101 Token::Gt => Some(Greater),
102 Token::EqEq => Some(Equal),
103 Token::Ne => Some(NotEqual),
104 Token::AndAnd => Some(LAnd),
105 Token::OrOr => Some(LOr),
106 Token::DotDot => Some(DotDot),
54a0048b 107 Token::DotDotDot => Some(DotDotDot),
9cc50fc6 108 Token::Colon => Some(Colon),
92a42be0
SL
109 _ if t.is_keyword(keywords::As) => Some(As),
110 _ => None
111 }
112 }
113
7453a54e
SL
114 /// Create a new AssocOp from ast::BinOpKind.
115 pub fn from_ast_binop(op: BinOpKind) -> Self {
92a42be0
SL
116 use self::AssocOp::*;
117 match op {
7453a54e
SL
118 BinOpKind::Lt => Less,
119 BinOpKind::Gt => Greater,
120 BinOpKind::Le => LessEqual,
121 BinOpKind::Ge => GreaterEqual,
122 BinOpKind::Eq => Equal,
123 BinOpKind::Ne => NotEqual,
124 BinOpKind::Mul => Multiply,
125 BinOpKind::Div => Divide,
126 BinOpKind::Rem => Modulus,
127 BinOpKind::Add => Add,
128 BinOpKind::Sub => Subtract,
129 BinOpKind::Shl => ShiftLeft,
130 BinOpKind::Shr => ShiftRight,
131 BinOpKind::BitAnd => BitAnd,
132 BinOpKind::BitXor => BitXor,
133 BinOpKind::BitOr => BitOr,
134 BinOpKind::And => LAnd,
135 BinOpKind::Or => LOr
92a42be0
SL
136 }
137 }
138
139 /// Gets the precedence of this operator
140 pub fn precedence(&self) -> usize {
141 use self::AssocOp::*;
142 match *self {
9cc50fc6 143 As | Colon => 14,
92a42be0
SL
144 Multiply | Divide | Modulus => 13,
145 Add | Subtract => 12,
146 ShiftLeft | ShiftRight => 11,
147 BitAnd => 10,
148 BitXor => 9,
149 BitOr => 8,
150 Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => 7,
151 LAnd => 6,
152 LOr => 5,
54a0048b 153 DotDot | DotDotDot => 4,
92a42be0
SL
154 Inplace => 3,
155 Assign | AssignOp(_) => 2,
156 }
157 }
158
159 /// Gets the fixity of this operator
160 pub fn fixity(&self) -> Fixity {
161 use self::AssocOp::*;
162 // NOTE: it is a bug to have an operators that has same precedence but different fixities!
163 match *self {
164 Inplace | Assign | AssignOp(_) => Fixity::Right,
165 As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
166 BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
9cc50fc6 167 LAnd | LOr | Colon => Fixity::Left,
54a0048b 168 DotDot | DotDotDot => Fixity::None
92a42be0
SL
169 }
170 }
171
172 pub fn is_comparison(&self) -> bool {
173 use self::AssocOp::*;
174 match *self {
175 Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
176 Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
54a0048b
SL
177 ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr |
178 DotDot | DotDotDot | Colon => false
92a42be0
SL
179 }
180 }
181
182 pub fn is_assign_like(&self) -> bool {
183 use self::AssocOp::*;
184 match *self {
185 Assign | AssignOp(_) | Inplace => true,
186 Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
187 Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
54a0048b 188 LOr | DotDot | DotDotDot | Colon => false
92a42be0
SL
189 }
190 }
191
7453a54e 192 pub fn to_ast_binop(&self) -> Option<BinOpKind> {
92a42be0
SL
193 use self::AssocOp::*;
194 match *self {
7453a54e
SL
195 Less => Some(BinOpKind::Lt),
196 Greater => Some(BinOpKind::Gt),
197 LessEqual => Some(BinOpKind::Le),
198 GreaterEqual => Some(BinOpKind::Ge),
199 Equal => Some(BinOpKind::Eq),
200 NotEqual => Some(BinOpKind::Ne),
201 Multiply => Some(BinOpKind::Mul),
202 Divide => Some(BinOpKind::Div),
203 Modulus => Some(BinOpKind::Rem),
204 Add => Some(BinOpKind::Add),
205 Subtract => Some(BinOpKind::Sub),
206 ShiftLeft => Some(BinOpKind::Shl),
207 ShiftRight => Some(BinOpKind::Shr),
208 BitAnd => Some(BinOpKind::BitAnd),
209 BitXor => Some(BinOpKind::BitXor),
210 BitOr => Some(BinOpKind::BitOr),
211 LAnd => Some(BinOpKind::And),
212 LOr => Some(BinOpKind::Or),
54a0048b 213 Inplace | Assign | AssignOp(_) | As | DotDot | DotDotDot | Colon => None
92a42be0
SL
214 }
215 }
92a42be0 216}