Reimplement "macros: Improve tt
fragments" with better performance.
This commit is contained in:
parent
3b71646a60
commit
6e9bf12c6f
1 changed files with 61 additions and 18 deletions
|
@ -210,6 +210,7 @@ pub struct Parser<'a> {
|
||||||
/// into modules, and sub-parsers have new values for this name.
|
/// into modules, and sub-parsers have new values for this name.
|
||||||
pub root_module_name: Option<String>,
|
pub root_module_name: Option<String>,
|
||||||
pub expected_tokens: Vec<TokenType>,
|
pub expected_tokens: Vec<TokenType>,
|
||||||
|
pub tts: Vec<(TokenTree, usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
|
@ -273,21 +274,13 @@ impl From<P<Expr>> for LhsExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub fn new(sess: &'a ParseSess, mut rdr: Box<Reader+'a>) -> Self {
|
pub fn new(sess: &'a ParseSess, rdr: Box<Reader+'a>) -> Self {
|
||||||
let tok0 = rdr.real_token();
|
let mut parser = Parser {
|
||||||
let span = tok0.sp;
|
|
||||||
let mut directory = match span {
|
|
||||||
syntax_pos::DUMMY_SP => PathBuf::new(),
|
|
||||||
_ => PathBuf::from(sess.codemap().span_to_filename(span)),
|
|
||||||
};
|
|
||||||
directory.pop();
|
|
||||||
|
|
||||||
Parser {
|
|
||||||
reader: rdr,
|
reader: rdr,
|
||||||
sess: sess,
|
sess: sess,
|
||||||
token: tok0.tok,
|
token: token::Underscore,
|
||||||
span: span,
|
span: syntax_pos::DUMMY_SP,
|
||||||
prev_span: span,
|
prev_span: syntax_pos::DUMMY_SP,
|
||||||
prev_token_kind: PrevTokenKind::Other,
|
prev_token_kind: PrevTokenKind::Other,
|
||||||
lookahead_buffer: Default::default(),
|
lookahead_buffer: Default::default(),
|
||||||
tokens_consumed: 0,
|
tokens_consumed: 0,
|
||||||
|
@ -295,11 +288,57 @@ impl<'a> Parser<'a> {
|
||||||
quote_depth: 0,
|
quote_depth: 0,
|
||||||
parsing_token_tree: false,
|
parsing_token_tree: false,
|
||||||
obsolete_set: HashSet::new(),
|
obsolete_set: HashSet::new(),
|
||||||
directory: directory,
|
directory: PathBuf::new(),
|
||||||
open_braces: Vec::new(),
|
open_braces: Vec::new(),
|
||||||
owns_directory: true,
|
owns_directory: true,
|
||||||
root_module_name: None,
|
root_module_name: None,
|
||||||
expected_tokens: Vec::new(),
|
expected_tokens: Vec::new(),
|
||||||
|
tts: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let tok = parser.next_tok();
|
||||||
|
parser.token = tok.tok;
|
||||||
|
parser.span = tok.sp;
|
||||||
|
if parser.span != syntax_pos::DUMMY_SP {
|
||||||
|
parser.directory = PathBuf::from(sess.codemap().span_to_filename(parser.span));
|
||||||
|
parser.directory.pop();
|
||||||
|
}
|
||||||
|
parser
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_tok(&mut self) -> TokenAndSpan {
|
||||||
|
'outer: loop {
|
||||||
|
let mut tok = if let Some((tts, i)) = self.tts.pop() {
|
||||||
|
let tt = tts.get_tt(i);
|
||||||
|
if i + 1 < tts.len() {
|
||||||
|
self.tts.push((tts, i + 1));
|
||||||
|
}
|
||||||
|
if let TokenTree::Token(sp, tok) = tt {
|
||||||
|
TokenAndSpan { tok: tok, sp: sp }
|
||||||
|
} else {
|
||||||
|
self.tts.push((tt, 0));
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.reader.real_token()
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let nt = match tok.tok {
|
||||||
|
token::Interpolated(ref nt) => nt.clone(),
|
||||||
|
_ => return tok,
|
||||||
|
};
|
||||||
|
match *nt {
|
||||||
|
token::NtTT(TokenTree::Token(sp, ref t)) => {
|
||||||
|
tok = TokenAndSpan { tok: t.clone(), sp: sp };
|
||||||
|
}
|
||||||
|
token::NtTT(ref tt) => {
|
||||||
|
self.tts.push((tt.clone(), 0));
|
||||||
|
continue 'outer
|
||||||
|
}
|
||||||
|
_ => return tok,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +887,7 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let next = if self.lookahead_buffer.start == self.lookahead_buffer.end {
|
let next = if self.lookahead_buffer.start == self.lookahead_buffer.end {
|
||||||
self.reader.real_token()
|
self.next_tok()
|
||||||
} else {
|
} else {
|
||||||
// Avoid token copies with `replace`.
|
// Avoid token copies with `replace`.
|
||||||
let old_start = self.lookahead_buffer.start;
|
let old_start = self.lookahead_buffer.start;
|
||||||
|
@ -893,7 +932,7 @@ impl<'a> Parser<'a> {
|
||||||
f(&self.token)
|
f(&self.token)
|
||||||
} else if dist < LOOKAHEAD_BUFFER_CAPACITY {
|
} else if dist < LOOKAHEAD_BUFFER_CAPACITY {
|
||||||
while self.lookahead_buffer.len() < dist {
|
while self.lookahead_buffer.len() < dist {
|
||||||
self.lookahead_buffer.buffer[self.lookahead_buffer.end] = self.reader.real_token();
|
self.lookahead_buffer.buffer[self.lookahead_buffer.end] = self.next_tok();
|
||||||
self.lookahead_buffer.end =
|
self.lookahead_buffer.end =
|
||||||
(self.lookahead_buffer.end + 1) % LOOKAHEAD_BUFFER_CAPACITY;
|
(self.lookahead_buffer.end + 1) % LOOKAHEAD_BUFFER_CAPACITY;
|
||||||
}
|
}
|
||||||
|
@ -2653,8 +2692,6 @@ impl<'a> Parser<'a> {
|
||||||
// and token::SubstNt's; it's too early to know yet
|
// and token::SubstNt's; it's too early to know yet
|
||||||
// whether something will be a nonterminal or a seq
|
// whether something will be a nonterminal or a seq
|
||||||
// yet.
|
// yet.
|
||||||
maybe_whole!(self, NtTT, |x| x);
|
|
||||||
|
|
||||||
match self.token {
|
match self.token {
|
||||||
token::Eof => {
|
token::Eof => {
|
||||||
let mut err: DiagnosticBuilder<'a> =
|
let mut err: DiagnosticBuilder<'a> =
|
||||||
|
@ -2667,6 +2704,12 @@ impl<'a> Parser<'a> {
|
||||||
Err(err)
|
Err(err)
|
||||||
},
|
},
|
||||||
token::OpenDelim(delim) => {
|
token::OpenDelim(delim) => {
|
||||||
|
if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) {
|
||||||
|
let tt = self.tts.pop().unwrap().0;
|
||||||
|
self.bump();
|
||||||
|
return Ok(tt);
|
||||||
|
}
|
||||||
|
|
||||||
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);
|
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);
|
||||||
// The span for beginning of the delimited section
|
// The span for beginning of the delimited section
|
||||||
let pre_span = self.span;
|
let pre_span = self.span;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue