]> git.lizzy.rs Git - rust.git/commitdiff
Remove `Matcher`s
authorPiotr Czarnecki <pioczarn@gmail.com>
Mon, 6 Oct 2014 23:18:24 +0000 (00:18 +0100)
committerPiotr Czarnecki <pioczarn@gmail.com>
Wed, 5 Nov 2014 22:06:01 +0000 (23:06 +0100)
src/libsyntax/ast.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs

index 6c71f6d08d245eca0b8ac5f0e03cfa64c02b60fe..639b007e7ab24a020f1249c95cf118d91116ad12 100644 (file)
@@ -641,14 +641,12 @@ pub enum KleeneOp {
 /// be passed to syntax extensions using a uniform type.
 ///
 /// If the syntax extension is an MBE macro, it will attempt to match its
-/// LHS "matchers" against the provided token tree, and if it finds a
+/// LHS token tree against the provided token tree, and if it finds a
 /// match, will transcribe the RHS token tree, splicing in any captured
-/// `macro_parser::matched_nonterminals` into the `TtNonterminal`s it finds.
+/// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
 ///
-/// The RHS of an MBE macro is the only place a `TtNonterminal` or `TtSequence`
-/// makes any real sense. You could write them elsewhere but nothing
-/// else knows what to do with them, so you'll probably get a syntax
-/// error.
+/// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
+/// Nothing special happens to misnamed or misplaced `SubstNt`s.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum TokenTree {
@@ -657,14 +655,19 @@ pub enum TokenTree {
     /// A delimited sequence of token trees
     TtDelimited(Span, Rc<Delimited>),
 
-    // This only makes sense for right-hand-sides of MBE macros:
+    // This only makes sense in MBE macros.
 
-    /// A Kleene-style repetition sequence with an optional separator.
-    // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
+    /// A kleene-style repetition sequence with a span, a TT forest,
+    /// an optional separator, and a boolean where true indicates
+    /// zero or more (..), and false indicates one or more (+).
+    /// The last member denotes the number of `MATCH_NONTERMINAL`s
+    /// in the forest.
+    // FIXME(eddyb) #12938 Use Rc<[TokenTree]> after DST.
     TtSequence(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, KleeneOp, uint),
 }
 
 impl TokenTree {
+    /// For unrolling some tokens or token trees into equivalent sequences.
     pub fn expand_into_tts(self) -> Rc<Vec<TokenTree>> {
         match self {
             TtToken(sp, token::DocComment(name)) => {
@@ -710,69 +713,6 @@ pub fn get_span(&self) -> Span {
     }
 }
 
-// Matchers are nodes defined-by and recognized-by the main rust parser and
-// language, but they're only ever found inside syntax-extension invocations;
-// indeed, the only thing that ever _activates_ the rules in the rust parser
-// for parsing a matcher is a matcher looking for the 'matchers' nonterminal
-// itself. Matchers represent a small sub-language for pattern-matching
-// token-trees, and are thus primarily used by the macro-defining extension
-// itself.
-//
-// MatchTok
-// --------
-//
-//     A matcher that matches a single token, denoted by the token itself. So
-//     long as there's no $ involved.
-//
-//
-// MatchSeq
-// --------
-//
-//     A matcher that matches a sequence of sub-matchers, denoted various
-//     possible ways:
-//
-//             $(M)*       zero or more Ms
-//             $(M)+       one or more Ms
-//             $(M),+      one or more comma-separated Ms
-//             $(A B C);*  zero or more semi-separated 'A B C' seqs
-//
-//
-// MatchNonterminal
-// -----------------
-//
-//     A matcher that matches one of a few interesting named rust
-//     nonterminals, such as types, expressions, items, or raw token-trees. A
-//     black-box matcher on expr, for example, binds an expr to a given ident,
-//     and that ident can re-occur as an interpolation in the RHS of a
-//     macro-by-example rule. For example:
-//
-//        $foo:expr   =>     1 + $foo    // interpolate an expr
-//        $foo:tt     =>     $foo        // interpolate a token-tree
-//        $foo:tt     =>     bar! $foo   // only other valid interpolation
-//                                       // is in arg position for another
-//                                       // macro
-//
-// As a final, horrifying aside, note that macro-by-example's input is
-// also matched by one of these matchers. Holy self-referential! It is matched
-// by a MatchSeq, specifically this one:
-//
-//                   $( $lhs:matchers => $rhs:tt );+
-//
-// If you understand that, you have closed the loop and understand the whole
-// macro system. Congratulations.
-pub type Matcher = Spanned<Matcher_>;
-
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
-pub enum Matcher_ {
-    /// Match one token
-    MatchTok(token::Token),
-    /// Match repetitions of a sequence: body, separator, Kleene operator,
-    /// lo, hi position-in-match-array used:
-    MatchSeq(Vec<Matcher>, Option<token::Token>, KleeneOp, uint, uint),
-    /// Parse a Rust NT: name to bind, name of NT, position in match array:
-    MatchNonterminal(Ident, Ident, uint)
-}
-
 pub type Mac = Spanned<Mac_>;
 
 /// Represents a macro invocation. The Path indicates which macro
index 022e3a56677e2f6f5d95b6d9b169bff72503ba83..833211f53e7aa9e1c1b8af488bbbac7333d29708 100644 (file)
@@ -78,7 +78,7 @@
 
 
 use ast;
-use ast::{Matcher, TokenTree, Ident};
+use ast::{TokenTree, Ident};
 use ast::{TtDelimited, TtSequence, TtToken};
 use codemap::{BytePos, mk_sp};
 use codemap;
@@ -97,9 +97,8 @@
 use std::collections::HashMap;
 use std::collections::hash_map::{Vacant, Occupied};
 
-/* to avoid costly uniqueness checks, we require that `MatchSeq` always has a
-nonempty body. */
-
+// To avoid costly uniqueness checks, we require that `MatchSeq` always has
+// a nonempty body.
 
 /// an unzipping of `TokenTree`s
 #[deriving(Clone)]
@@ -157,22 +156,22 @@ pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: ByteP
     }
 }
 
-/// NamedMatch is a pattern-match result for a single ast::MatchNonterminal:
+/// NamedMatch is a pattern-match result for a single token::MATCH_NONTERMINAL:
 /// so it is associated with a single ident in a parse, and all
-/// MatchedNonterminal's in the NamedMatch have the same nonterminal type
-/// (expr, item, etc). All the leaves in a single NamedMatch correspond to a
-/// single matcher_nonterminal in the ast::Matcher that produced it.
+/// `MatchedNonterminal`s in the NamedMatch have the same nonterminal type
+/// (expr, item, etc). Each leaf in a single NamedMatch corresponds to a
+/// single token::MATCH_NONTERMINAL in the TokenTree that produced it.
 ///
 /// The in-memory structure of a particular NamedMatch represents the match
 /// that occurred when a particular subset of a matcher was applied to a
 /// particular token tree.
 ///
 /// The width of each MatchedSeq in the NamedMatch, and the identity of the
-/// MatchedNonterminal's, will depend on the token tree it was applied to: each
-/// MatchedSeq corresponds to a single MatchSeq in the originating
-/// ast::Matcher. The depth of the NamedMatch structure will therefore depend
-/// only on the nesting depth of ast::MatchSeq's in the originating
-/// ast::Matcher it was derived from.
+/// `MatchedNonterminal`s, will depend on the token tree it was applied to:
+/// each MatchedSeq corresponds to a single TTSeq in the originating
+/// token tree. The depth of the NamedMatch structure will therefore depend
+/// only on the nesting depth of `ast::TTSeq`s in the originating
+/// token tree it was derived from.
 
 pub enum NamedMatch {
     MatchedSeq(Vec<Rc<NamedMatch>>, codemap::Span),
@@ -512,7 +511,6 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
         p.quote_depth -= 1u;
         res
       }
-      "matchers" => token::NtMatchers(p.parse_matchers()),
       _ => {
           p.fatal(format!("unsupported builtin nonterminal parser: {}",
                           name).as_slice())
index cbf34ba5eb320036018615a456d5a76df0d18385..381e4310d89ecb8ccb1348bd944fd7cf470aaf16 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq, TtDelimited};
-use ast::{TtSequence, TtToken};
+use ast::{Ident, TtDelimited, TtSequence, TtToken};
 use ast;
 use codemap::{Span, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, MacroDef};
@@ -21,7 +20,7 @@
 use parse::parser::Parser;
 use parse::attr::ParserAttr;
 use parse::token::{special_idents, gensym_ident};
-use parse::token::{MatchNt, NtMatchers, NtTT};
+use parse::token::{MatchNt, NtTT};
 use parse::token;
 use print;
 use ptr::P;
@@ -207,6 +206,11 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
     cx.span_fatal(best_fail_spot, best_fail_msg.as_slice());
 }
 
+// Note that macro-by-example's input is also matched against a token tree:
+//                   $( $lhs:tt => $rhs:tt );+
+//
+// Holy self-referential!
+
 /// This procedure performs the expansion of the
 /// macro_rules! macro. It parses the RHS and adds
 /// an extension to the current context.
index 75fbdb8d8b6b0fe810f48431e0461d73fdf4bae9..746e1d112c7e9488c13d899b44c6f8c07df31ada 100644 (file)
@@ -656,8 +656,6 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
         token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
         token::NtPath(box path) => token::NtPath(box fld.fold_path(path)),
         token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&*tt))),
-        // it looks to me like we can leave out the matchers: token::NtMatchers(matchers)
-        _ => nt
     }
 }
 
index 741014fec896250b468e08a010b5942787a0c247..5a0c7d92fa2cb885ac9292b141afd6ca98b4e87d 100644 (file)
@@ -37,8 +37,8 @@
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
-use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal, MatchNormal};
-use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
+use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchNormal};
+use ast::{Method, MutTy, BiMul, Mutability};
 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
@@ -2628,66 +2628,6 @@ pub fn parse_all_token_trees(&mut self) -> Vec<TokenTree> {
         tts
     }
 
-    pub fn parse_matchers(&mut self) -> Vec<Matcher> {
-        // unification of Matcher's and TokenTree's would vastly improve
-        // the interpolation of Matcher's
-        maybe_whole!(self, NtMatchers);
-        let mut name_idx = 0u;
-        let delim = self.expect_open_delim();
-        self.parse_matcher_subseq_upto(&mut name_idx, &token::CloseDelim(delim))
-    }
-
-    /// This goofy function is necessary to correctly match parens in Matcher's.
-    /// Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
-    /// invalid. It's similar to common::parse_seq.
-    pub fn parse_matcher_subseq_upto(&mut self,
-                                     name_idx: &mut uint,
-                                     ket: &token::Token)
-                                     -> Vec<Matcher> {
-        let mut ret_val = Vec::new();
-        let mut lparens = 0u;
-
-        while self.token != *ket || lparens > 0u {
-            if self.token == token::OpenDelim(token::Paren) { lparens += 1u; }
-            if self.token == token::CloseDelim(token::Paren) { lparens -= 1u; }
-            ret_val.push(self.parse_matcher(name_idx));
-        }
-
-        self.bump();
-
-        return ret_val;
-    }
-
-    pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
-        let lo = self.span.lo;
-
-        let m = if self.token == token::Dollar {
-            self.bump();
-            if self.token == token::OpenDelim(token::Paren) {
-                let name_idx_lo = *name_idx;
-                self.bump();
-                let ms = self.parse_matcher_subseq_upto(name_idx,
-                                                        &token::CloseDelim(token::Paren));
-                if ms.len() == 0u {
-                    self.fatal("repetition body must be nonempty");
-                }
-                let (sep, kleene_op) = self.parse_sep_and_kleene_op();
-                MatchSeq(ms, sep, kleene_op, name_idx_lo, *name_idx)
-            } else {
-                let bound_to = self.parse_ident();
-                self.expect(&token::Colon);
-                let nt_name = self.parse_ident();
-                let m = MatchNonterminal(bound_to, nt_name, *name_idx);
-                *name_idx += 1;
-                m
-            }
-        } else {
-            MatchTok(self.bump_and_get())
-        };
-
-        return spanned(lo, self.span.hi, m);
-    }
-
     /// Parse a prefix-operator expr
     pub fn parse_prefix_expr(&mut self) -> P<Expr> {
         let lo = self.span.lo;
index 8dd2f8b840f92b45f912b59d0ff0e81e6033c62a..b0cca5e14de15448bcf603e4be57c97bbafd8b40 100644 (file)
@@ -337,7 +337,6 @@ pub enum Nonterminal {
     NtMeta(P<ast::MetaItem>),
     NtPath(Box<ast::Path>),
     NtTT(P<ast::TokenTree>), // needs P'ed to break a circularity
-    NtMatchers(Vec<ast::Matcher>)
 }
 
 impl fmt::Show for Nonterminal {
@@ -353,7 +352,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             NtMeta(..) => f.pad("NtMeta(..)"),
             NtPath(..) => f.pad("NtPath(..)"),
             NtTT(..) => f.pad("NtTT(..)"),
-            NtMatchers(..) => f.pad("NtMatchers(..)"),
         }
     }
 }
index 12ce81eedca8c77f13c715959d759d989a3c5e01..8ffc2aa3583805d5457a67f64b67d87f97f005a1 100644 (file)
@@ -272,7 +272,6 @@ pub fn token_to_string(tok: &Token) -> String {
             token::NtPat(..)      => "an interpolated pattern".into_string(),
             token::NtIdent(..)    => "an interpolated identifier".into_string(),
             token::NtTT(..)       => "an interpolated tt".into_string(),
-            token::NtMatchers(..) => "an interpolated matcher sequence".into_string(),
         }
     }
 }