diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-02-20 05:44:06 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-03-03 02:05:57 +0000 |
| commit | 8cd0c0885f841c9bfd0c330e3da21363427010e4 (patch) | |
| tree | f3deee85d2261de9e0b13c8b3dce7eb59e034111 /src/libsyntax/tokenstream.rs | |
| parent | 8dca72be9be71fbccae9370b45af8efb946dedc1 (diff) | |
| download | rust-8cd0c0885f841c9bfd0c330e3da21363427010e4.tar.gz rust-8cd0c0885f841c9bfd0c330e3da21363427010e4.zip | |
Introduce `syntax::parse::parser::TokenCursor`.
Diffstat (limited to 'src/libsyntax/tokenstream.rs')
| -rw-r--r-- | src/libsyntax/tokenstream.rs | 114 |
1 files changed, 46 insertions, 68 deletions
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 552395945a1..083435a0433 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -22,12 +22,11 @@ //! and a borrowed TokenStream is sufficient to build an owned TokenStream without taking //! ownership of the original. -use ast::{self, AttrStyle, LitKind}; +use ast::{self, LitKind}; use syntax_pos::{BytePos, Span, DUMMY_SP}; use codemap::Spanned; use ext::base; use ext::tt::{macro_parser, quoted}; -use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::{self, Directory}; use parse::token::{self, Token, Lit}; use print::pprust; @@ -103,72 +102,6 @@ pub enum TokenTree { } impl TokenTree { - pub fn len(&self) -> usize { - match *self { - TokenTree::Token(_, token::DocComment(name)) => { - match doc_comment_style(&name.as_str()) { - AttrStyle::Outer => 2, - AttrStyle::Inner => 3, - } - } - TokenTree::Delimited(_, ref delimed) => match delimed.delim { - token::NoDelim => delimed.tts.len(), - _ => delimed.tts.len() + 2, - }, - TokenTree::Token(..) => 0, - } - } - - pub fn get_tt(&self, index: usize) -> TokenTree { - match (self, index) { - (&TokenTree::Token(sp, token::DocComment(_)), 0) => TokenTree::Token(sp, token::Pound), - (&TokenTree::Token(sp, token::DocComment(name)), 1) - if doc_comment_style(&name.as_str()) == AttrStyle::Inner => { - TokenTree::Token(sp, token::Not) - } - (&TokenTree::Token(sp, token::DocComment(name)), _) => { - let stripped = strip_doc_comment_decoration(&name.as_str()); - - // Searches for the occurrences of `"#*` and returns the minimum number of `#`s - // required to wrap the text. - let num_of_hashes = stripped.chars() - .scan(0, |cnt, x| { - *cnt = if x == '"' { - 1 - } else if *cnt != 0 && x == '#' { - *cnt + 1 - } else { - 0 - }; - Some(*cnt) - }) - .max() - .unwrap_or(0); - - TokenTree::Delimited(sp, Rc::new(Delimited { - delim: token::Bracket, - tts: vec![TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"))), - TokenTree::Token(sp, token::Eq), - TokenTree::Token(sp, token::Literal( - token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))], - })) - } - (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { - delimed.tts[index].clone() - } - (&TokenTree::Delimited(span, ref delimed), _) => { - if index == 0 { - return delimed.open_tt(span); - } - if index == delimed.tts.len() + 1 { - return delimed.close_tt(span); - } - delimed.tts[index - 1].clone() - } - _ => panic!("Cannot expand a token tree"), - } - } - /// Use this token tree as a matcher to parse given tts. pub fn parse(cx: &base::ExtCtxt, mtch: &[quoted::TokenTree], tts: &[TokenTree]) -> macro_parser::NamedParseResult { @@ -416,6 +349,51 @@ impl Cursor { } }) } + + pub fn original_stream(self) -> TokenStream { + match self.0 { + CursorKind::Empty => TokenStream::empty(), + CursorKind::Tree(tree, _) => tree.into(), + CursorKind::Stream(cursor) => TokenStream::concat_rc_slice({ + cursor.stack.get(0).cloned().map(|(stream, _)| stream).unwrap_or(cursor.stream) + }), + } + } + + pub fn look_ahead(&self, n: usize) -> Option<TokenTree> { + fn look_ahead(streams: &[TokenStream], mut n: usize) -> Result<TokenTree, usize> { + for stream in streams { + n = match stream.kind { + TokenStreamKind::Tree(ref tree) if n == 0 => return Ok(tree.clone()), + TokenStreamKind::Tree(..) => n - 1, + TokenStreamKind::Stream(ref stream) => match look_ahead(stream, n) { + Ok(tree) => return Ok(tree), + Err(n) => n, + }, + _ => n, + }; + } + + Err(n) + } + + match self.0 { + CursorKind::Empty | CursorKind::Tree(_, true) => Err(n), + CursorKind::Tree(ref tree, false) => look_ahead(&[tree.clone().into()], n), + CursorKind::Stream(ref cursor) => { + look_ahead(&cursor.stream[cursor.index ..], n).or_else(|mut n| { + for &(ref stream, index) in cursor.stack.iter().rev() { + n = match look_ahead(&stream[index..], n) { + Ok(tree) => return Ok(tree), + Err(n) => n, + } + } + + Err(n) + }) + } + }.ok() + } } impl fmt::Display for TokenStream { |
