Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5daf13ca
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5daf13ca
编写于
1月 13, 2016
作者:
A
Alex Burka
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
libsyntax: parse inclusive ranges
上级
c5d58de6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
81 addition
and
50 deletion
+81
-50
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+11
-2
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+3
-2
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+50
-37
src/libsyntax/parse/token.rs
src/libsyntax/parse/token.rs
+1
-1
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+6
-2
src/libsyntax/util/parser.rs
src/libsyntax/util/parser.rs
+9
-5
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+1
-1
未找到文件。
src/libsyntax/ast.rs
浏览文件 @
5daf13ca
...
...
@@ -886,6 +886,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy,
Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Debug)]
pub
enum
RangeLimits
{
/// Inclusive at the beginning, exclusive at the end
HalfOpen
,
/// Inclusive at the beginning and end
Closed
,
}
#[derive(Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Debug)]
pub
enum
ExprKind
{
/// A `box x` expression.
...
...
@@ -974,8 +983,8 @@ pub enum ExprKind {
TupField
(
P
<
Expr
>
,
Spanned
<
usize
>
),
/// An indexing operation (`foo[2]`)
Index
(
P
<
Expr
>
,
P
<
Expr
>
),
/// A range (`1..2`, `1..`,
or `
..2`)
Range
(
Option
<
P
<
Expr
>>
,
Option
<
P
<
Expr
>>
),
/// A range (`1..2`, `1..`,
`..2`, `1...2`, `1...`, `.
..2`)
Range
(
Option
<
P
<
Expr
>>
,
Option
<
P
<
Expr
>>
,
RangeLimits
),
/// Variable reference, possibly containing `::` and/or type
/// parameters, e.g. foo::bar::<baz>.
...
...
src/libsyntax/fold.rs
浏览文件 @
5daf13ca
...
...
@@ -1273,9 +1273,10 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
ExprKind
::
Index
(
el
,
er
)
=>
{
ExprKind
::
Index
(
folder
.fold_expr
(
el
),
folder
.fold_expr
(
er
))
}
ExprKind
::
Range
(
e1
,
e2
)
=>
{
ExprKind
::
Range
(
e1
,
e2
,
lim
)
=>
{
ExprKind
::
Range
(
e1
.map
(|
x
|
folder
.fold_expr
(
x
)),
e2
.map
(|
x
|
folder
.fold_expr
(
x
)))
e2
.map
(|
x
|
folder
.fold_expr
(
x
)),
lim
)
}
ExprKind
::
Path
(
qself
,
path
)
=>
{
let
qself
=
qself
.map
(|
QSelf
{
ty
,
position
}|
{
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
5daf13ca
...
...
@@ -20,7 +20,7 @@
use
ast
::{
Constness
,
Crate
,
CrateConfig
};
use
ast
::{
Decl
,
DeclKind
};
use
ast
::{
EMPTY_CTXT
,
EnumDef
,
ExplicitSelf
};
use
ast
::{
Expr
,
ExprKind
};
use
ast
::{
Expr
,
ExprKind
,
RangeLimits
};
use
ast
::{
Field
,
FnDecl
};
use
ast
::{
ForeignItem
,
ForeignItemKind
,
FunctionRetTy
};
use
ast
::{
Ident
,
ImplItem
,
Item
,
ItemKind
};
...
...
@@ -2054,9 +2054,10 @@ pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
pub
fn
mk_range
(
&
mut
self
,
start
:
Option
<
P
<
Expr
>>
,
end
:
Option
<
P
<
Expr
>>
)
->
ast
::
ExprKind
{
ExprKind
::
Range
(
start
,
end
)
end
:
Option
<
P
<
Expr
>>
,
limits
:
RangeLimits
)
->
ast
::
Expr_
{
ExprKind
::
Range
(
start
,
end
,
limits
)
}
pub
fn
mk_field
(
&
mut
self
,
expr
:
P
<
Expr
>
,
ident
:
ast
::
SpannedIdent
)
->
ast
::
ExprKind
{
...
...
@@ -2894,7 +2895,7 @@ pub fn parse_assoc_expr_with(&mut self,
LhsExpr
::
AttributesParsed
(
attrs
)
=>
Some
(
attrs
),
_
=>
None
,
};
if
self
.token
==
token
::
DotDot
{
if
self
.token
==
token
::
DotDot
||
self
.token
==
token
::
DotDotDot
{
return
self
.parse_prefix_range_expr
(
attrs
);
}
else
{
try!
(
self
.parse_prefix_expr
(
attrs
))
...
...
@@ -2940,32 +2941,32 @@ pub fn parse_assoc_expr_with(&mut self,
ExprKind
::
Type
(
lhs
,
rhs
),
None
);
continue
}
else
if
op
==
AssocOp
::
DotDot
{
// If we didn’t have to handle `x..`, it would be pretty easy to generalise
// it to the Fixity::None code.
//
// We have 2 alternatives here: `x..y` and `x..` The other two variants are
// handled with `parse_prefix_range_expr` call above.
let
rhs
=
if
self
.is_at_start_of_range_notation_rhs
()
{
let
rhs
=
self
.parse_assoc_expr_with
(
op
.precedence
()
+
1
,
LhsExpr
::
NotYetParsed
);
match
rhs
{
Ok
(
e
)
=>
Some
(
e
),
Err
(
mut
e
)
=>
{
e
.cancel
();
None
}
// If we didn’t have to handle `x..`, it would be pretty easy to generalise
// it to the Fixity::None code.
//
// We have 2 alternatives here: `x..y` and `x..` The other two variants are
// handled with `parse_prefix_range_expr` call above.
let
rhs
=
if
self
.is_at_start_of_range_notation_rhs
()
{
let
rhs
=
self
.parse_assoc_expr_with
(
op
.precedence
()
+
1
,
LhsExpr
::
NotYetParsed
);
match
rhs
{
Ok
(
e
)
=>
Some
(
e
),
Err
(
mut
e
)
=>
{
e
.cancel
();
None
}
}
else
{
None
};
let
(
lhs_span
,
rhs_span
)
=
(
lhs_span
,
if
let
Some
(
ref
x
)
=
rhs
{
x
.span
}
else
{
cur_op_span
});
let
r
=
self
.mk_range
(
Some
(
lhs
),
rhs
);
lhs
=
self
.mk_expr
(
lhs_span
.lo
,
rhs_span
.hi
,
r
,
None
);
break
}
}
else
{
None
};
let
(
lhs_span
,
rhs_span
)
=
(
lhs
.span
,
if
let
Some
(
ref
x
)
=
rhs
{
x
.span
}
else
{
cur_op_span
});
let
r
=
self
.mk_range
(
Some
(
lhs
),
rhs
,
RangeLimits
::
HalfOpen
);
lhs
=
self
.mk_expr
(
lhs_span
.lo
,
rhs_span
.hi
,
r
,
None
);
break
}
let
rhs
=
try!
(
match
op
.fixity
()
{
...
...
@@ -2981,8 +2982,8 @@ pub fn parse_assoc_expr_with(&mut self,
this
.parse_assoc_expr_with
(
op
.precedence
()
+
1
,
LhsExpr
::
NotYetParsed
)
}),
//
We currently have no non-associative operators that are not handled above by
//
the special cases. The code is here only for future convenience.
//
the only operator handled here is `...` (the other non-associative operators are
//
special-cased above)
Fixity
::
None
=>
self
.with_res
(
restrictions
-
Restrictions
::
RESTRICTION_STMT_EXPR
,
|
this
|
{
...
...
@@ -3023,6 +3024,11 @@ pub fn parse_assoc_expr_with(&mut self,
let
aopexpr
=
self
.mk_assign_op
(
codemap
::
respan
(
cur_op_span
,
aop
),
lhs
,
rhs
);
self
.mk_expr
(
lhs_span
.lo
,
rhs_span
.hi
,
aopexpr
,
None
)
}
AssocOp
::
DotDotDot
=>
{
let
(
lhs_span
,
rhs_span
)
=
(
lhs
.span
,
rhs
.span
);
let
r
=
self
.mk_range
(
Some
(
lhs
),
Some
(
rhs
),
RangeLimits
::
Closed
);
self
.mk_expr
(
lhs_span
.lo
,
rhs_span
.hi
,
r
,
None
)
}
AssocOp
::
As
|
AssocOp
::
Colon
|
AssocOp
::
DotDot
=>
{
self
.bug
(
"As, Colon or DotDot branch reached"
)
}
...
...
@@ -3054,18 +3060,19 @@ fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
}
}
/// Parse prefix-forms of range notation: `..expr`
and `..
`
/// Parse prefix-forms of range notation: `..expr`
, `..`, `...expr
`
fn
parse_prefix_range_expr
(
&
mut
self
,
already_parsed_attrs
:
Option
<
ThinAttributes
>
)
->
PResult
<
'a
,
P
<
Expr
>>
{
debug_assert!
(
self
.token
==
token
::
DotDot
);
debug_assert!
(
self
.token
==
token
::
DotDot
||
self
.token
==
token
::
DotDotDot
);
let
tok
=
self
.token
.clone
();
let
attrs
=
try!
(
self
.parse_or_use_outer_attributes
(
already_parsed_attrs
));
let
lo
=
self
.span.lo
;
let
mut
hi
=
self
.span.hi
;
self
.bump
();
let
opt_end
=
if
self
.is_at_start_of_range_notation_rhs
()
{
// RHS must be parsed with more associativity than
DotDot
.
let
next_prec
=
AssocOp
::
from_token
(
&
tok
en
::
DotDot
)
.unwrap
()
.precedence
()
+
1
;
// RHS must be parsed with more associativity than
the dots
.
let
next_prec
=
AssocOp
::
from_token
(
&
tok
)
.unwrap
()
.precedence
()
+
1
;
Some
(
try!
(
self
.parse_assoc_expr_with
(
next_prec
,
LhsExpr
::
NotYetParsed
)
.map
(|
x
|{
...
...
@@ -3075,7 +3082,13 @@ fn parse_prefix_range_expr(&mut self,
}
else
{
None
};
let
r
=
self
.mk_range
(
None
,
opt_end
);
let
r
=
self
.mk_range
(
None
,
opt_end
,
if
tok
==
token
::
DotDot
{
RangeLimits
::
HalfOpen
}
else
{
RangeLimits
::
Closed
});
Ok
(
self
.mk_expr
(
lo
,
hi
,
r
,
attrs
))
}
...
...
src/libsyntax/parse/token.rs
浏览文件 @
5daf13ca
...
...
@@ -196,7 +196,7 @@ pub fn can_begin_expr(&self) -> bool {
BinOp
(
Or
)
=>
true
,
// in lambda syntax
OrOr
=>
true
,
// in lambda syntax
AndAnd
=>
true
,
// double borrow
DotDot
=>
true
,
// range notation
DotDot
|
DotDotDot
=>
true
,
// range notation
ModSep
=>
true
,
Interpolated
(
NtExpr
(
..
))
=>
true
,
Interpolated
(
NtIdent
(
..
))
=>
true
,
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
5daf13ca
...
...
@@ -2163,11 +2163,15 @@ fn print_expr_outer_attr_style(&mut self,
try!
(
self
.print_expr
(
&
index
));
try!
(
word
(
&
mut
self
.s
,
"]"
));
}
ast
::
ExprKin
d
::
Range
(
ref
start
,
ref
end
)
=>
{
ast
::
ExprKin
g
::
Range
(
ref
start
,
ref
end
,
limits
)
=>
{
if
let
&
Some
(
ref
e
)
=
start
{
try!
(
self
.print_expr
(
&
e
));
}
try!
(
word
(
&
mut
self
.s
,
".."
));
if
limits
==
ast
::
RangeLimits
::
HalfOpen
{
try!
(
word
(
&
mut
self
.s
,
".."
));
}
else
{
try!
(
word
(
&
mut
self
.s
,
"..."
));
}
if
let
&
Some
(
ref
e
)
=
end
{
try!
(
self
.print_expr
(
&
e
));
}
...
...
src/libsyntax/util/parser.rs
浏览文件 @
5daf13ca
...
...
@@ -61,6 +61,8 @@ pub enum AssocOp {
As
,
/// `..` range
DotDot
,
/// `...` range
DotDotDot
,
/// `:`
Colon
,
}
...
...
@@ -102,6 +104,7 @@ pub fn from_token(t: &Token) -> Option<AssocOp> {
Token
::
AndAnd
=>
Some
(
LAnd
),
Token
::
OrOr
=>
Some
(
LOr
),
Token
::
DotDot
=>
Some
(
DotDot
),
Token
::
DotDotDot
=>
Some
(
DotDotDot
),
Token
::
Colon
=>
Some
(
Colon
),
_
if
t
.is_keyword
(
keywords
::
As
)
=>
Some
(
As
),
_
=>
None
...
...
@@ -147,7 +150,7 @@ pub fn precedence(&self) -> usize {
Less
|
Greater
|
LessEqual
|
GreaterEqual
|
Equal
|
NotEqual
=>
7
,
LAnd
=>
6
,
LOr
=>
5
,
DotDot
=>
4
,
DotDot
|
DotDotDot
=>
4
,
Inplace
=>
3
,
Assign
|
AssignOp
(
_
)
=>
2
,
}
...
...
@@ -162,7 +165,7 @@ pub fn fixity(&self) -> Fixity {
As
|
Multiply
|
Divide
|
Modulus
|
Add
|
Subtract
|
ShiftLeft
|
ShiftRight
|
BitAnd
|
BitXor
|
BitOr
|
Less
|
Greater
|
LessEqual
|
GreaterEqual
|
Equal
|
NotEqual
|
LAnd
|
LOr
|
Colon
=>
Fixity
::
Left
,
DotDot
=>
Fixity
::
None
DotDot
|
DotDotDot
=>
Fixity
::
None
}
}
...
...
@@ -171,7 +174,8 @@ pub fn is_comparison(&self) -> bool {
match
*
self
{
Less
|
Greater
|
LessEqual
|
GreaterEqual
|
Equal
|
NotEqual
=>
true
,
Inplace
|
Assign
|
AssignOp
(
_
)
|
As
|
Multiply
|
Divide
|
Modulus
|
Add
|
Subtract
|
ShiftLeft
|
ShiftRight
|
BitAnd
|
BitXor
|
BitOr
|
LAnd
|
LOr
|
DotDot
|
Colon
=>
false
ShiftLeft
|
ShiftRight
|
BitAnd
|
BitXor
|
BitOr
|
LAnd
|
LOr
|
DotDot
|
DotDotDot
|
Colon
=>
false
}
}
...
...
@@ -181,7 +185,7 @@ pub fn is_assign_like(&self) -> bool {
Assign
|
AssignOp
(
_
)
|
Inplace
=>
true
,
Less
|
Greater
|
LessEqual
|
GreaterEqual
|
Equal
|
NotEqual
|
As
|
Multiply
|
Divide
|
Modulus
|
Add
|
Subtract
|
ShiftLeft
|
ShiftRight
|
BitAnd
|
BitXor
|
BitOr
|
LAnd
|
LOr
|
DotDot
|
Colon
=>
false
LOr
|
DotDot
|
DotDotDot
|
Colon
=>
false
}
}
...
...
@@ -206,7 +210,7 @@ pub fn to_ast_binop(&self) -> Option<BinOpKind> {
BitOr
=>
Some
(
BinOpKind
::
BitOr
),
LAnd
=>
Some
(
BinOpKind
::
And
),
LOr
=>
Some
(
BinOpKind
::
Or
),
Inplace
|
Assign
|
AssignOp
(
_
)
|
As
|
DotDot
|
Colon
=>
None
Inplace
|
Assign
|
AssignOp
(
_
)
|
As
|
DotDot
|
DotDotDot
|
Colon
=>
None
}
}
}
src/libsyntax/visit.rs
浏览文件 @
5daf13ca
...
...
@@ -763,7 +763,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor
.visit_expr
(
main_expression
);
visitor
.visit_expr
(
index_expression
)
}
ExprKind
::
Range
(
ref
start
,
ref
end
)
=>
{
ExprKind
::
Range
(
ref
start
,
ref
end
,
_
)
=>
{
walk_list!
(
visitor
,
visit_expr
,
start
);
walk_list!
(
visitor
,
visit_expr
,
end
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录