@@ -290,7 +290,7 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ {
290
290
ret spanned( lo, t. span . hi , { mode: mode, ty: t} ) ;
291
291
}
292
292
let inputs =
293
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
293
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
294
294
parse_fn_input_ty, p) ;
295
295
// FIXME: there's no syntax for this right now anyway
296
296
// auto constrs = parse_constrs(~[], p);
@@ -319,7 +319,8 @@ fn parse_ty_obj(p: parser) -> ast::ty_ {
319
319
}
320
320
}
321
321
let meths =
322
- parse_seq ( token:: LBRACE , token:: RBRACE , none, parse_method_sig, p) ;
322
+ parse_seq ( token:: LBRACE , token:: RBRACE , seq_sep_none ( ) ,
323
+ parse_method_sig, p) ;
323
324
ret ast:: ty_obj ( meths. node ) ;
324
325
}
325
326
@@ -376,7 +377,7 @@ fn parse_ty_constr(fn_args: [ast::arg], p: parser) -> @ast::constr {
376
377
let lo = p. get_lo_pos ( ) ;
377
378
let path = parse_path ( p) ;
378
379
let args: { node : [ @ast:: constr_arg ] , span : span } =
379
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
380
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
380
381
{ |p| parse_constr_arg ( fn_args, p) } , p) ;
381
382
ret @spanned ( lo, args. span . hi ,
382
383
{ path: path, args: args. node , id: p. get_id ( ) } ) ;
@@ -386,7 +387,7 @@ fn parse_constr_in_type(p: parser) -> @ast::ty_constr {
386
387
let lo = p. get_lo_pos ( ) ;
387
388
let path = parse_path ( p) ;
388
389
let args: [ @ast:: ty_constr_arg ] =
389
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
390
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
390
391
parse_type_constr_arg, p) . node ;
391
392
let hi = p. get_lo_pos ( ) ;
392
393
let tc: ast:: ty_constr_ = { path: path, args: args, id: p. get_id ( ) } ;
@@ -540,7 +541,7 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
540
541
t = ast:: ty_ptr ( parse_mt ( p) ) ;
541
542
} else if p. peek ( ) == token:: LBRACE {
542
543
let elems =
543
- parse_seq ( token:: LBRACE , token:: RBRACE , some ( token:: COMMA ) ,
544
+ parse_seq ( token:: LBRACE , token:: RBRACE , seq_sep_opt ( token:: COMMA ) ,
544
545
parse_ty_field, p) ;
545
546
let hi = elems. span . hi ;
546
547
t = ast:: ty_rec ( elems. node ) ;
@@ -631,31 +632,47 @@ fn parse_seq_lt_gt<copy T>(sep: option::t<token::token>,
631
632
ret spanned( lo, hi, result) ;
632
633
}
633
634
634
- fn parse_seq_to_end < copy T > ( ket : token:: token , sep : option :: t < token :: token > ,
635
+ fn parse_seq_to_end < copy T > ( ket : token:: token , sep : seq_sep ,
635
636
f : block ( parser ) -> T , p : parser ) -> [ T ] {
636
637
let val = parse_seq_to_before_end ( ket, sep, f, p) ;
637
638
p. bump ( ) ;
638
639
ret val;
639
640
}
640
641
642
+ type seq_sep = {
643
+ sep : option:: t < token:: token > ,
644
+ trailing_opt : bool // is trailing separator optional?
645
+ } ;
646
+
647
+ fn seq_sep ( t : token:: token ) -> seq_sep {
648
+ ret { sep : option:: some ( t) , trailing_opt : false } ;
649
+ }
650
+ fn seq_sep_opt ( t : token:: token ) -> seq_sep {
651
+ ret { sep : option:: some ( t) , trailing_opt : true } ;
652
+ }
653
+ fn seq_sep_none ( ) -> seq_sep {
654
+ ret { sep : option:: none, trailing_opt : false } ;
655
+ }
656
+
641
657
fn parse_seq_to_before_end < copy T > ( ket : token:: token ,
642
- sep : option :: t < token :: token > ,
658
+ sep : seq_sep ,
643
659
f : block ( parser ) -> T , p : parser ) -> [ T ] {
644
660
let first: bool = true ;
645
661
let v: [ T ] = [ ] ;
646
662
while p. peek ( ) != ket {
647
- alt sep {
663
+ alt sep. sep {
648
664
some ( t) { if first { first = false ; } else { expect ( p, t) ; } }
649
665
_ { }
650
666
}
667
+ if sep. trailing_opt && p. peek ( ) == ket { break ; }
651
668
v += [ f ( p) ] ;
652
669
}
653
670
ret v;
654
671
}
655
672
656
673
657
674
fn parse_seq < copy T > ( bra : token:: token , ket : token:: token ,
658
- sep : option :: t < token :: token > , f : block ( parser ) -> T ,
675
+ sep : seq_sep , f : block ( parser ) -> T ,
659
676
p : parser ) -> spanned < [ T ] > {
660
677
let lo = p. get_lo_pos ( ) ;
661
678
expect ( p, bra) ;
@@ -810,6 +827,10 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
810
827
while p. peek ( ) != token:: RBRACE {
811
828
if eat_word ( p, "with" ) { base = some ( parse_expr ( p) ) ; break ; }
812
829
expect ( p, token:: COMMA ) ;
830
+ if p. peek ( ) == token:: RBRACE {
831
+ // record ends by an optional trailing comma
832
+ break ;
833
+ }
813
834
fields += [ parse_field ( p, token:: COLON ) ] ;
814
835
}
815
836
hi = p. get_hi_pos ( ) ;
@@ -850,8 +871,8 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
850
871
p. bump ( ) ;
851
872
let mut = parse_mutability( p) ;
852
873
let es =
853
- parse_seq_to_end ( token:: RBRACKET , some ( token:: COMMA ) , parse_expr ,
854
- p) ;
874
+ parse_seq_to_end ( token:: RBRACKET , seq_sep ( token:: COMMA ) ,
875
+ parse_expr , p) ;
855
876
ex = ast:: expr_vec ( es, mut) ;
856
877
} else if p. peek ( ) == token:: POUND_LT {
857
878
p. bump ( ) ;
@@ -876,7 +897,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
876
897
if p. peek ( ) == token:: LPAREN {
877
898
p. bump ( ) ;
878
899
fields =
879
- some ( parse_seq_to_end ( token:: RPAREN , some ( token:: COMMA ) ,
900
+ some ( parse_seq_to_end ( token:: RPAREN , seq_sep ( token:: COMMA ) ,
880
901
parse_anon_obj_field, p) ) ;
881
902
}
882
903
let meths: [ @ast:: method ] = [ ] ;
@@ -906,7 +927,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
906
927
}
907
928
}
908
929
let es =
909
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
930
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
910
931
parse_expr_opt, p) ;
911
932
hi = es. span . hi ;
912
933
ex = ast:: expr_bind ( e, es. node ) ;
@@ -977,7 +998,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
977
998
// The rest is a call expression.
978
999
let f: @ast:: expr = parse_self_method ( p) ;
979
1000
let es =
980
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
1001
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
981
1002
parse_expr, p) ;
982
1003
hi = es. span . hi ;
983
1004
ex = ast:: expr_call ( f, es. node , false ) ;
@@ -1016,13 +1037,12 @@ fn parse_syntax_ext_naked(p: parser, lo: uint) -> @ast::expr {
1016
1037
p. fatal ( "expected a syntax expander name" ) ;
1017
1038
}
1018
1039
//temporary for a backwards-compatible cycle:
1040
+ let sep = seq_sep ( token:: COMMA ) ;
1019
1041
let es =
1020
1042
if p. peek ( ) == token:: LPAREN {
1021
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
1022
- parse_expr, p)
1043
+ parse_seq ( token:: LPAREN , token:: RPAREN , sep, parse_expr, p)
1023
1044
} else {
1024
- parse_seq ( token:: LBRACKET , token:: RBRACKET , some ( token:: COMMA ) ,
1025
- parse_expr, p)
1045
+ parse_seq ( token:: LBRACKET , token:: RBRACKET , sep, parse_expr, p)
1026
1046
} ;
1027
1047
let hi = es. span . hi ;
1028
1048
let e = mk_expr ( p, es. span . lo , hi, ast:: expr_vec ( es. node , ast:: imm) ) ;
@@ -1053,7 +1073,7 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
1053
1073
} else {
1054
1074
// Call expr.
1055
1075
let es = parse_seq ( token:: LPAREN , token:: RPAREN ,
1056
- some ( token:: COMMA ) , parse_expr, p) ;
1076
+ seq_sep ( token:: COMMA ) , parse_expr, p) ;
1057
1077
hi = es. span . hi ;
1058
1078
let nd = ast:: expr_call ( e, es. node , false ) ;
1059
1079
e = mk_expr ( p, lo, hi, nd) ;
@@ -1508,7 +1528,7 @@ fn parse_pat(p: parser) -> @ast::pat {
1508
1528
token:: LPAREN . {
1509
1529
let a =
1510
1530
parse_seq ( token:: LPAREN , token:: RPAREN ,
1511
- some ( token:: COMMA ) , parse_pat, p) ;
1531
+ seq_sep ( token:: COMMA ) , parse_pat, p) ;
1512
1532
args = a. node ;
1513
1533
hi = a. span . hi ;
1514
1534
}
@@ -1761,8 +1781,8 @@ fn parse_ty_params(p: parser) -> [ast::ty_param] {
1761
1781
fn parse_fn_decl ( p : parser , purity : ast:: purity , il : ast:: inlineness ) ->
1762
1782
ast:: fn_decl {
1763
1783
let inputs: ast:: spanned < [ ast:: arg ] > =
1764
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) , parse_arg ,
1765
- p) ;
1784
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
1785
+ parse_arg , p) ;
1766
1786
// Use the args list to translate each bound variable
1767
1787
// mentioned in a constraint to an arg index.
1768
1788
// Seems weird to do this in the parser, but I'm not sure how else to.
@@ -1787,7 +1807,7 @@ fn parse_fn_block_decl(p: parser) -> ast::fn_decl {
1787
1807
[ ]
1788
1808
} else {
1789
1809
parse_seq ( token:: BINOP ( token:: OR ) , token:: BINOP ( token:: OR ) ,
1790
- some ( token:: COMMA ) , parse_fn_block_arg, p) . node
1810
+ seq_sep ( token:: COMMA ) , parse_fn_block_arg, p) . node
1791
1811
} ;
1792
1812
ret { inputs : inputs,
1793
1813
output : @spanned ( p. get_lo_pos ( ) , p. get_hi_pos ( ) , ast:: ty_infer) ,
@@ -1861,7 +1881,7 @@ fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
1861
1881
let ident = parse_value_ident ( p) ;
1862
1882
let ty_params = parse_ty_params ( p) ;
1863
1883
let fields: ast:: spanned < [ ast:: obj_field ] > =
1864
- parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
1884
+ parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
1865
1885
parse_obj_field, p) ;
1866
1886
let meths: [ @ast:: method ] = [ ] ;
1867
1887
expect ( p, token:: LBRACE ) ;
@@ -2066,7 +2086,7 @@ fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item {
2066
2086
alt p. peek ( ) {
2067
2087
token:: LPAREN . {
2068
2088
let arg_tys = parse_seq ( token:: LPAREN , token:: RPAREN ,
2069
- some ( token:: COMMA ) ,
2089
+ seq_sep ( token:: COMMA ) ,
2070
2090
{ |p| parse_ty ( p, false ) } , p) ;
2071
2091
for ty: @ast:: ty in arg_tys. node {
2072
2092
args += [ { ty: ty, id: p. get_id ( ) } ] ;
@@ -2258,7 +2278,7 @@ fn parse_meta_item(p: parser) -> @ast::meta_item {
2258
2278
}
2259
2279
2260
2280
fn parse_meta_seq ( p : parser ) -> [ @ast:: meta_item ] {
2261
- ret parse_seq ( token:: LPAREN , token:: RPAREN , some ( token:: COMMA ) ,
2281
+ ret parse_seq ( token:: LPAREN , token:: RPAREN , seq_sep ( token:: COMMA ) ,
2262
2282
parse_meta_item, p) . node ;
2263
2283
}
2264
2284
@@ -2315,7 +2335,7 @@ fn parse_rest_import_name(p: parser, first: ast::ident,
2315
2335
ret spanned( lo, hi, { name: ident, id: p. get_id ( ) } ) ;
2316
2336
}
2317
2337
let from_idents_ =
2318
- parse_seq ( token:: LBRACE , token:: RBRACE , some ( token:: COMMA ) ,
2338
+ parse_seq ( token:: LBRACE , token:: RBRACE , seq_sep ( token:: COMMA ) ,
2319
2339
parse_import_ident, p) . node ;
2320
2340
if vec:: is_empty ( from_idents_) {
2321
2341
p. fatal ( "at least one import is required" ) ;
@@ -2385,7 +2405,7 @@ fn parse_import(p: parser) -> ast::view_item_ {
2385
2405
2386
2406
fn parse_export ( p : parser ) -> ast:: view_item_ {
2387
2407
let ids =
2388
- parse_seq_to_before_end ( token:: SEMI , option :: some ( token:: COMMA ) ,
2408
+ parse_seq_to_before_end ( token:: SEMI , seq_sep ( token:: COMMA ) ,
2389
2409
parse_ident, p) ;
2390
2410
ret ast:: view_item_export ( ids, p. get_id ( ) ) ;
2391
2411
}
0 commit comments