Skip to content

Commit d29f0d2

Browse files
committed
Move token tree related lexer state to a separate struct
We only used a bunch of fields when tokenizing into a token tree, so let's move them out of the base lexer
1 parent efa3c27 commit d29f0d2

File tree

3 files changed

+71
-48
lines changed

3 files changed

+71
-48
lines changed

src/libsyntax/parse/lexer/mod.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,7 @@ pub struct StringReader<'a> {
6666
span: Span,
6767
/// The raw source span which *does not* take `override_span` into account
6868
span_src_raw: Span,
69-
/// Stack of open delimiters and their spans. Used for error message.
70-
open_braces: Vec<(token::DelimToken, Span)>,
71-
crate unmatched_braces: Vec<UnmatchedBrace>,
72-
/// The type and spans for all braces
73-
///
74-
/// Used only for error recovery when arriving to EOF with mismatched braces.
75-
matching_delim_spans: Vec<(token::DelimToken, Span, Span)>,
76-
crate override_span: Option<Span>,
77-
last_unclosed_found_span: Option<Span>,
69+
override_span: Option<Span>,
7870
}
7971

8072
impl<'a> StringReader<'a> {
@@ -254,11 +246,7 @@ impl<'a> StringReader<'a> {
254246
token: token::Eof,
255247
span: syntax_pos::DUMMY_SP,
256248
span_src_raw: syntax_pos::DUMMY_SP,
257-
open_braces: Vec::new(),
258-
unmatched_braces: Vec::new(),
259-
matching_delim_spans: Vec::new(),
260249
override_span,
261-
last_unclosed_found_span: None,
262250
}
263251
}
264252

src/libsyntax/parse/lexer/tokentrees.rs

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
1+
use syntax_pos::Span;
2+
13
use crate::print::pprust::token_to_string;
24
use crate::parse::lexer::{StringReader, UnmatchedBrace};
35
use crate::parse::{token, PResult};
46
use crate::tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree, TreeAndJoint};
57

68
impl<'a> StringReader<'a> {
9+
crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec<UnmatchedBrace>) {
10+
let mut tt_reader = TokenTreesReader {
11+
string_reader: self,
12+
open_braces: Vec::new(),
13+
unmatched_braces: Vec::new(),
14+
matching_delim_spans: Vec::new(),
15+
last_unclosed_found_span: None,
16+
};
17+
let res = tt_reader.parse_all_token_trees();
18+
(res, tt_reader.unmatched_braces)
19+
}
20+
}
21+
22+
struct TokenTreesReader<'a> {
23+
string_reader: StringReader<'a>,
24+
/// Stack of open delimiters and their spans. Used for error message.
25+
open_braces: Vec<(token::DelimToken, Span)>,
26+
unmatched_braces: Vec<UnmatchedBrace>,
27+
/// The type and spans for all braces
28+
///
29+
/// Used only for error recovery when arriving to EOF with mismatched braces.
30+
matching_delim_spans: Vec<(token::DelimToken, Span, Span)>,
31+
last_unclosed_found_span: Option<Span>,
32+
}
33+
34+
impl<'a> TokenTreesReader<'a> {
735
// Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
8-
crate fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
36+
fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
937
let mut tts = Vec::new();
1038

11-
while self.token != token::Eof {
39+
while self.string_reader.token != token::Eof {
1240
tts.push(self.parse_token_tree()?);
1341
}
1442

@@ -19,7 +47,7 @@ impl<'a> StringReader<'a> {
1947
fn parse_token_trees_until_close_delim(&mut self) -> TokenStream {
2048
let mut tts = vec![];
2149
loop {
22-
if let token::CloseDelim(..) = self.token {
50+
if let token::CloseDelim(..) = self.string_reader.token {
2351
return TokenStream::new(tts);
2452
}
2553

@@ -34,25 +62,25 @@ impl<'a> StringReader<'a> {
3462
}
3563

3664
fn parse_token_tree(&mut self) -> PResult<'a, TreeAndJoint> {
37-
let sm = self.sess.source_map();
38-
match self.token {
65+
let sm = self.string_reader.sess.source_map();
66+
match self.string_reader.token {
3967
token::Eof => {
4068
let msg = "this file contains an un-closed delimiter";
41-
let mut err = self.sess.span_diagnostic.struct_span_err(self.span, msg);
69+
let mut err = self.string_reader.sess.span_diagnostic
70+
.struct_span_err(self.span(), msg);
4271
for &(_, sp) in &self.open_braces {
4372
err.span_label(sp, "un-closed delimiter");
4473
}
4574

4675
if let Some((delim, _)) = self.open_braces.last() {
4776
if let Some((_, open_sp, close_sp)) = self.matching_delim_spans.iter()
4877
.filter(|(d, open_sp, close_sp)| {
49-
50-
if let Some(close_padding) = sm.span_to_margin(*close_sp) {
51-
if let Some(open_padding) = sm.span_to_margin(*open_sp) {
52-
return delim == d && close_padding != open_padding;
78+
if let Some(close_padding) = sm.span_to_margin(*close_sp) {
79+
if let Some(open_padding) = sm.span_to_margin(*open_sp) {
80+
return delim == d && close_padding != open_padding;
81+
}
5382
}
54-
}
55-
false
83+
false
5684
}).next() // these are in reverse order as they get inserted on close, but
5785
{ // we want the last open/first close
5886
err.span_label(
@@ -69,21 +97,21 @@ impl<'a> StringReader<'a> {
6997
},
7098
token::OpenDelim(delim) => {
7199
// The span for beginning of the delimited section
72-
let pre_span = self.span;
100+
let pre_span = self.span();
73101

74102
// Parse the open delimiter.
75-
self.open_braces.push((delim, self.span));
76-
self.real_token();
103+
self.open_braces.push((delim, self.span()));
104+
self.string_reader.real_token();
77105

78106
// Parse the token trees within the delimiters.
79107
// We stop at any delimiter so we can try to recover if the user
80108
// uses an incorrect delimiter.
81109
let tts = self.parse_token_trees_until_close_delim();
82110

83111
// Expand to cover the entire delimited token tree
84-
let delim_span = DelimSpan::from_pair(pre_span, self.span);
112+
let delim_span = DelimSpan::from_pair(pre_span, self.span());
85113

86-
match self.token {
114+
match self.string_reader.token {
87115
// Correct delimiter.
88116
token::CloseDelim(d) if d == delim => {
89117
let (open_brace, open_brace_span) = self.open_braces.pop().unwrap();
@@ -93,26 +121,26 @@ impl<'a> StringReader<'a> {
93121
self.matching_delim_spans.clear();
94122
} else {
95123
self.matching_delim_spans.push(
96-
(open_brace, open_brace_span, self.span),
124+
(open_brace, open_brace_span, self.span()),
97125
);
98126
}
99127
// Parse the close delimiter.
100-
self.real_token();
128+
self.string_reader.real_token();
101129
}
102130
// Incorrect delimiter.
103131
token::CloseDelim(other) => {
104132
let mut unclosed_delimiter = None;
105133
let mut candidate = None;
106-
if self.last_unclosed_found_span != Some(self.span) {
134+
if self.last_unclosed_found_span != Some(self.span()) {
107135
// do not complain about the same unclosed delimiter multiple times
108-
self.last_unclosed_found_span = Some(self.span);
136+
self.last_unclosed_found_span = Some(self.span());
109137
// This is a conservative error: only report the last unclosed
110138
// delimiter. The previous unclosed delimiters could actually be
111139
// closed! The parser just hasn't gotten to them yet.
112140
if let Some(&(_, sp)) = self.open_braces.last() {
113141
unclosed_delimiter = Some(sp);
114142
};
115-
if let Some(current_padding) = sm.span_to_margin(self.span) {
143+
if let Some(current_padding) = sm.span_to_margin(self.span()) {
116144
for (brace, brace_span) in &self.open_braces {
117145
if let Some(padding) = sm.span_to_margin(*brace_span) {
118146
// high likelihood of these two corresponding
@@ -126,7 +154,7 @@ impl<'a> StringReader<'a> {
126154
self.unmatched_braces.push(UnmatchedBrace {
127155
expected_delim: tok,
128156
found_delim: other,
129-
found_span: self.span,
157+
found_span: self.span(),
130158
unclosed_span: unclosed_delimiter,
131159
candidate_span: candidate,
132160
});
@@ -142,7 +170,7 @@ impl<'a> StringReader<'a> {
142170
// bar(baz(
143171
// } // Incorrect delimiter but matches the earlier `{`
144172
if !self.open_braces.iter().any(|&(b, _)| b == other) {
145-
self.real_token();
173+
self.string_reader.real_token();
146174
}
147175
}
148176
token::Eof => {
@@ -162,22 +190,28 @@ impl<'a> StringReader<'a> {
162190
token::CloseDelim(_) => {
163191
// An unexpected closing delimiter (i.e., there is no
164192
// matching opening delimiter).
165-
let token_str = token_to_string(&self.token);
193+
let token_str = token_to_string(&self.string_reader.token);
166194
let msg = format!("unexpected close delimiter: `{}`", token_str);
167-
let mut err = self.sess.span_diagnostic.struct_span_err(self.span, &msg);
168-
err.span_label(self.span, "unexpected close delimiter");
195+
let mut err = self.string_reader.sess.span_diagnostic
196+
.struct_span_err(self.span(), &msg);
197+
err.span_label(self.span(), "unexpected close delimiter");
169198
Err(err)
170199
},
171200
_ => {
172-
let tt = TokenTree::Token(self.span, self.token.clone());
201+
let tt = TokenTree::Token(self.span(), self.string_reader.token.clone());
173202
// Note that testing for joint-ness here is done via the raw
174203
// source span as the joint-ness is a property of the raw source
175204
// rather than wanting to take `override_span` into account.
176-
let raw = self.span_src_raw;
177-
self.real_token();
178-
let is_joint = raw.hi() == self.span_src_raw.lo() && token::is_op(&self.token);
205+
let raw = self.string_reader.span_src_raw;
206+
self.string_reader.real_token();
207+
let is_joint = raw.hi() == self.string_reader.span_src_raw.lo()
208+
&& token::is_op(&self.string_reader.token);
179209
Ok((tt, if is_joint { Joint } else { NonJoint }))
180210
}
181211
}
182212
}
213+
214+
fn span(&self) -> Span {
215+
self.string_reader.span
216+
}
183217
}

src/libsyntax/parse/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,22 +295,23 @@ pub fn source_file_to_stream(
295295
}
296296

297297
/// Given a source file, produces a sequence of token trees. Returns any buffered errors from
298-
/// parsing the token tream.
298+
/// parsing the token stream.
299299
pub fn maybe_file_to_stream(
300300
sess: &ParseSess,
301301
source_file: Lrc<SourceFile>,
302302
override_span: Option<Span>,
303303
) -> Result<(TokenStream, Vec<lexer::UnmatchedBrace>), Vec<Diagnostic>> {
304304
let mut srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?;
305305
srdr.real_token();
306+
let (token_trees, unmatched_braces) = srdr.into_token_trees();
306307

307-
match srdr.parse_all_token_trees() {
308-
Ok(stream) => Ok((stream, srdr.unmatched_braces)),
308+
match token_trees {
309+
Ok(stream) => Ok((stream, unmatched_braces)),
309310
Err(err) => {
310311
let mut buffer = Vec::with_capacity(1);
311312
err.buffer(&mut buffer);
312313
// Not using `emit_unclosed_delims` to use `db.buffer`
313-
for unmatched in srdr.unmatched_braces {
314+
for unmatched in unmatched_braces {
314315
let mut db = sess.span_diagnostic.struct_span_err(unmatched.found_span, &format!(
315316
"incorrect close delimiter: `{}`",
316317
token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),

0 commit comments

Comments
 (0)