diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-08-19 19:30:44 +0300 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-08-19 21:59:33 +0300 |
| commit | 914e1f456415eae0ae095dd39dc51c115c1ffb5a (patch) | |
| tree | 9d9ae8aec35689ca0625e251ad035bac410a9bca /src/libsyntax/parse | |
| parent | 8b932dfda77f8a48f0d134c31c4b33382724a69c (diff) | |
| download | rust-914e1f456415eae0ae095dd39dc51c115c1ffb5a.tar.gz rust-914e1f456415eae0ae095dd39dc51c115c1ffb5a.zip | |
glue tokens when building token stream
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer/tokentrees.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 2 |
2 files changed, 33 insertions, 9 deletions
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index 37e67a2729e..e5ba7e45309 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -39,29 +39,29 @@ struct TokenTreesReader<'a> { impl<'a> TokenTreesReader<'a> { // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`. fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { - let mut tts = Vec::new(); + let mut buf = TokenStreamBuilder::default(); self.real_token(); while self.token != token::Eof { - tts.push(self.parse_token_tree()?); + buf.push(self.parse_token_tree()?); } - Ok(TokenStream::new(tts)) + Ok(buf.into_token_stream()) } // Parse a stream of tokens into a list of `TokenTree`s, up to a `CloseDelim`. fn parse_token_trees_until_close_delim(&mut self) -> TokenStream { - let mut tts = vec![]; + let mut buf = TokenStreamBuilder::default(); loop { if let token::CloseDelim(..) = self.token.kind { - return TokenStream::new(tts); + return buf.into_token_stream(); } match self.parse_token_tree() { - Ok(tree) => tts.push(tree), + Ok(tree) => buf.push(tree), Err(mut e) => { e.emit(); - return TokenStream::new(tts); + return buf.into_token_stream(); } } } @@ -223,8 +223,32 @@ impl<'a> TokenTreesReader<'a> { _ => { self.token = token; return; - }, + } + } + } + } +} + +#[derive(Default)] +struct TokenStreamBuilder { + buf: Vec<TreeAndJoint>, +} + +impl TokenStreamBuilder { + fn push(&mut self, (tree, joint): TreeAndJoint) { + if let Some((TokenTree::Token(prev_token), Joint)) = self.buf.last() { + if let TokenTree::Token(token) = &tree { + if let Some(glued) = prev_token.glue(token) { + self.buf.pop(); + self.buf.push((TokenTree::Token(glued), joint)); + return; + } } } + self.buf.push((tree, joint)) + } + + fn into_token_stream(self) -> TokenStream { + TokenStream::new(self.buf) } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index be800b4de66..1865f925165 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -551,7 +551,7 @@ impl Token { } } - crate fn glue(self, joint: Token) -> Option<Token> { + crate fn glue(&self, joint: &Token) -> Option<Token> { let kind = match self.kind { Eq => match joint.kind { Eq => EqEq, |
