diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-01-29 08:38:44 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-02-28 22:14:29 +0000 |
| commit | d8b34e9a74a4e91c4283ba4002a050ac0150cec6 (patch) | |
| tree | fc62b9e970fd9120e078856dd6c9727bcb55ac89 /src/libsyntax/parse/parser.rs | |
| parent | 247188803356234ae5d6ecf947ffb2308688dc90 (diff) | |
| download | rust-d8b34e9a74a4e91c4283ba4002a050ac0150cec6.tar.gz rust-d8b34e9a74a4e91c4283ba4002a050ac0150cec6.zip | |
Add `syntax::ext::tt::quoted::{TokenTree, ..}` and remove `tokenstream::TokenTree::Sequence`.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 161 |
1 files changed, 13 insertions, 148 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3a3c20dfb64..ab965e27633 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -43,19 +43,16 @@ use {ast, attr}; use codemap::{self, CodeMap, Spanned, spanned, respan}; use syntax_pos::{self, Span, Pos, BytePos, mk_sp}; use errors::{self, DiagnosticBuilder}; -use ext::tt::macro_parser; -use parse; -use parse::classify; +use parse::{self, classify, token}; use parse::common::SeqSep; use parse::lexer::TokenAndSpan; use parse::obsolete::ObsoleteSyntax; -use parse::token::{self, MatchNt, SubstNt}; use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}; use util::parser::{AssocOp, Fixity}; use print::pprust; use ptr::P; use parse::PResult; -use tokenstream::{self, Delimited, SequenceRepetition, TokenTree}; +use tokenstream::{Delimited, TokenTree}; use symbol::{Symbol, keywords}; use util::ThinVec; @@ -168,8 +165,6 @@ pub struct Parser<'a> { /// the previous token kind prev_token_kind: PrevTokenKind, pub restrictions: Restrictions, - pub quote_depth: usize, // not (yet) related to the quasiquoter - parsing_token_tree: bool, /// The set of seen errors about obsolete syntax. Used to suppress /// extra detail when the same error is seen twice pub obsolete_set: HashSet<ObsoleteSyntax>, @@ -329,8 +324,6 @@ impl<'a> Parser<'a> { prev_span: syntax_pos::DUMMY_SP, prev_token_kind: PrevTokenKind::Other, restrictions: Restrictions::empty(), - quote_depth: 0, - parsing_token_tree: false, obsolete_set: HashSet::new(), directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned }, root_module_name: None, @@ -359,20 +352,11 @@ impl<'a> Parser<'a> { if i + 1 < tts.len() { self.tts.push((tts, i + 1)); } - // FIXME(jseyfried): remove after fixing #39390 in #39419. - if self.quote_depth > 0 { - if let TokenTree::Sequence(sp, _) = tt { - self.span_err(sp, "attempted to repeat an expression containing no \ - syntax variables matched as repeating at this depth"); - } - } - match tt { - TokenTree::Token(sp, tok) => TokenAndSpan { tok: tok, sp: sp }, - _ if tt.len() > 0 => { - self.tts.push((tt, 0)); - continue - } - _ => continue, + if let TokenTree::Token(sp, tok) = tt { + TokenAndSpan { tok: tok, sp: sp } + } else { + self.tts.push((tt, 0)); + continue } } else { TokenAndSpan { tok: token::Eof, sp: self.span } @@ -997,7 +981,6 @@ impl<'a> Parser<'a> { tok = match tts.get_tt(i) { TokenTree::Token(_, tok) => tok, TokenTree::Delimited(_, delimited) => token::OpenDelim(delimited.delim), - TokenTree::Sequence(..) => token::Dollar, }; } } @@ -2586,139 +2569,21 @@ impl<'a> Parser<'a> { return Ok(e); } - // Parse unquoted tokens after a `$` in a token tree - fn parse_unquoted(&mut self) -> PResult<'a, TokenTree> { - let mut sp = self.span; - let name = match self.token { - token::Dollar => { - self.bump(); - - if self.token == token::OpenDelim(token::Paren) { - let Spanned { node: seq, span: seq_span } = self.parse_seq( - &token::OpenDelim(token::Paren), - &token::CloseDelim(token::Paren), - SeqSep::none(), - |p| p.parse_token_tree() - )?; - let (sep, repeat) = self.parse_sep_and_kleene_op()?; - let name_num = macro_parser::count_names(&seq); - return Ok(TokenTree::Sequence(mk_sp(sp.lo, seq_span.hi), - Rc::new(SequenceRepetition { - tts: seq, - separator: sep, - op: repeat, - num_captures: name_num - }))); - } else if self.token.is_keyword(keywords::Crate) { - let ident = match self.token { - token::Ident(id) => ast::Ident { name: Symbol::intern("$crate"), ..id }, - _ => unreachable!(), - }; - self.bump(); - return Ok(TokenTree::Token(sp, token::Ident(ident))); - } else { - sp = mk_sp(sp.lo, self.span.hi); - self.parse_ident().unwrap_or_else(|mut e| { - e.emit(); - keywords::Invalid.ident() - }) - } - } - token::SubstNt(name) => { - self.bump(); - name - } - _ => unreachable!() - }; - // continue by trying to parse the `:ident` after `$name` - if self.token == token::Colon && - self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) { - self.bump(); - sp = mk_sp(sp.lo, self.span.hi); - let nt_kind = self.parse_ident()?; - Ok(TokenTree::Token(sp, MatchNt(name, nt_kind))) - } else { - Ok(TokenTree::Token(sp, SubstNt(name))) - } - } - pub fn check_unknown_macro_variable(&mut self) { - if self.quote_depth == 0 && !self.parsing_token_tree { - match self.token { - token::SubstNt(name) => - self.fatal(&format!("unknown macro variable `{}`", name)).emit(), - _ => {} - } - } - } - - /// Parse an optional separator followed by a Kleene-style - /// repetition token (+ or *). - pub fn parse_sep_and_kleene_op(&mut self) - -> PResult<'a, (Option<token::Token>, tokenstream::KleeneOp)> { - fn parse_kleene_op<'a>(parser: &mut Parser<'a>) -> - PResult<'a, Option<tokenstream::KleeneOp>> { - match parser.token { - token::BinOp(token::Star) => { - parser.bump(); - Ok(Some(tokenstream::KleeneOp::ZeroOrMore)) - }, - token::BinOp(token::Plus) => { - parser.bump(); - Ok(Some(tokenstream::KleeneOp::OneOrMore)) - }, - _ => Ok(None) - } - }; - - if let Some(kleene_op) = parse_kleene_op(self)? { - return Ok((None, kleene_op)); - } - - let separator = match self.token { - token::CloseDelim(..) => None, - _ => Some(self.bump_and_get()), - }; - match parse_kleene_op(self)? { - Some(zerok) => Ok((separator, zerok)), - None => return Err(self.fatal("expected `*` or `+`")) + if let token::SubstNt(name) = self.token { + self.fatal(&format!("unknown macro variable `{}`", name)).emit() } } /// parse a single token tree from the input. pub fn parse_token_tree(&mut self) -> PResult<'a, TokenTree> { - // FIXME #6994: currently, this is too eager. It - // parses token trees but also identifies TokenType::Sequence's - // and token::SubstNt's; it's too early to know yet - // whether something will be a nonterminal or a seq - // yet. match self.token { - token::OpenDelim(delim) => { - if self.quote_depth == 0 { - 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 lo = self.span.lo; - self.bump(); - let tts = self.parse_seq_to_before_tokens(&[&token::CloseDelim(token::Brace), - &token::CloseDelim(token::Paren), - &token::CloseDelim(token::Bracket)], - SeqSep::none(), - |p| p.parse_token_tree(), - |mut e| e.emit()); - self.parsing_token_tree = parsing_token_tree; + token::OpenDelim(..) => { + let tt = self.tts.pop().unwrap().0; self.bump(); - - Ok(TokenTree::Delimited(Span { lo: lo, ..self.prev_span }, Rc::new(Delimited { - delim: delim, - tts: tts, - }))) + return Ok(tt); }, - token::CloseDelim(..) | token::Eof => Ok(TokenTree::Token(self.span, token::Eof)), - token::Dollar | token::SubstNt(..) if self.quote_depth > 0 => self.parse_unquoted(), + token::CloseDelim(_) | token::Eof => unreachable!(), _ => Ok(TokenTree::Token(self.span, self.bump_and_get())), } } |
