diff --git a/Cargo.lock b/Cargo.lock index 846f2c4..4c3a172 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,7 +292,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.14.14" +version = "0.14.15" dependencies = [ "display_source", "parser", @@ -337,7 +337,7 @@ dependencies = [ [[package]] name = "parser" -version = "0.2.1" +version = "0.3.0" dependencies = [ "lalrpop", "lalrpop-util", @@ -348,7 +348,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.8" +version = "0.1.9" dependencies = [ "parser", "syntax", diff --git a/Cargo.toml b/Cargo.toml index e0b38f8..024b51d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.14.14" +version = "0.14.15" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/op_expr.mdtlbl b/examples/op_expr.mdtlbl index dec83a6..2d6a7f3 100644 --- a/examples/op_expr.mdtlbl +++ b/examples/op_expr.mdtlbl @@ -22,17 +22,20 @@ * | `a & b` | `a & b` | -6 | LR | * | `a ^ b` | `a ^ b` | -7 | LR | * | `a | b` | `a | b` | -8 | LR | -* | `a == b` | `a == b` | -9 | LR | -* | `a != b` | `a != b` | -9 | LR | -* | `a < b` | `a < b` | -9 | LR | -* | `a > b` | `a > b` | -9 | LR | -* | `a <= b` | `a <= b` | -9 | LR | -* | `a >= b` | `a >= b` | -9 | LR | -* | `a === b` | `a === b` | -9 | LR | -* | `a !== b` | `a !== b` | -9 | LR | -* | `a && b` | `a && b` | -10 | LR | -* | `a || b` | `a + b` | -11 | LR | -* | `if c?a:b` | ... | -12 | LR | +* | `a < b` | `a < b` | -9 | - | +* | `a > b` | `a > b` | -9 | - | +* | `a <= b` | `a <= b` | -9 | - | +* | `a >= b` | `a >= b` | -9 | - | +* | `a == b` | `a == b` | -10 | - | +* | `a != b` | `a != b` | -10 | - | +* | `a === b` | `a === b` | -10 | - | +* | `a !== b` | `a !== b` | -10 | - | +* | `a && b` | `a && b` | -11 | LR | +* | `a || b` | `a + b` | -12 | LR | +* | `if c?a:b` | ... | -13 | LR | +* +* 结合性的`LR`指左结合 比如`a+b+c`结合为`(a+b)+c` +* 而结合性为`-`指不发生结合, 将需要添加括号 * * 以上表格外, 还有一元与二元函数(其实就是op) * 它们的优先级与括号平级, diff --git a/tools/parser/Cargo.toml b/tools/parser/Cargo.toml index 39147a8..849d9cf 100644 --- a/tools/parser/Cargo.toml +++ b/tools/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser" -version = "0.2.1" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/src/parser.lalrpop b/tools/parser/src/parser.lalrpop index cc6fa31..ff417ae 100644 --- a/tools/parser/src/parser.lalrpop +++ b/tools/parser/src/parser.lalrpop @@ -457,43 +457,35 @@ OpExprDoMultiple: (Vec, Vec) = { }, } -OpExprBody: OpExprInfo = OpExprBody12; +OpExprBody: OpExprInfo = OpExprBody13; -OpExprBody12: OpExprInfo = { - "if" "?" ":" => { +OpExprBody13: OpExprInfo = { + "if" "?" ":" => { OpExprInfo::new_if_else(meta, cmp, a, b) }, - OpExprBody11, + OpExprBody12, } -OpExprBody11: OpExprInfo = { - "||" => op_expr_build_op( +OpExprBody12: OpExprInfo = { + "||" => op_expr_build_op( || Op::Add(ResultHandle, a.into_value(meta), b.into_value(meta))), - OpExprBody10, + OpExprBody11, } -OpExprBody10: OpExprInfo = { - "&&" => op_expr_build_op( +OpExprBody11: OpExprInfo = { + "&&" => op_expr_build_op( || Op::Land(ResultHandle, a.into_value(meta), b.into_value(meta))), - OpExprBody9, + OpExprBody10, } -OpExprBody9: OpExprInfo = { - "==" => op_expr_build_op( +OpExprBody10: OpExprInfo = { + "==" => op_expr_build_op( || Op::Equal(ResultHandle, a.into_value(meta), b.into_value(meta))), - "!=" => op_expr_build_op( + "!=" => op_expr_build_op( || Op::NotEqual(ResultHandle, a.into_value(meta), b.into_value(meta))), - "<" => op_expr_build_op( - || Op::LessThan(ResultHandle, a.into_value(meta), b.into_value(meta))), - ">" => op_expr_build_op( - || Op::GreaterThan(ResultHandle, a.into_value(meta), b.into_value(meta))), - "<=" => op_expr_build_op( - || Op::LessThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))), - ">=" => op_expr_build_op( - || Op::GreaterThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))), - "===" => op_expr_build_op( + "===" => op_expr_build_op( || Op::StrictEqual(ResultHandle, a.into_value(meta), b.into_value(meta))), - "!==" => + "!==" => op_expr_build_op(|| Op::Equal( ResultHandle, DExp::new_nores(vec![ @@ -501,6 +493,17 @@ OpExprBody9: OpExprInfo = { ].into()).into(), ReprVar(FALSE_VAR.into()) )), + OpExprBody9, +} +OpExprBody9: OpExprInfo = { + "<" => op_expr_build_op( + || Op::LessThan(ResultHandle, a.into_value(meta), b.into_value(meta))), + ">" => op_expr_build_op( + || Op::GreaterThan(ResultHandle, a.into_value(meta), b.into_value(meta))), + "<=" => op_expr_build_op( + || Op::LessThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))), + ">=" => op_expr_build_op( + || Op::GreaterThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))), OpExprBody8, } diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index 2d2b9fa..405adc6 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.8" +version = "0.1.9" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/tests/src/lib.rs b/tools/parser/tests/src/lib.rs index 9c63d57..c18a4e8 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -2229,6 +2229,47 @@ fn op_expr_test() { "#).unwrap(), ); + assert_eq!( + parse!(parser, r#" + x = a < b == c > d; + x = a < b != c > d; + x = a < b === c > d; + x = a < b !== c > d; + "#).unwrap(), + parse!(parser, r#" + op x (op $ a < b;) == (op $ c > d;); + op x (op $ a < b;) != (op $ c > d;); + op x (op $ a < b;) === (op $ c > d;); + op x (op $ a < b;) !== (op $ c > d;); + "#).unwrap(), + ); + + assert!( + parse!(parser, r#" + x = a == b == c; + "#).is_err(), + ); + + assert!( + parse!(parser, r#" + x = a < b < c; + "#).is_err(), + ); + + assert!( + parse!(parser, r#" + x = a === b === c; + "#).is_err(), + ); + + assert_eq!( + parse!(parser, r#" + x = (a < b) < c; + "#).unwrap(), + parse!(parser, r#" + op x (op $ a < b;) < c; + "#).unwrap(), + ); } #[test]