Make the matcher parser treat () in a matchy way, like one would expect.

This commit is contained in:
Paul Stansifer 2012-07-09 17:04:06 -07:00
parent 55e28f6689
commit b1af6ac6f1

View file

@ -1246,9 +1246,29 @@ class parser {
fn parse_matchers() -> ~[matcher] { fn parse_matchers() -> ~[matcher] {
let name_idx = @mut 0u; let name_idx = @mut 0u;
ret self.parse_seq(token::LBRACE, token::RBRACE, ret self.parse_matcher_subseq(name_idx, token::LBRACE, token::RBRACE);
common::seq_sep_none(), }
|p| p.parse_matcher(name_idx)).node;
// 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 { fn parse_matcher(name_idx: @mut uint) -> matcher {
@ -1257,9 +1277,8 @@ class parser {
let m = if self.token == token::DOLLAR { let m = if self.token == token::DOLLAR {
self.bump(); self.bump();
if self.token == token::LPAREN { if self.token == token::LPAREN {
let ms = (self.parse_seq(token::LPAREN, token::RPAREN, let ms = self.parse_matcher_subseq(name_idx, token::LPAREN,
common::seq_sep_none(), token::RPAREN);
|p| p.parse_matcher(name_idx)).node);
if ms.len() == 0u { if ms.len() == 0u {
self.fatal("repetition body must be nonempty"); self.fatal("repetition body must be nonempty");
} }