Skip to content

Commit 6e9bf12

Browse files
committed
Reimplement "macros: Improve tt fragments" with better performance.
1 parent 3b71646 commit 6e9bf12

File tree

1 file changed

+61
-18
lines changed

1 file changed

+61
-18
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub struct Parser<'a> {
210210
/// into modules, and sub-parsers have new values for this name.
211211
pub root_module_name: Option<String>,
212212
pub expected_tokens: Vec<TokenType>,
213+
pub tts: Vec<(TokenTree, usize)>,
213214
}
214215

215216
#[derive(PartialEq, Eq, Clone)]
@@ -273,33 +274,71 @@ impl From<P<Expr>> for LhsExpr {
273274
}
274275

275276
impl<'a> Parser<'a> {
276-
pub fn new(sess: &'a ParseSess, mut rdr: Box<Reader+'a>) -> Self {
277-
let tok0 = rdr.real_token();
278-
let span = tok0.sp;
279-
let mut directory = match span {
280-
syntax_pos::DUMMY_SP => PathBuf::new(),
281-
_ => PathBuf::from(sess.codemap().span_to_filename(span)),
282-
};
283-
directory.pop();
284-
285-
Parser {
277+
pub fn new(sess: &'a ParseSess, rdr: Box<Reader+'a>) -> Self {
278+
let mut parser = Parser {
286279
reader: rdr,
287280
sess: sess,
288-
token: tok0.tok,
289-
span: span,
290-
prev_span: span,
281+
token: token::Underscore,
282+
span: syntax_pos::DUMMY_SP,
283+
prev_span: syntax_pos::DUMMY_SP,
291284
prev_token_kind: PrevTokenKind::Other,
292285
lookahead_buffer: Default::default(),
293286
tokens_consumed: 0,
294287
restrictions: Restrictions::empty(),
295288
quote_depth: 0,
296289
parsing_token_tree: false,
297290
obsolete_set: HashSet::new(),
298-
directory: directory,
291+
directory: PathBuf::new(),
299292
open_braces: Vec::new(),
300293
owns_directory: true,
301294
root_module_name: None,
302295
expected_tokens: Vec::new(),
296+
tts: Vec::new(),
297+
};
298+
299+
let tok = parser.next_tok();
300+
parser.token = tok.tok;
301+
parser.span = tok.sp;
302+
if parser.span != syntax_pos::DUMMY_SP {
303+
parser.directory = PathBuf::from(sess.codemap().span_to_filename(parser.span));
304+
parser.directory.pop();
305+
}
306+
parser
307+
}
308+
309+
fn next_tok(&mut self) -> TokenAndSpan {
310+
'outer: loop {
311+
let mut tok = if let Some((tts, i)) = self.tts.pop() {
312+
let tt = tts.get_tt(i);
313+
if i + 1 < tts.len() {
314+
self.tts.push((tts, i + 1));
315+
}
316+
if let TokenTree::Token(sp, tok) = tt {
317+
TokenAndSpan { tok: tok, sp: sp }
318+
} else {
319+
self.tts.push((tt, 0));
320+
continue
321+
}
322+
} else {
323+
self.reader.real_token()
324+
};
325+
326+
loop {
327+
let nt = match tok.tok {
328+
token::Interpolated(ref nt) => nt.clone(),
329+
_ => return tok,
330+
};
331+
match *nt {
332+
token::NtTT(TokenTree::Token(sp, ref t)) => {
333+
tok = TokenAndSpan { tok: t.clone(), sp: sp };
334+
}
335+
token::NtTT(ref tt) => {
336+
self.tts.push((tt.clone(), 0));
337+
continue 'outer
338+
}
339+
_ => return tok,
340+
}
341+
}
303342
}
304343
}
305344

@@ -848,7 +887,7 @@ impl<'a> Parser<'a> {
848887
};
849888

850889
let next = if self.lookahead_buffer.start == self.lookahead_buffer.end {
851-
self.reader.real_token()
890+
self.next_tok()
852891
} else {
853892
// Avoid token copies with `replace`.
854893
let old_start = self.lookahead_buffer.start;
@@ -893,7 +932,7 @@ impl<'a> Parser<'a> {
893932
f(&self.token)
894933
} else if dist < LOOKAHEAD_BUFFER_CAPACITY {
895934
while self.lookahead_buffer.len() < dist {
896-
self.lookahead_buffer.buffer[self.lookahead_buffer.end] = self.reader.real_token();
935+
self.lookahead_buffer.buffer[self.lookahead_buffer.end] = self.next_tok();
897936
self.lookahead_buffer.end =
898937
(self.lookahead_buffer.end + 1) % LOOKAHEAD_BUFFER_CAPACITY;
899938
}
@@ -2653,8 +2692,6 @@ impl<'a> Parser<'a> {
26532692
// and token::SubstNt's; it's too early to know yet
26542693
// whether something will be a nonterminal or a seq
26552694
// yet.
2656-
maybe_whole!(self, NtTT, |x| x);
2657-
26582695
match self.token {
26592696
token::Eof => {
26602697
let mut err: DiagnosticBuilder<'a> =
@@ -2667,6 +2704,12 @@ impl<'a> Parser<'a> {
26672704
Err(err)
26682705
},
26692706
token::OpenDelim(delim) => {
2707+
if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) {
2708+
let tt = self.tts.pop().unwrap().0;
2709+
self.bump();
2710+
return Ok(tt);
2711+
}
2712+
26702713
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);
26712714
// The span for beginning of the delimited section
26722715
let pre_span = self.span;

0 commit comments

Comments
 (0)