@@ -62,7 +62,7 @@ use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
62
62
use ast:: { ViewPath , ViewPathGlob , ViewPathList , ViewPathSimple } ;
63
63
use ast:: { Visibility , WhereClause } ;
64
64
use ast;
65
- use ast_util:: { self , as_prec, ident_to_path, operator_prec} ;
65
+ use ast_util:: { self , prefix_prec , as_prec, range_prec , ident_to_path, operator_prec} ;
66
66
use codemap:: { self , Span , BytePos , Spanned , spanned, mk_sp} ;
67
67
use diagnostic;
68
68
use ext:: tt:: macro_parser;
@@ -93,7 +93,6 @@ bitflags! {
93
93
const RESTRICTION_STMT_EXPR = 0b0001 ,
94
94
const RESTRICTION_NO_BAR_OP = 0b0010 ,
95
95
const RESTRICTION_NO_STRUCT_LITERAL = 0b0100 ,
96
- const RESTRICTION_NO_DOTS = 0b1000 ,
97
96
}
98
97
}
99
98
@@ -2769,34 +2768,35 @@ impl<'a> Parser<'a> {
2769
2768
}
2770
2769
2771
2770
/// Parse a prefix-operator expr
2772
- pub fn parse_prefix_expr ( & mut self ) -> P < Expr > {
2771
+ /// only operators with a precedence >= min_prec will be accepted
2772
+ pub fn parse_prefix_expr ( & mut self , min_prec : uint ) -> P < Expr > {
2773
2773
let lo = self . span . lo ;
2774
2774
let hi;
2775
2775
2776
2776
let ex;
2777
2777
match self . token {
2778
2778
token:: Not => {
2779
2779
self . bump ( ) ;
2780
- let e = self . parse_prefix_expr ( ) ;
2780
+ let e = self . parse_prefix_expr ( prefix_prec ) ;
2781
2781
hi = e. span . hi ;
2782
2782
ex = self . mk_unary ( UnNot , e) ;
2783
2783
}
2784
2784
token:: BinOp ( token:: Minus ) => {
2785
2785
self . bump ( ) ;
2786
- let e = self . parse_prefix_expr ( ) ;
2786
+ let e = self . parse_prefix_expr ( prefix_prec ) ;
2787
2787
hi = e. span . hi ;
2788
2788
ex = self . mk_unary ( UnNeg , e) ;
2789
2789
}
2790
2790
token:: BinOp ( token:: Star ) => {
2791
2791
self . bump ( ) ;
2792
- let e = self . parse_prefix_expr ( ) ;
2792
+ let e = self . parse_prefix_expr ( prefix_prec ) ;
2793
2793
hi = e. span . hi ;
2794
2794
ex = self . mk_unary ( UnDeref , e) ;
2795
2795
}
2796
2796
token:: BinOp ( token:: And ) | token:: AndAnd => {
2797
2797
self . expect_and ( ) ;
2798
2798
let m = self . parse_mutability ( ) ;
2799
- let e = self . parse_prefix_expr ( ) ;
2799
+ let e = self . parse_prefix_expr ( prefix_prec ) ;
2800
2800
hi = e. span . hi ;
2801
2801
ex = ExprAddrOf ( m, e) ;
2802
2802
}
@@ -2810,14 +2810,14 @@ impl<'a> Parser<'a> {
2810
2810
_ => self . obsolete ( last_span, ObsoleteSyntax :: OwnedExpr )
2811
2811
}
2812
2812
2813
- let e = self . parse_prefix_expr ( ) ;
2813
+ let e = self . parse_prefix_expr ( prefix_prec ) ;
2814
2814
hi = e. span . hi ;
2815
2815
ex = self . mk_unary ( UnUniq , e) ;
2816
2816
}
2817
- token:: DotDot if ! self . restrictions . contains ( RESTRICTION_NO_DOTS ) => {
2817
+ token:: DotDot if min_prec <= range_prec => {
2818
2818
// A range, closed above: `..expr`.
2819
2819
self . bump ( ) ;
2820
- let e = self . parse_expr ( ) ;
2820
+ let e = self . parse_binops ( range_prec + 1 ) ;
2821
2821
hi = e. span . hi ;
2822
2822
ex = self . mk_range ( None , Some ( e) ) ;
2823
2823
}
@@ -2848,15 +2848,15 @@ impl<'a> Parser<'a> {
2848
2848
"perhaps you meant `box() (foo)` instead?" ) ;
2849
2849
self . abort_if_errors ( ) ;
2850
2850
}
2851
- let subexpression = self . parse_prefix_expr ( ) ;
2851
+ let subexpression = self . parse_prefix_expr ( prefix_prec ) ;
2852
2852
hi = subexpression. span . hi ;
2853
2853
ex = ExprBox ( Some ( place) , subexpression) ;
2854
2854
return self . mk_expr ( lo, hi, ex) ;
2855
2855
}
2856
2856
}
2857
2857
2858
2858
// Otherwise, we use the unique pointer default.
2859
- let subexpression = self . parse_prefix_expr ( ) ;
2859
+ let subexpression = self . parse_prefix_expr ( prefix_prec ) ;
2860
2860
hi = subexpression. span . hi ;
2861
2861
// FIXME (pnkfelix): After working out kinks with box
2862
2862
// desugaring, should be `ExprBox(None, subexpression)`
@@ -2868,10 +2868,10 @@ impl<'a> Parser<'a> {
2868
2868
return self . mk_expr ( lo, hi, ex) ;
2869
2869
}
2870
2870
2871
- /// Parse an expression of binops
2872
- pub fn parse_binops ( & mut self ) -> P < Expr > {
2873
- let prefix_expr = self . parse_prefix_expr ( ) ;
2874
- self . parse_more_binops ( prefix_expr, 0 )
2871
+ /// Parse an expression of binops of at least min_prec precedence
2872
+ pub fn parse_binops ( & mut self , min_prec : uint ) -> P < Expr > {
2873
+ let prefix_expr = self . parse_prefix_expr ( min_prec ) ;
2874
+ self . parse_more_binops ( prefix_expr, min_prec )
2875
2875
}
2876
2876
2877
2877
/// Parse an expression of binops of at least min_prec precedence
@@ -2894,10 +2894,9 @@ impl<'a> Parser<'a> {
2894
2894
self . check_no_chained_comparison ( & * lhs, cur_op)
2895
2895
}
2896
2896
let cur_prec = operator_prec ( cur_op) ;
2897
- if cur_prec > min_prec {
2897
+ if cur_prec >= min_prec {
2898
2898
self . bump ( ) ;
2899
- let expr = self . parse_prefix_expr ( ) ;
2900
- let rhs = self . parse_more_binops ( expr, cur_prec) ;
2899
+ let rhs = self . parse_binops ( cur_prec + 1 ) ;
2901
2900
let lhs_span = lhs. span ;
2902
2901
let rhs_span = rhs. span ;
2903
2902
let binary = self . mk_binary ( cur_op, lhs, rhs) ;
@@ -2908,19 +2907,57 @@ impl<'a> Parser<'a> {
2908
2907
}
2909
2908
}
2910
2909
None => {
2911
- if as_prec > min_prec && self . eat_keyword ( keywords:: As ) {
2910
+ if as_prec >= min_prec && self . eat_keyword ( keywords:: As ) {
2912
2911
let rhs = self . parse_ty ( ) ;
2913
2912
let _as = self . mk_expr ( lhs. span . lo ,
2914
2913
rhs. span . hi ,
2915
2914
ExprCast ( lhs, rhs) ) ;
2916
2915
self . parse_more_binops ( _as, min_prec)
2916
+ } else if range_prec >= min_prec
2917
+ && match lhs. node { ExprRange ( _, _) => false , _ => true }
2918
+ && self . eat ( & token:: DotDot ) {
2919
+ // '..' range notation, infix or postfix form
2920
+ // Note that we intentionally reject other range expressions on the lhs.
2921
+ // This makes '..1..2' invalid.
2922
+ // This is necessary for consistency between the prefix and postfix forms.
2923
+ let opt_rhs = if self . is_at_start_of_range_notation_rhs ( ) {
2924
+ Some ( self . parse_binops ( range_prec + 1 ) )
2925
+ } else {
2926
+ None
2927
+ } ;
2928
+ let lo = lhs. span . lo ;
2929
+ let hi = self . span . hi ;
2930
+ let range = self . mk_range ( Some ( lhs) , opt_rhs) ;
2931
+ let bin = self . mk_expr ( lo, hi, range) ;
2932
+ self . parse_more_binops ( bin, min_prec)
2917
2933
} else {
2918
2934
lhs
2919
2935
}
2920
2936
}
2921
2937
}
2922
2938
}
2923
2939
2940
+ fn is_at_start_of_range_notation_rhs ( & self ) -> bool {
2941
+ if self . token . can_begin_expr ( ) {
2942
+ // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
2943
+ if self . token == token:: OpenDelim ( token:: Brace ) {
2944
+ return !self . restrictions . contains ( RESTRICTION_NO_STRUCT_LITERAL ) ;
2945
+ }
2946
+
2947
+ // `1..*i` is ambiguous between `1..(*i)` and `(1..)*(i)`.
2948
+ // We pick the `1..(*i)` interpretation.
2949
+
2950
+ // `r==1..&&true` is ambiguous between `r==(1..(&&true))` and `(r==(1..))&&true`.
2951
+ // We pick the latter interpretation.
2952
+ match self . token . to_binop ( ) {
2953
+ Some ( op) => operator_prec ( op) > range_prec,
2954
+ None => true
2955
+ }
2956
+ } else {
2957
+ false
2958
+ }
2959
+ }
2960
+
2924
2961
/// Produce an error if comparison operators are chained (RFC #558).
2925
2962
/// We only need to check lhs, not rhs, because all comparison ops
2926
2963
/// have same precedence and are left-associative
@@ -2944,7 +2981,7 @@ impl<'a> Parser<'a> {
2944
2981
/// actually, this seems to be the main entry point for
2945
2982
/// parsing an arbitrary expression.
2946
2983
pub fn parse_assign_expr ( & mut self ) -> P < Expr > {
2947
- let lhs = self . parse_binops ( ) ;
2984
+ let lhs = self . parse_binops ( 0 ) ;
2948
2985
self . parse_assign_expr_with ( lhs)
2949
2986
}
2950
2987
@@ -2976,23 +3013,6 @@ impl<'a> Parser<'a> {
2976
3013
let assign_op = self . mk_assign_op ( aop, lhs, rhs) ;
2977
3014
self . mk_expr ( span. lo , rhs_span. hi , assign_op)
2978
3015
}
2979
- // A range expression, either `expr..expr` or `expr..`.
2980
- token:: DotDot if !self . restrictions . contains ( RESTRICTION_NO_DOTS ) => {
2981
- self . bump ( ) ;
2982
-
2983
- let opt_end = if self . token . can_begin_expr ( ) {
2984
- let end = self . parse_expr_res ( RESTRICTION_NO_DOTS ) ;
2985
- Some ( end)
2986
- } else {
2987
- None
2988
- } ;
2989
-
2990
- let lo = lhs. span . lo ;
2991
- let hi = self . span . hi ;
2992
- let range = self . mk_range ( Some ( lhs) , opt_end) ;
2993
- return self . mk_expr ( lo, hi, range) ;
2994
- }
2995
-
2996
3016
_ => {
2997
3017
lhs
2998
3018
}
0 commit comments