Skip to content

Commit

Permalink
Merge pull request #20 from clarkmcc/19-fix-operator-precedence
Browse files Browse the repository at this point in the history
Fixed operator precedence #19
  • Loading branch information
clarkmcc authored Sep 18, 2023
2 parents 9f7210f + 6f61014 commit 34c5aab
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
4 changes: 2 additions & 2 deletions interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
name = "cel-interpreter"
description = "An interpreter for the Common Expression Language (CEL)"
repository = "https://github.com/clarkmcc/cel-rust"
version = "0.4.0"
version = "0.4.1"
authors = ["Tom Forbes <[email protected]>", "Clark McCauley <[email protected]>"]
edition = "2018"
license = "MIT"
categories = ["interpreter", "cel"]

[dependencies]
cel-parser = { path = "../parser", version = "0.5.0" }
cel-parser = { path = "../parser", version = "0.5.1" }
thiserror = "1.0.40"
chrono = "0.4.26"
nom = "7.1.3"
Expand Down
2 changes: 1 addition & 1 deletion parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cel-parser"
description = "A parser for the Common Expression Language (CEL)"
repository = "https://github.com/clarkmcc/cel-rust"
version = "0.5.0"
version = "0.5.1"
authors = ["Tom Forbes <[email protected]>", "Clark McCauley <[email protected]>"]
edition = "2018"
license = "MIT"
Expand Down
52 changes: 42 additions & 10 deletions parser/src/cel.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,42 @@ match {
}

pub Expression: Expression = {
<left:Expression> <op:ArithmeticOp> <right:Member> => Expression::Arithmetic(left.into(), op, right.into()),
<left:Expression> <op:RelationOp> <right:Member> => Expression::Relation(left.into(), op, right.into()),
<condition:Expression> "?" <left:Member> ":" <right:Primary> => Expression::Ternary(condition.into(), left.into(), right.into()),
<left:Expression> "||" <right:Member> => Expression::Or(left.into(), right.into()),
<left:Expression> "&&" <right:Member> => Expression::And(left.into(), right.into()),
<op:UnaryOp> <right:Member> => Expression::Unary(op, right.into()),
Conditional
};

pub Conditional: Expression = {
<condition:LogicalOr> "?" <if_true:LogicalOr> ":" <if_false:Conditional> => Expression::Ternary(condition.into(), if_true.into(), if_false.into()),
LogicalOr
};

pub LogicalOr: Expression = {
<left:LogicalOr> "||" <right:LogicalAnd> => Expression::Or(left.into(), right.into()),
LogicalAnd
};

pub LogicalAnd: Expression = {
<left:LogicalAnd> "&&" <right:Relations> => Expression::And(left.into(), right.into()),
Relations
};

pub Relations: Expression = {
<left:ArithmeticAddSub> <op:RelationOp> <right:ArithmeticAddSub> => Expression::Relation(left.into(), op, right.into()),
ArithmeticAddSub
};

pub ArithmeticAddSub: Expression = {
<left:ArithmeticAddSub> <op:ArithmeticOpAddSub> <right:ArithmeticMulDivMod> => Expression::Arithmetic(left.into(), op, right.into()),
ArithmeticMulDivMod
};

Member,
pub ArithmeticMulDivMod: Expression = {
<left:ArithmeticMulDivMod> <op:ArithmeticOpMulDivMod> <right:Unary> => Expression::Arithmetic(left.into(), op, right.into()),
Unary
};

pub Unary: Expression = {
<op:UnaryOp> <right:Member> => Expression::Unary(op, right.into()),
Member
};

pub Member: Expression = {
Expand Down Expand Up @@ -64,14 +92,18 @@ CommaSeparated<T>: Vec<T> = {
}
};

ArithmeticOp: ArithmeticOp = { // (3)
ArithmeticOpAddSub: ArithmeticOp = {
"+" => ArithmeticOp::Add,
"-" => ArithmeticOp::Subtract,
"-" => ArithmeticOp::Subtract
};

ArithmeticOpMulDivMod: ArithmeticOp = {
"*" => ArithmeticOp::Multiply,
"/" => ArithmeticOp::Divide,
"%" => ArithmeticOp::Modulus,
"%" => ArithmeticOp::Modulus
};


UnaryOp: UnaryOp = {
"!" => UnaryOp::Not,
"!!" => UnaryOp::DoubleNot,
Expand Down
15 changes: 15 additions & 0 deletions parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,4 +491,19 @@ mod tests {
),
);
}

#[test]
fn test_operator_precedence() {
assert_parse_eq(
"a && b == 'string'",
And(
Box::new(Ident("a".to_string().into())),
Box::new(Relation(
Box::new(Ident("b".to_string().into())),
RelationOp::Equals,
Box::new(Expression::Atom(String("string".to_string().into()))),
)),
),
);
}
}

0 comments on commit 34c5aab

Please sign in to comment.