diff options
| author | Mark Mansi <markm@cs.wisc.edu> | 2018-01-18 19:30:15 -0600 |
|---|---|---|
| committer | Mark Mansi <markm@cs.wisc.edu> | 2018-01-30 12:30:41 -0600 |
| commit | bb8110c1fcc33117fbf8bed985c0f472b3816bc3 (patch) | |
| tree | c3d3d931b7cfd51ef922011b7825a0ca01fcebad /src/libsyntax/ext | |
| parent | 760879bc88b2884275b59fc38e0c5b1a8632e4cd (diff) | |
| download | rust-bb8110c1fcc33117fbf8bed985c0f472b3816bc3.tar.gz rust-bb8110c1fcc33117fbf8bed985c0f472b3816bc3.zip | |
Update the macro parser to allow at most once repetitions for `?` Kleene
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 1a9849ca530..88144b19609 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -486,8 +486,8 @@ fn inner_parse_loop( match item.top_elts.get_tt(idx) { // Need to descend into a sequence TokenTree::Sequence(sp, seq) => { - if seq.op == quoted::KleeneOp::ZeroOrMore { - // Examine the case where there are 0 matches of this sequence + // Examine the case where there are 0 matches of this sequence + if seq.op == quoted::KleeneOp::ZeroOrMore || seq.op == quoted::KleeneOp::ZeroOrOne { let mut new_item = item.clone(); new_item.match_cur += seq.num_captures; new_item.idx += 1; @@ -497,20 +497,26 @@ fn inner_parse_loop( cur_items.push(new_item); } - // Examine the case where there is at least one match of this sequence - let matches = create_matches(item.matches.len()); - cur_items.push(Box::new(MatcherPos { - stack: vec![], - sep: seq.separator.clone(), - idx: 0, - matches, - match_lo: item.match_cur, - match_cur: item.match_cur, - match_hi: item.match_cur + seq.num_captures, - up: Some(item), - sp_lo: sp.lo(), - top_elts: Tt(TokenTree::Sequence(sp, seq)), - })); + // For ZeroOrMore and OneOrMore, we want to examine the case were there is at + // least one match. For ZeroOrOne, we only want the case where there is exactly + // one match. + if (seq.op == quoted::KleeneOp::ZeroOrOne && seq.num_captures == 1) || + seq.op != quoted::KleeneOp::ZeroOrOne { + + let matches = create_matches(item.matches.len()); + cur_items.push(Box::new(MatcherPos { + stack: vec![], + sep: seq.separator.clone(), + idx: 0, + matches, + match_lo: item.match_cur, + match_cur: item.match_cur, + match_hi: item.match_cur + seq.num_captures, + up: Some(item), + sp_lo: sp.lo(), + top_elts: Tt(TokenTree::Sequence(sp, seq)), + })); + } } // We need to match a metavar (but the identifier is invalid)... this is an error |
