1 // Copyright 2012 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.
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.
14 use codemap
::{BytePos, spanned}
;
15 use parse
::lexer
::reader
;
16 use parse
::parser
::Parser
;
19 use core
::option
::{None, Option, Some}
;
24 // SeqSep : a sequence separator (token)
25 // and whether a trailing separator is allowed.
27 sep
: Option
<token
::Token
>,
28 trailing_sep_allowed
: bool
31 pub fn seq_sep_trailing_disallowed(+t
: token
::Token
) -> SeqSep
{
34 trailing_sep_allowed
: false,
37 pub fn seq_sep_trailing_allowed(+t
: token
::Token
) -> SeqSep
{
40 trailing_sep_allowed
: true,
43 pub fn seq_sep_none() -> SeqSep
{
46 trailing_sep_allowed
: false,
50 pub fn token_to_str(reader
: @reader
, token
: &token
::Token
) -> ~str {
51 token
::to_str(reader
.interner(), token
)
55 fn unexpected_last(&self, t
: &token
::Token
) -> ! {
59 "unexpected token: `%s`",
60 token_to_str(self.reader
, t
)
65 fn unexpected(&self) -> ! {
68 "unexpected token: `%s`",
69 token_to_str(self.reader
, ©
*self.token
)
74 // expect and consume the token t. Signal an error if
75 // the next token is not t.
76 fn expect(&self, t
: &token
::Token
) {
77 if *self.token
== *t
{
82 "expected `%s` but found `%s`",
83 token_to_str(self.reader
, t
),
84 token_to_str(self.reader
, ©
*self.token
)
90 fn parse_ident(&self) -> ast
::ident
{
91 self.check_strict_keywords();
92 self.check_reserved_keywords();
94 token
::IDENT(i
, _
) => {
98 token
::INTERPOLATED(token
::nt_ident(*)) => {
100 ~"ident interpolation not converted to real token"
106 "expected ident, found `%s`",
107 token_to_str(self.reader
, ©
*self.token
)
114 fn parse_path_list_ident(&self) -> ast
::path_list_ident
{
115 let lo
= self.span
.lo
;
116 let ident
= self.parse_ident();
117 let hi
= self.span
.hi
;
118 spanned(lo
, hi
, ast
::path_list_ident_
{ name
: ident
,
122 // consume token 'tok' if it exists. Returns true if the given
123 // token was present, false otherwise.
124 fn eat(&self, tok
: &token
::Token
) -> bool
{
125 return if *self.token
== *tok { self.bump(); true }
else { false }
;
128 // Storing keywords as interned idents instead of strings would be nifty.
130 // A sanity check that the word we are asking for is a known keyword
131 fn require_keyword(&self, word
: &~str) {
132 if !self.keywords
.contains(word
) {
133 self.bug(fmt
!("unknown keyword: %s", *word
));
137 fn token_is_word(&self, word
: &~str, tok
: &token
::Token
) -> bool
{
139 token
::IDENT(sid
, false) => { *self.id_to_str(sid) == *word }
144 fn token_is_keyword(&self, word
: &~str, tok
: &token
::Token
) -> bool
{
145 self.require_keyword(word
);
146 self.token_is_word(word
, tok
)
149 fn is_keyword(&self, word
: &~str) -> bool
{
150 self.token_is_keyword(word
, ©
*self.token
)
153 fn is_any_keyword(&self, tok
: &token
::Token
) -> bool
{
155 token
::IDENT(sid
, false) => {
156 self.keywords
.contains(self.id_to_str(sid
))
162 fn eat_keyword(&self, word
: &~str) -> bool
{
163 self.require_keyword(word
);
164 let is_kw
= match *self.token
{
165 token
::IDENT(sid
, false) => *word
== *self.id_to_str(sid
),
168 if is_kw { self.bump() }
172 fn expect_keyword(&self, word
: &~str) {
173 self.require_keyword(word
);
174 if !self.eat_keyword(word
) {
177 "expected `%s`, found `%s`",
179 token_to_str(self.reader
, ©
*self.token
)
185 fn is_strict_keyword(&self, word
: &~str) -> bool
{
186 self.strict_keywords
.contains(word
)
189 fn check_strict_keywords(&self) {
191 token
::IDENT(_
, false) => {
192 let w
= token_to_str(self.reader
, ©
*self.token
);
193 self.check_strict_keywords_(&w
);
199 fn check_strict_keywords_(&self, w
: &~str) {
200 if self.is_strict_keyword(w
) {
201 self.fatal(fmt
!("found `%s` in ident position", *w
));
205 fn is_reserved_keyword(&self, word
: &~str) -> bool
{
206 self.reserved_keywords
.contains(word
)
209 fn check_reserved_keywords(&self) {
211 token
::IDENT(_
, false) => {
212 let w
= token_to_str(self.reader
, ©
*self.token
);
213 self.check_reserved_keywords_(&w
);
219 fn check_reserved_keywords_(&self, w
: &~str) {
220 if self.is_reserved_keyword(w
) {
221 self.fatal(fmt
!("`%s` is a reserved keyword", *w
));
225 // expect and consume a GT. if a >> is seen, replace it
226 // with a single > and continue.
227 fn expect_gt(&self) {
228 if *self.token
== token
::GT
{
230 } else if *self.token
== token
::BINOP(token
::SHR
) {
233 self.span
.lo
+ BytePos(1u),
237 let mut s
: ~str = ~"expected `";
238 s
+= token_to_str(self.reader
, &token
::GT
);
240 s
+= token_to_str(self.reader
, ©
*self.token
);
246 // parse a sequence bracketed by '<' and '>', stopping
248 fn parse_seq_to_before_gt
<T
: Copy
>(
250 sep
: Option
<token
::Token
>,
253 let mut first
= true;
254 let mut v
= opt_vec
::Empty
;
255 while *self.token
!= token
::GT
256 && *self.token
!= token
::BINOP(token
::SHR
) {
259 if first { first = false; }
260 else { self.expect(t); }
269 fn parse_seq_to_gt
<T
: Copy
>(
271 sep
: Option
<token
::Token
>,
274 let v
= self.parse_seq_to_before_gt(sep
, f
);
279 // parse a sequence, including the closing delimiter. The function
280 // f must consume tokens until reaching the next separator or
282 fn parse_seq_to_end
<T
: Copy
>(
288 let val
= self.parse_seq_to_before_end(ket
, sep
, f
);
293 // parse a sequence, not including the closing delimiter. The function
294 // f must consume tokens until reaching the next separator or
296 fn parse_seq_to_before_end
<T
: Copy
>(
302 let mut first
: bool
= true;
303 let mut v
: ~[T
] = ~[];
304 while *self.token
!= *ket
{
307 if first { first = false; }
308 else { self.expect(t); }
312 if sep
.trailing_sep_allowed
&& *self.token
== *ket { break; }
318 // parse a sequence, including the closing delimiter. The function
319 // f must consume tokens until reaching the next separator or
321 fn parse_unspanned_seq
<T
: Copy
>(
329 let result
= self.parse_seq_to_before_end(ket
, sep
, f
);
334 // NB: Do not use this function unless you actually plan to place the
335 // spanned list in the AST.
336 fn parse_seq
<T
: Copy
>(
343 let lo
= self.span
.lo
;
345 let result
= self.parse_seq_to_before_end(ket
, sep
, f
);
346 let hi
= self.span
.hi
;
348 spanned(lo
, hi
, result
)