Skip to content

Commit b1af6ac

Browse files
committed
Make the matcher parser treat () in a matchy way, like one would expect.
1 parent 55e28f6 commit b1af6ac

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,9 +1246,29 @@ class parser {
12461246

12471247
fn parse_matchers() -> ~[matcher] {
12481248
let name_idx = @mut 0u;
1249-
ret self.parse_seq(token::LBRACE, token::RBRACE,
1250-
common::seq_sep_none(),
1251-
|p| p.parse_matcher(name_idx)).node;
1249+
ret self.parse_matcher_subseq(name_idx, token::LBRACE, token::RBRACE);
1250+
}
1251+
1252+
1253+
// This goofy function is necessary to correctly match parens in matchers.
1254+
// Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
1255+
// invalid. It's similar to common::parse_seq.
1256+
fn parse_matcher_subseq(name_idx: @mut uint, bra: token::token,
1257+
ket: token::token) -> ~[matcher] {
1258+
let mut ret_val = ~[];
1259+
let mut lparens = 0u;
1260+
1261+
self.expect(bra);
1262+
1263+
while self.token != ket || lparens > 0u {
1264+
if self.token == token::LPAREN { lparens += 1u; }
1265+
if self.token == token::RPAREN { lparens -= 1u; }
1266+
vec::push(ret_val, self.parse_matcher(name_idx));
1267+
}
1268+
1269+
self.bump();
1270+
1271+
ret ret_val;
12521272
}
12531273

12541274
fn parse_matcher(name_idx: @mut uint) -> matcher {
@@ -1257,9 +1277,8 @@ class parser {
12571277
let m = if self.token == token::DOLLAR {
12581278
self.bump();
12591279
if self.token == token::LPAREN {
1260-
let ms = (self.parse_seq(token::LPAREN, token::RPAREN,
1261-
common::seq_sep_none(),
1262-
|p| p.parse_matcher(name_idx)).node);
1280+
let ms = self.parse_matcher_subseq(name_idx, token::LPAREN,
1281+
token::RPAREN);
12631282
if ms.len() == 0u {
12641283
self.fatal("repetition body must be nonempty");
12651284
}

0 commit comments

Comments
 (0)