1 // Copyright 2016 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.
11 use print
::pprust
::token_to_string
;
12 use parse
::lexer
::StringReader
;
13 use parse
::{token, PResult}
;
15 use tokenstream
::{Delimited, TokenTree}
;
19 impl<'a
> StringReader
<'a
> {
20 // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
21 pub fn parse_all_token_trees(&mut self) -> PResult
<'a
, Vec
<TokenTree
>> {
22 let mut tts
= Vec
::new();
23 while self.token
!= token
::Eof
{
24 tts
.push(self.parse_token_tree()?
);
29 // Parse a stream of tokens into a list of `TokenTree`s, up to a `CloseDelim`.
30 fn parse_token_trees_until_close_delim(&mut self) -> Vec
<TokenTree
> {
33 if let token
::CloseDelim(..) = self.token
{
36 match self.parse_token_tree() {
37 Ok(tt
) => tts
.push(tt
),
46 fn parse_token_tree(&mut self) -> PResult
<'a
, TokenTree
> {
49 let msg
= "this file contains an un-closed delimiter";
50 let mut err
= self.sess
.span_diagnostic
.struct_span_err(self.span
, msg
);
51 for &(_
, sp
) in &self.open_braces
{
52 err
.span_help(sp
, "did you mean to close this delimiter?");
56 token
::OpenDelim(delim
) => {
57 // The span for beginning of the delimited section
58 let pre_span
= self.span
;
60 // Parse the open delimiter.
61 self.open_braces
.push((delim
, self.span
));
64 // Parse the token trees within the delimiters.
65 // We stop at any delimiter so we can try to recover if the user
66 // uses an incorrect delimiter.
67 let tts
= self.parse_token_trees_until_close_delim();
69 // Expand to cover the entire delimited token tree
70 let span
= Span { hi: self.span.hi, ..pre_span }
;
74 token
::CloseDelim(d
) if d
== delim
=> {
75 self.open_braces
.pop().unwrap();
77 // Parse the close delimiter.
80 // Incorrect delimiter.
81 token
::CloseDelim(other
) => {
82 let token_str
= token_to_string(&self.token
);
83 let msg
= format
!("incorrect close delimiter: `{}`", token_str
);
84 let mut err
= self.sess
.span_diagnostic
.struct_span_err(self.span
, &msg
);
85 // This is a conservative error: only report the last unclosed delimiter.
86 // The previous unclosed delimiters could actually be closed! The parser
87 // just hasn't gotten to them yet.
88 if let Some(&(_
, sp
)) = self.open_braces
.last() {
89 err
.span_note(sp
, "unclosed delimiter");
93 self.open_braces
.pop().unwrap();
95 // If the incorrect delimiter matches an earlier opening
96 // delimiter, then don't consume it (it can be used to
97 // close the earlier one). Otherwise, consume it.
98 // E.g., we try to recover from:
101 // } // Incorrect delimiter but matches the earlier `{`
102 if !self.open_braces
.iter().any(|&(b
, _
)| b
== other
) {
107 // Silently recover, the EOF token will be seen again
108 // and an error emitted then. Thus we don't pop from
109 // self.open_braces here.
114 Ok(TokenTree
::Delimited(span
, Rc
::new(Delimited
{
119 token
::CloseDelim(_
) => {
120 // An unexpected closing delimiter (i.e., there is no
121 // matching opening delimiter).
122 let token_str
= token_to_string(&self.token
);
123 let msg
= format
!("unexpected close delimiter: `{}`", token_str
);
124 let err
= self.sess
.span_diagnostic
.struct_span_err(self.span
, &msg
);
128 let tt
= TokenTree
::Token(self.span
, self.token
.clone());