about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-07-09 17:04:06 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-07-09 17:44:46 -0700
commitb1af6ac6f1baceffc63d097af6686e11974b6e1a (patch)
tree4e385c7f2a0a23d69c0c1404adb8679687e37b9c /src/libsyntax/parse/parser.rs
parent55e28f6689249d794c6941f64485a255d63663c5 (diff)
downloadrust-b1af6ac6f1baceffc63d097af6686e11974b6e1a.tar.gz
rust-b1af6ac6f1baceffc63d097af6686e11974b6e1a.zip
Make the matcher parser treat `()` in a matchy way, like one would expect.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 261ffdb6651..67cc265f7a0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1246,9 +1246,29 @@ class parser {
 
     fn parse_matchers() -> ~[matcher] {
         let name_idx = @mut 0u;
-        ret self.parse_seq(token::LBRACE, token::RBRACE,
-                           common::seq_sep_none(),
-                           |p| p.parse_matcher(name_idx)).node;
+        ret self.parse_matcher_subseq(name_idx, token::LBRACE, token::RBRACE);
+    }
+
+
+    // This goofy function is necessary to correctly match parens in matchers.
+    // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
+    // invalid. It's similar to common::parse_seq.
+    fn parse_matcher_subseq(name_idx: @mut uint, bra: token::token,
+                            ket: token::token) -> ~[matcher] {
+        let mut ret_val = ~[];
+        let mut lparens = 0u;
+
+        self.expect(bra);
+
+        while self.token != ket || lparens > 0u {
+            if self.token == token::LPAREN { lparens += 1u; }
+            if self.token == token::RPAREN { lparens -= 1u; }
+            vec::push(ret_val, self.parse_matcher(name_idx));
+        }
+
+        self.bump();
+
+        ret ret_val;
     }
 
     fn parse_matcher(name_idx: @mut uint) -> matcher {
@@ -1257,9 +1277,8 @@ class parser {
         let m = if self.token == token::DOLLAR {
             self.bump();
             if self.token == token::LPAREN {
-                let ms = (self.parse_seq(token::LPAREN, token::RPAREN,
-                                         common::seq_sep_none(),
-                                         |p| p.parse_matcher(name_idx)).node);
+                let ms = self.parse_matcher_subseq(name_idx, token::LPAREN,
+                                                   token::RPAREN);
                 if ms.len() == 0u {
                     self.fatal("repetition body must be nonempty");
                 }