Skip to content

Commit

Permalink
将相等比较单独提出一个优先级, 并且去除比较运算的左结合
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Jan 23, 2024
1 parent bc490fb commit 9b900d5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 40 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.14.14"
version = "0.14.15"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
25 changes: 14 additions & 11 deletions examples/op_expr.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
* 它们的优先级与括号平级,
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
49 changes: 26 additions & 23 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -457,50 +457,53 @@ OpExprDoMultiple: (Vec<Value>, Vec<OpExprInfo>) = {
},
}

OpExprBody: OpExprInfo = OpExprBody12;
OpExprBody: OpExprInfo = OpExprBody13;

OpExprBody12: OpExprInfo = {
"if" <cmp:JumpCmp> "?" <a:OpExprBody12> ":" <b:OpExprBody12> => {
OpExprBody13: OpExprInfo = {
"if" <cmp:JumpCmp> "?" <a:OpExprBody13> ":" <b:OpExprBody13> => {
OpExprInfo::new_if_else(meta, cmp, a, b)
},
OpExprBody11,
OpExprBody12,
}

OpExprBody11: OpExprInfo = {
<a:OpExprBody11> "||" <b:OpExprBody10> => op_expr_build_op(
OpExprBody12: OpExprInfo = {
<a:OpExprBody12> "||" <b:OpExprBody11> => op_expr_build_op(
|| Op::Add(ResultHandle, a.into_value(meta), b.into_value(meta))),
OpExprBody10,
OpExprBody11,
}

OpExprBody10: OpExprInfo = {
<a:OpExprBody10> "&&" <b:OpExprBody9> => op_expr_build_op(
OpExprBody11: OpExprInfo = {
<a:OpExprBody11> "&&" <b:OpExprBody10> => op_expr_build_op(
|| Op::Land(ResultHandle, a.into_value(meta), b.into_value(meta))),
OpExprBody9,
OpExprBody10,
}

OpExprBody9: OpExprInfo = {
<a:OpExprBody9> "==" <b:OpExprBody8> => op_expr_build_op(
OpExprBody10: OpExprInfo = {
<a:OpExprBody9> "==" <b:OpExprBody9> => op_expr_build_op(
|| Op::Equal(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> "!=" <b:OpExprBody8> => op_expr_build_op(
<a:OpExprBody9> "!=" <b:OpExprBody9> => op_expr_build_op(
|| Op::NotEqual(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> "<" <b:OpExprBody8> => op_expr_build_op(
|| Op::LessThan(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> ">" <b:OpExprBody8> => op_expr_build_op(
|| Op::GreaterThan(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> "<=" <b:OpExprBody8> => op_expr_build_op(
|| Op::LessThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> ">=" <b:OpExprBody8> => op_expr_build_op(
|| Op::GreaterThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> "===" <b:OpExprBody8> => op_expr_build_op(
<a:OpExprBody9> "===" <b:OpExprBody9> => op_expr_build_op(
|| Op::StrictEqual(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody9> "!==" <b:OpExprBody8> =>
<a:OpExprBody9> "!==" <b:OpExprBody9> =>
op_expr_build_op(|| Op::Equal(
ResultHandle,
DExp::new_nores(vec![
Op::StrictEqual(ResultHandle, a.into_value(meta), b.into_value(meta)).into()
].into()).into(),
ReprVar(FALSE_VAR.into())
)),
OpExprBody9,
}
OpExprBody9: OpExprInfo = {
<a:OpExprBody8> "<" <b:OpExprBody8> => op_expr_build_op(
|| Op::LessThan(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody8> ">" <b:OpExprBody8> => op_expr_build_op(
|| Op::GreaterThan(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody8> "<=" <b:OpExprBody8> => op_expr_build_op(
|| Op::LessThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))),
<a:OpExprBody8> ">=" <b:OpExprBody8> => op_expr_build_op(
|| Op::GreaterThanEq(ResultHandle, a.into_value(meta), b.into_value(meta))),
OpExprBody8,
}

Expand Down
2 changes: 1 addition & 1 deletion tools/parser/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
41 changes: 41 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 9b900d5

Please sign in to comment.