Skip to content

Commit 94d6eee

Browse files
committed
Add a KleeneOp enum for clarity
1 parent 34dacb8 commit 94d6eee

File tree

6 files changed

+42
-30
lines changed

6 files changed

+42
-30
lines changed

src/libsyntax/ast.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,14 @@ impl Delimiter {
609609
}
610610
}
611611

612+
/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
613+
/// for token sequences.
614+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
615+
pub enum KleeneOp {
616+
ZeroOrMore,
617+
OneOrMore,
618+
}
619+
612620
/// When the main rust parser encounters a syntax-extension invocation, it
613621
/// parses the arguments to the invocation as a token-tree. This is a very
614622
/// loose structure, such that all sorts of different AST-fragments can
@@ -633,12 +641,9 @@ pub enum TokenTree {
633641

634642
// These only make sense for right-hand-sides of MBE macros:
635643

636-
/// A kleene-style repetition sequence with a span, a `TTForest`,
637-
/// an optional separator, and a boolean where true indicates
638-
/// zero or more (..), and false indicates one or more (+).
644+
/// A Kleene-style repetition sequence with an optional separator.
639645
// FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
640-
TtSequence(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
641-
646+
TtSequence(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, KleeneOp),
642647
/// A syntactic variable that will be filled in by macro expansion.
643648
TtNonterminal(Span, Ident)
644649
}
@@ -711,9 +716,9 @@ pub type Matcher = Spanned<Matcher_>;
711716
pub enum Matcher_ {
712717
/// Match one token
713718
MatchTok(::parse::token::Token),
714-
/// Match repetitions of a sequence: body, separator, zero ok?,
719+
/// Match repetitions of a sequence: body, separator, Kleene operator,
715720
/// lo, hi position-in-match-array used:
716-
MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
721+
MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, KleeneOp, uint, uint),
717722
/// Parse a Rust NT: name to bind, name of NT, position in match array:
718723
MatchNonterminal(Ident, Ident, uint)
719724
}

src/libsyntax/ext/tt/macro_parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,9 @@ pub fn parse(sess: &ParseSess,
323323
} else {
324324
match ei.elts[idx].node.clone() {
325325
/* need to descend into sequence */
326-
MatchSeq(ref matchers, ref sep, zero_ok,
326+
MatchSeq(ref matchers, ref sep, kleene_op,
327327
match_idx_lo, match_idx_hi) => {
328-
if zero_ok {
328+
if kleene_op == ast::ZeroOrMore {
329329
let mut new_ei = ei.clone();
330330
new_ei.idx += 1u;
331331
//we specifically matched zero repeats.

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,11 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
232232
ms(MatchSeq(vec!(
233233
ms(MatchNonterminal(lhs_nm, special_idents::matchers, 0u)),
234234
ms(MatchTok(FAT_ARROW)),
235-
ms(MatchNonterminal(rhs_nm, special_idents::tt, 1u))), Some(SEMI), false, 0u, 2u)),
235+
ms(MatchNonterminal(rhs_nm, special_idents::tt, 1u))), Some(SEMI),
236+
ast::OneOrMore, 0u, 2u)),
236237
//to phase into semicolon-termination instead of
237238
//semicolon-separation
238-
ms(MatchSeq(vec!(ms(MatchTok(SEMI))), None, true, 2u, 2u)));
239+
ms(MatchSeq(vec!(ms(MatchTok(SEMI))), None, ast::ZeroOrMore, 2u, 2u)));
239240

240241

241242
// Parse the macro_rules! invocation (`none` is for no interpolations):

src/libsyntax/ext/tt/transcribe.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
227227
r.stack.last_mut().unwrap().idx += 1;
228228
return ret_val;
229229
}
230-
TtSequence(sp, tts, sep, zerok) => {
230+
TtSequence(sp, tts, sep, kleene_op) => {
231231
// FIXME(pcwalton): Bad copy.
232-
match lockstep_iter_size(&TtSequence(sp, tts.clone(), sep.clone(), zerok), r) {
232+
match lockstep_iter_size(&TtSequence(sp, tts.clone(), sep.clone(), kleene_op), r) {
233233
LisUnconstrained => {
234234
r.sp_diag.span_fatal(
235235
sp.clone(), /* blame macro writer */
@@ -243,7 +243,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
243243
}
244244
LisConstraint(len, _) => {
245245
if len == 0 {
246-
if !zerok {
246+
if kleene_op == ast::OneOrMore {
247247
// FIXME #2887 blame invoker
248248
r.sp_diag.span_fatal(sp.clone(),
249249
"this must repeat at least once");

src/libsyntax/parse/parser.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,27 +2497,30 @@ impl<'a> Parser<'a> {
24972497
return e;
24982498
}
24992499

2500-
/// Parse an optional separator followed by a kleene-style
2500+
/// Parse an optional separator followed by a Kleene-style
25012501
/// repetition token (+ or *).
2502-
pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
2503-
fn parse_zerok(parser: &mut Parser) -> Option<bool> {
2502+
pub fn parse_sep_and_kleene_op(&mut self) -> (Option<token::Token>, ast::KleeneOp) {
2503+
fn parse_kleene_op(parser: &mut Parser) -> Option<ast::KleeneOp> {
25042504
match parser.token {
2505-
token::BINOP(token::STAR) | token::BINOP(token::PLUS) => {
2506-
let zerok = parser.token == token::BINOP(token::STAR);
2505+
token::BINOP(token::STAR) => {
25072506
parser.bump();
2508-
Some(zerok)
2507+
Some(ast::ZeroOrMore)
2508+
},
2509+
token::BINOP(token::PLUS) => {
2510+
parser.bump();
2511+
Some(ast::OneOrMore)
25092512
},
25102513
_ => None
25112514
}
25122515
};
25132516

2514-
match parse_zerok(self) {
2515-
Some(zerok) => return (None, zerok),
2517+
match parse_kleene_op(self) {
2518+
Some(kleene_op) => return (None, kleene_op),
25162519
None => {}
25172520
}
25182521

25192522
let separator = self.bump_and_get();
2520-
match parse_zerok(self) {
2523+
match parse_kleene_op(self) {
25212524
Some(zerok) => (Some(separator), zerok),
25222525
None => self.fatal("expected `*` or `+`")
25232526
}
@@ -2564,11 +2567,11 @@ impl<'a> Parser<'a> {
25642567
seq_sep_none(),
25652568
|p| p.parse_token_tree()
25662569
);
2567-
let (s, z) = p.parse_sep_and_zerok();
2570+
let (sep, repeat) = p.parse_sep_and_kleene_op();
25682571
let seq = match seq {
25692572
Spanned { node, .. } => node,
25702573
};
2571-
TtSequence(mk_sp(sp.lo, p.span.hi), Rc::new(seq), s, z)
2574+
TtSequence(mk_sp(sp.lo, p.span.hi), Rc::new(seq), sep, repeat)
25722575
} else {
25732576
TtNonterminal(sp, p.parse_ident())
25742577
}
@@ -2679,8 +2682,8 @@ impl<'a> Parser<'a> {
26792682
if ms.len() == 0u {
26802683
self.fatal("repetition body must be nonempty");
26812684
}
2682-
let (sep, zerok) = self.parse_sep_and_zerok();
2683-
MatchSeq(ms, sep, zerok, name_idx_lo, *name_idx)
2685+
let (sep, kleene_op) = self.parse_sep_and_kleene_op();
2686+
MatchSeq(ms, sep, kleene_op, name_idx_lo, *name_idx)
26842687
} else {
26852688
let bound_to = self.parse_ident();
26862689
self.expect(&token::COLON);

src/libsyntax/print/pprust.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,20 +1037,23 @@ impl<'a> State<'a> {
10371037
_ => Ok(())
10381038
}
10391039
}
1040-
ast::TtSequence(_, ref tts, ref sep, zerok) => {
1040+
ast::TtSequence(_, ref tts, ref separator, kleene_op) => {
10411041
try!(word(&mut self.s, "$("));
10421042
for tt_elt in (*tts).iter() {
10431043
try!(self.print_tt(tt_elt));
10441044
}
10451045
try!(word(&mut self.s, ")"));
1046-
match *sep {
1046+
match *separator {
10471047
Some(ref tk) => {
10481048
try!(word(&mut self.s,
10491049
parse::token::to_string(tk).as_slice()));
10501050
}
10511051
None => ()
10521052
}
1053-
word(&mut self.s, if zerok { "*" } else { "+" })
1053+
match kleene_op {
1054+
ast::ZeroOrMore => word(&mut self.s, "*"),
1055+
ast::OneOrMore => word(&mut self.s, "+"),
1056+
}
10541057
}
10551058
ast::TtNonterminal(_, name) => {
10561059
try!(word(&mut self.s, "$"));

0 commit comments

Comments
 (0)