Skip to content

Commit

Permalink
Move ExprPrecedence to libsyntax/util/parser.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jan 15, 2018
1 parent afe8d13 commit 71c0873
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 136 deletions.
2 changes: 1 addition & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use syntax::ptr::P;
use syntax::symbol::{Symbol, keywords};
use syntax::tokenstream::TokenStream;
use syntax::util::ThinVec;
use syntax::ast::ExprPrecedence;
use syntax::util::parser::ExprPrecedence;
use ty::AdtKind;

use rustc_data_structures::indexed_vec;
Expand Down
136 changes: 1 addition & 135 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,7 @@ pub use self::UnsafeSource::*;
pub use self::PathParameters::*;
pub use symbol::{Ident, Symbol as Name};
pub use util::ThinVec;
pub use util::parser::{
AssocOp,
PREC_RESET,
PREC_CLOSURE,
PREC_JUMP,
PREC_RANGE,
PREC_PREFIX,
PREC_POSTFIX,
PREC_PAREN,
PREC_FORCE_PAREN,
};
pub use util::parser::ExprPrecedence;

use syntax_pos::{Span, DUMMY_SP};
use codemap::{respan, Spanned};
Expand All @@ -39,7 +29,6 @@ use tokenstream::{ThinTokenStream, TokenStream};

use serialize::{self, Encoder, Decoder};
use std::collections::HashSet;
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
use std::u32;
Expand Down Expand Up @@ -917,129 +906,6 @@ pub struct Expr {
pub attrs: ThinVec<Attribute>
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExprPrecedence {
Closure,
Break,
Continue,
Ret,
Yield,

Range,

Binary(BinOpKind),

InPlace,
Cast,
Type,

Assign,
AssignOp,

Box,
AddrOf,
Unary,

Call,
MethodCall,
Field,
TupField,
Index,
Try,
InlineAsm,
Mac,

Array,
Repeat,
Tup,
Lit,
Path,
Paren,
If,
IfLet,
While,
WhileLet,
ForLoop,
Loop,
Match,
Block,
Catch,
Struct,
}

impl PartialOrd for ExprPrecedence {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.order().cmp(&other.order()))
}
}

impl Ord for ExprPrecedence {
fn cmp(&self, other: &Self) -> Ordering {
self.order().cmp(&other.order())
}
}

impl ExprPrecedence {
pub fn order(self) -> i8 {
match self {
ExprPrecedence::Closure => PREC_CLOSURE,

ExprPrecedence::Break |
ExprPrecedence::Continue |
ExprPrecedence::Ret |
ExprPrecedence::Yield => PREC_JUMP,

// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
// ensures that `pprust` will add parentheses in the right places to get the desired
// parse.
ExprPrecedence::Range => PREC_RANGE,

// Binop-like expr kinds, handled by `AssocOp`.
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8,
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
ExprPrecedence::Type => AssocOp::Colon.precedence() as i8,

ExprPrecedence::Assign |
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,

// Unary, prefix
ExprPrecedence::Box |
ExprPrecedence::AddrOf |
ExprPrecedence::Unary => PREC_PREFIX,

// Unary, postfix
ExprPrecedence::Call |
ExprPrecedence::MethodCall |
ExprPrecedence::Field |
ExprPrecedence::TupField |
ExprPrecedence::Index |
ExprPrecedence::Try |
ExprPrecedence::InlineAsm |
ExprPrecedence::Mac => PREC_POSTFIX,

// Never need parens
ExprPrecedence::Array |
ExprPrecedence::Repeat |
ExprPrecedence::Tup |
ExprPrecedence::Lit |
ExprPrecedence::Path |
ExprPrecedence::Paren |
ExprPrecedence::If |
ExprPrecedence::IfLet |
ExprPrecedence::While |
ExprPrecedence::WhileLet |
ExprPrecedence::ForLoop |
ExprPrecedence::Loop |
ExprPrecedence::Match |
ExprPrecedence::Block |
ExprPrecedence::Catch |
ExprPrecedence::Struct => PREC_PAREN,
}
}
}

impl Expr {
/// Wether this expression would be valid somewhere that expects a value, for example, an `if`
/// condition.
Expand Down
126 changes: 126 additions & 0 deletions src/libsyntax/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use parse::token::{Token, BinOpToken};
use symbol::keywords;
use ast::{self, BinOpKind};

use std::cmp::Ordering;

/// Associative operator with precedence.
///
/// This is the enum which specifies operator precedence and fixity to the parser.
Expand Down Expand Up @@ -228,6 +230,130 @@ pub const PREC_POSTFIX: i8 = 60;
pub const PREC_PAREN: i8 = 99;
pub const PREC_FORCE_PAREN: i8 = 100;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExprPrecedence {
Closure,
Break,
Continue,
Ret,
Yield,

Range,

Binary(BinOpKind),

InPlace,
Cast,
Type,

Assign,
AssignOp,

Box,
AddrOf,
Unary,

Call,
MethodCall,
Field,
TupField,
Index,
Try,
InlineAsm,
Mac,

Array,
Repeat,
Tup,
Lit,
Path,
Paren,
If,
IfLet,
While,
WhileLet,
ForLoop,
Loop,
Match,
Block,
Catch,
Struct,
}

impl PartialOrd for ExprPrecedence {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.order().cmp(&other.order()))
}
}

impl Ord for ExprPrecedence {
fn cmp(&self, other: &Self) -> Ordering {
self.order().cmp(&other.order())
}
}

impl ExprPrecedence {
pub fn order(self) -> i8 {
match self {
ExprPrecedence::Closure => PREC_CLOSURE,

ExprPrecedence::Break |
ExprPrecedence::Continue |
ExprPrecedence::Ret |
ExprPrecedence::Yield => PREC_JUMP,

// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
// ensures that `pprust` will add parentheses in the right places to get the desired
// parse.
ExprPrecedence::Range => PREC_RANGE,

// Binop-like expr kinds, handled by `AssocOp`.
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8,
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
ExprPrecedence::Type => AssocOp::Colon.precedence() as i8,

ExprPrecedence::Assign |
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,

// Unary, prefix
ExprPrecedence::Box |
ExprPrecedence::AddrOf |
ExprPrecedence::Unary => PREC_PREFIX,

// Unary, postfix
ExprPrecedence::Call |
ExprPrecedence::MethodCall |
ExprPrecedence::Field |
ExprPrecedence::TupField |
ExprPrecedence::Index |
ExprPrecedence::Try |
ExprPrecedence::InlineAsm |
ExprPrecedence::Mac => PREC_POSTFIX,

// Never need parens
ExprPrecedence::Array |
ExprPrecedence::Repeat |
ExprPrecedence::Tup |
ExprPrecedence::Lit |
ExprPrecedence::Path |
ExprPrecedence::Paren |
ExprPrecedence::If |
ExprPrecedence::IfLet |
ExprPrecedence::While |
ExprPrecedence::WhileLet |
ExprPrecedence::ForLoop |
ExprPrecedence::Loop |
ExprPrecedence::Match |
ExprPrecedence::Block |
ExprPrecedence::Catch |
ExprPrecedence::Struct => PREC_PAREN,
}
}
}


/// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any
/// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
Expand Down

0 comments on commit 71c0873

Please sign in to comment.