compiler2: update operator precedence and associativity (#3218)
parent
c1f4fc3f0f
commit
fe8a6abb41
|
@ -13,10 +13,12 @@ struct Foo {}
|
||||||
// pub type Expr = Foo | IfExpr | BinaryExpr | IntegerExpr
|
// pub type Expr = Foo | IfExpr | BinaryExpr | IntegerExpr
|
||||||
pub type Expr = Foo | IfExpr | BinaryExpr | ScalarExpr | UnaryExpr
|
pub type Expr = Foo | IfExpr | BinaryExpr | ScalarExpr | UnaryExpr
|
||||||
|
|
||||||
// pub struct IntegerExpr {
|
/*
|
||||||
// pub:
|
pub struct IntegerExpr {
|
||||||
// val int
|
pub:
|
||||||
// }
|
val int
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
|
@ -92,28 +94,30 @@ pub fn (x Expr) str() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum BinaryOp {
|
/*
|
||||||
// sum
|
enum BinaryOp {
|
||||||
// difference
|
sum
|
||||||
// product
|
difference
|
||||||
// quotient
|
product
|
||||||
// remainder
|
quotient
|
||||||
// bitwise_and
|
remainder
|
||||||
// bitwise_or
|
bitwise_and
|
||||||
// bitwise_xor
|
bitwise_or
|
||||||
// left_shift
|
bitwise_xor
|
||||||
// right_shift
|
left_shift
|
||||||
|
right_shift
|
||||||
|
|
||||||
// equality
|
equality
|
||||||
// inequality
|
inequality
|
||||||
// less_than
|
less_than
|
||||||
// less_than_or_equal
|
less_than_or_equal
|
||||||
// more_than
|
more_than
|
||||||
// more_than_or_equal
|
more_than_or_equal
|
||||||
|
|
||||||
// in_check
|
in_check
|
||||||
|
|
||||||
// //These are suffixed with `bool` to prevent conflict with the keyword `or`
|
//These are suffixed with `bool` to prevent conflict with the keyword `or`
|
||||||
// and_bool
|
and_bool
|
||||||
// or_bool
|
or_bool
|
||||||
// }
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -12,12 +12,15 @@ fn test_parser() {
|
||||||
println('\n')
|
println('\n')
|
||||||
|
|
||||||
text_expr := [
|
text_expr := [
|
||||||
|
'1 += 2',
|
||||||
|
'1.2 + 3.4',
|
||||||
'4 + 4',
|
'4 + 4',
|
||||||
'1 + 2 * 5',
|
'1 + 2 * 5',
|
||||||
'(2 * 3) / 2',
|
'(2 * 3) / 2',
|
||||||
'3 + (7 * 6)',
|
'3 + (7 * 6)',
|
||||||
'2 ^ 8 * (7 * 6)',
|
'2 ^ 8 * (7 * 6)',
|
||||||
'(2) + (17*2-30) * (5)+2 - (8/2)*4'
|
'20 + (10 * 15) / 5', // 50
|
||||||
|
'(2) + (17*2-30) * (5)+2 - (8/2)*4' // 8
|
||||||
]
|
]
|
||||||
for s in text_expr {
|
for s in text_expr {
|
||||||
// print using str method
|
// print using str method
|
||||||
|
|
|
@ -313,10 +313,16 @@ const (
|
||||||
// Precedence returns a tokens precedence if defined, otherwise lowest_prec
|
// Precedence returns a tokens precedence if defined, otherwise lowest_prec
|
||||||
pub fn (tok Token) precedence() int {
|
pub fn (tok Token) precedence() int {
|
||||||
match tok {
|
match tok {
|
||||||
.plus, .minus { return 4 }
|
// `*` | `/` | `%` | `<<` | `>>` | `&`
|
||||||
.mul, .div { return 4 }
|
.mul, .div, .left_shift, .righ_shift, .amp { return 7 }
|
||||||
.xor { return 6 }
|
// `+` | `-` | `|` | `^`
|
||||||
.mod {return 7 }
|
.plus, .minus, .pipe, .xor { return 6 }
|
||||||
|
// `==` | `!=` | `<` | `<=` | `>` | `>=`
|
||||||
|
.eq, .ne, .lt, .le, .gt, .ge { return 5 }
|
||||||
|
// `&&`
|
||||||
|
.and { return 4 }
|
||||||
|
// `||`
|
||||||
|
.logical_or { return 3 }
|
||||||
else { return lowest_prec }
|
else { return lowest_prec }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,15 +338,25 @@ pub fn (tok Token) is_scalar() bool {
|
||||||
// is_unary returns true if the token can be in a unary expression
|
// is_unary returns true if the token can be in a unary expression
|
||||||
pub fn (tok Token) is_unary() bool {
|
pub fn (tok Token) is_unary() bool {
|
||||||
match tok {
|
match tok {
|
||||||
.plus, .minus { return true }
|
// `+` | `-` | `!` | `~` | `*` | `&`
|
||||||
|
.plus, .minus, .not, .bit_not, .mul, .amp { return true }
|
||||||
else { return false }
|
else { return false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: do we need this for all tokens (is_left_assoc / is_right_assoc),
|
||||||
|
// or only ones with the same precedence?
|
||||||
|
|
||||||
// is_left_assoc returns true if the token is left associative
|
// is_left_assoc returns true if the token is left associative
|
||||||
pub fn (tok Token) is_left_assoc() bool {
|
pub fn (tok Token) is_left_assoc() bool {
|
||||||
match tok {
|
match tok {
|
||||||
.number, .plus, .minus, .mul, .div, .mod { return true }
|
// .number,
|
||||||
|
// `*` | `/` | `%`
|
||||||
|
.mul, .div, .mod,
|
||||||
|
// `^` | `||` | `&`
|
||||||
|
.xor, .logical_or, .and,
|
||||||
|
// `,`
|
||||||
|
.comma { return true }
|
||||||
else { return false }
|
else { return false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,7 +364,14 @@ pub fn (tok Token) is_left_assoc() bool {
|
||||||
// is_right_assoc returns true if the token is right associative
|
// is_right_assoc returns true if the token is right associative
|
||||||
pub fn (tok Token) is_right_assoc() bool {
|
pub fn (tok Token) is_right_assoc() bool {
|
||||||
match tok {
|
match tok {
|
||||||
.xor { return true }
|
// `+` | `-` | `!` | `++` | `--`
|
||||||
|
.plus, .minus, .not, .inc, .dec,
|
||||||
|
// `=` | `+=` | `-=` | `*=` | `/=`
|
||||||
|
.assign, .plus_assign, .minus_assign, .mult_assign, .div_assign,
|
||||||
|
// `%=` | `>>=` | `<<=`
|
||||||
|
.mod_assign, .righ_shift_assign, .left_shift_assign,
|
||||||
|
// `&=` | `^=` | `|=`
|
||||||
|
.and_assign, .xor_assign, .or_assign { return true }
|
||||||
else { return false }
|
else { return false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue