Skip to content

Commit

Permalink
修改表达式等号优先级
Browse files Browse the repository at this point in the history
  • Loading branch information
X37ddV committed Jul 5, 2017
1 parent f8a4ad1 commit 319883a
Show file tree
Hide file tree
Showing 12 changed files with 1,017 additions and 937 deletions.
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

## Usage
```javascript
var exprManager = new ExprManager();
var data = {
Table: [{
Field0: 0,
Expand Down Expand Up @@ -53,16 +52,33 @@ var dataContext = {
var context = {
Field0: "!"
};
var exprManager = new ExprManager();
exprManager.init(data, dataContext, context);
var tableName = "Table";
var dataCursor = {
"Table": 0,
"Table.SubTable": 0
};
exprManager.init(data, dataContext, context);
var v = exprManager.calcExpr("Field1 + ' ' + SubTable[0].Field1 + $C.Field0", "Table", dataCursor);
var expr = "Field1 + ' ' + SubTable[0].Field1 + $C.Field0";
var v = exprManager.calcExpr(expr, tableName, dataCursor);
console.log(v.toValue());
// => Hello Wrold!
```

## Operator Precedence
| Operator | Description |
| ----------- | ------------------------------------------------------------------ |
| . [] () {} | Member access, array, grouping, object |
| + - ! | Unary operators, logical NOT |
| * / % | Multiplication, division, modulo division |
| + - | Addition, subtraction |
| < <= > >= | Less than, less than or equal, greater than, greater than or equal |
| == != | Equality, inequality |
| && | Logical AND |
| \|\| | Logical OR |
| : | Colon operator |
| , | Multiple evaluation |

## Example
npm install
npm start
Expand Down
906 changes: 468 additions & 438 deletions docs/expr-manager.html

Large diffs are not rendered by default.

79 changes: 47 additions & 32 deletions expr-manager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// expr-manager.js 0.1.1
// expr-manager.js 0.1.2
// https://github.com/X37ddV/expr-manager
// (c) 2016-2017 X37ddV
// Released under the MIT License.
Expand Down Expand Up @@ -1453,7 +1453,7 @@ var Lexer = (function () {
tValue = s[n++];
if (n < s.length && s[n] === "=") {
tValue += s[n++];
tType = "TK_CO";
tType = "TK_EO";
}
else {
tType = "TK_NOT";
Expand All @@ -1470,6 +1470,16 @@ var Lexer = (function () {
tType = "TK_CO";
break;
case "=":
tValue = s[n++];
if (n < s.length && s[n] === "=") {
tValue += s[n++];
tType = "TK_EO";
}
else {
tType = "TK_UNKNOWN";
}
tText = tValue;
break;
case "&":
case "|":
tValue = s[n++];
Expand Down Expand Up @@ -1692,46 +1702,47 @@ var Lexer = (function () {
// 节点类型
var tokens = ("TK_UNKNOWN,TK_STRING,TK_NUMBER,TK_BOOL,TK_NULL,TK_IDEN,TK_DOT,TK_LP,TK_LA," +
"TK_LO,TK_RP,TK_RA,TK_RO,TK_UNARY,TK_NOT,TK_MULTI,TK_DIV,TK_MOD,TK_PLUS,TK_MINUS," +
"TK_CO,TK_AND,TK_OR,TK_COLON,TK_COMMA").split(",");
"TK_CO,TK_EO,TK_AND,TK_OR,TK_COLON,TK_COMMA").split(",");
var genTokenState = function (tks, opts) {
var r = {};
tks.forEach(function (v, i) { return r[v] = opts[i] === "1"; });
return r;
};
// 起始节点规则
var RULE_BTOKENS = genTokenState(tokens, "0111110111000110000000000".split(""));
var RULE_BTOKENS = genTokenState(tokens, "01111101110001100000000000".split(""));
// 结束节点规则
var RULE_ETOKENS = genTokenState(tokens, "0111110000111000000000000".split(""));
var RULE_ETOKENS = genTokenState(tokens, "01111100001110000000000000".split(""));
// 后序节点规则
var RULE_LEXICAL = (function (tks, opts) {
var r = {};
tks.forEach(function (v, i) { return r[v] = genTokenState(tks, opts[i].split("")); });
return r;
})(tokens, ("0000000000000000000000000," +
"0000001010111001111111111," +
"0000001000111001111111111," +
"0000001000111001111111111," +
"0000000000111001111111111," +
"0000001110111001111111111," +
"0000010000000000000000000," +
"0111110111100110000000000," +
"0111110111010110000000000," +
"0111110000001000000000000," +
"0000001010111001111111101," +
"0000001010111001111111101," +
"0000001011111001111111101," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000," +
"0111110111000110000000000"
})(tokens, ("00000000000000000000000000," +
"00000010101110011111111111," +
"00000010001110011111111111," +
"00000010001110011111111111," +
"00000000001110011111111111," +
"00000011101110011111111111," +
"00000100000000000000000000," +
"01111101111001100000000000," +
"01111101110101100000000000," +
"01111100000010000000000000," +
"00000010101110011111111101," +
"00000010101110011111111101," +
"00000010111110011111111101," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000," +
"01111101110001100000000000"
).split(","));

// 语法解析器
Expand Down Expand Up @@ -1890,8 +1901,10 @@ var Parser = (function () {
p = this.doParser_4(p, "TK_MULTI,TK_DIV,TK_MOD");
// - 处理 + - 四则运算
p = this.doParser_4(p, "TK_PLUS,TK_MINUS");
// - 处理 < <= > >= == != 比较运算符
p = this.doParser_4(p, "TK_CO,TK_EO");
// - 处理 < <= > >= 比较运算符
p = this.doParser_4(p, "TK_CO");
// - 处理 == != 等于运算符
p = this.doParser_4(p, "TK_EO");
// - 处理 && 与运算
p = this.doParser_4(p, "TK_AND");
// - 处理 || 或运算
Expand Down Expand Up @@ -3234,6 +3247,7 @@ var Calc = (function () {
tv = lv.subtract(rv);
break;
case "TK_CO":
case "TK_EO":
tv = lv.compare(rv, t.tokenValue);
break;
case "TK_AND":
Expand Down Expand Up @@ -3468,6 +3482,7 @@ var Check = (function () {
tt = lt.subtract(rt);
break;
case "TK_CO":
case "TK_EO":
tt = lt.compare(rt, t.tokenValue);
break;
case "TK_AND":
Expand Down
2 changes: 1 addition & 1 deletion expr-manager.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "expr-manager",
"version": "0.1.1",
"version": "0.1.2",
"description": "Parse, validate, calc, and manage expression",
"main": "expr-manager.js",
"types": "expr-manager.d.js",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/base/calc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ export default class Calc {
case "TK_MINUS": /// -减法结点
tv = lv.subtract(rv);
break;
case "TK_CO": /// 比较运算符结点,包括==,!=,>,>=,<,<=
case "TK_CO": /// 比较运算符结点,包括>,>=,<,<=
case "TK_EO": /// 等于运算符结点,包括==,!=,
tv = lv.compare(rv, t.tokenValue);
break;
case "TK_AND": /// &&结点
Expand Down
3 changes: 2 additions & 1 deletion src/lib/base/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ export default class Check {
case "TK_MINUS": /// -减法结点
tt = lt.subtract(rt);
break;
case "TK_CO": /// 比较运算符结点,包括==,!=,>,>=,<,<=
case "TK_CO": /// 比较运算符结点,包括>,>=,<,<=
case "TK_EO": /// 等于运算符结点,包括==,!=,
tt = lt.compare(rt, t.tokenValue);
break;
case "TK_AND": /// &&结点
Expand Down
11 changes: 10 additions & 1 deletion src/lib/base/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class Lexer {
tValue = s[n++];
if (n < s.length && s[n] === "=") {
tValue += s[n++];
tType = "TK_CO";
tType = "TK_EO";
} else {
tType = "TK_NOT";
}
Expand All @@ -91,6 +91,15 @@ export default class Lexer {
tType = "TK_CO";
break;
case "=": /// ==
tValue = s[n++];
if (n < s.length && s[n] === "=") {
tValue += s[n++];
tType = "TK_EO";
} else {
tType = "TK_UNKNOWN";
}
tText = tValue;
break;
case "&": /// &&
case "|": /// ||
tValue = s[n++];
Expand Down
6 changes: 4 additions & 2 deletions src/lib/base/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,10 @@ export default class Parser {
p = this.doParser_4(p, "TK_MULTI,TK_DIV,TK_MOD");
// - 处理 + - 四则运算
p = this.doParser_4(p, "TK_PLUS,TK_MINUS");
// - 处理 < <= > >= == != 比较运算符
p = this.doParser_4(p, "TK_CO,TK_EO");
// - 处理 < <= > >= 比较运算符
p = this.doParser_4(p, "TK_CO");
// - 处理 == != 等于运算符
p = this.doParser_4(p, "TK_EO");
// - 处理 && 与运算
p = this.doParser_4(p, "TK_AND");
// - 处理 || 或运算
Expand Down
57 changes: 29 additions & 28 deletions src/lib/base/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,46 @@
// 节点类型
const tokens = ("TK_UNKNOWN,TK_STRING,TK_NUMBER,TK_BOOL,TK_NULL,TK_IDEN,TK_DOT,TK_LP,TK_LA," +
"TK_LO,TK_RP,TK_RA,TK_RO,TK_UNARY,TK_NOT,TK_MULTI,TK_DIV,TK_MOD,TK_PLUS,TK_MINUS," +
"TK_CO,TK_AND,TK_OR,TK_COLON,TK_COMMA").split(",");
"TK_CO,TK_EO,TK_AND,TK_OR,TK_COLON,TK_COMMA").split(",");
const genTokenState = (tks: string[], opts: string[]): object => {
const r = {};
tks.forEach((v, i) => r[v] = opts[i] === "1");
return r;
};
// 起始节点规则 /// BTOKENS[zz]==true表示tokens[z]可以作为起始节点
export const RULE_BTOKENS = genTokenState(tokens, "0111110111000110000000000".split(""));
export const RULE_BTOKENS = genTokenState(tokens, "01111101110001100000000000".split(""));
// 结束节点规则 /// ETOKENS[zz]==true表示tokens[z]可以作为结束节点
export const RULE_ETOKENS = genTokenState(tokens, "0111110000111000000000000".split(""));
export const RULE_ETOKENS = genTokenState(tokens, "01111100001110000000000000".split(""));
// 后序节点规则 /// LEXICAL[xx][yy]==true表示tokens[x]后可以紧接着出现tokens[y]
export const RULE_LEXICAL = ((tks: string[], opts: string[]): object => {
const r = {};
tks.forEach((v, i) => r[v] = genTokenState(tks, opts[i].split("")));
return r;
})(tokens, (
"0000000000000000000000000," + /// TK_UNKNOWN
"0000001010111001111111111," + /// TK_STRING 'abc'
"0000001000111001111111111," + /// TK_NUMBER 123
"0000001000111001111111111," + /// TK_BOOL true
"0000000000111001111111111," + /// TK_NULL null
"0000001110111001111111111," + /// TK_IDEN abc
"0000010000000000000000000," + /// TK_DOT .
"0111110111100110000000000," + /// TK_LP (
"0111110111010110000000000," + /// TK_LA [
"0111110000001000000000000," + /// TK_LO {
"0000001010111001111111101," + /// TK_RP )
"0000001010111001111111101," + /// TK_RA ]
"0000001011111001111111101," + /// TK_RO }
"0111110111000110000000000," + /// TK_UNARY +/-单目运算
"0111110111000110000000000," + /// TK_NOT !
"0111110111000110000000000," + /// TK_MULTI *
"0111110111000110000000000," + /// TK_DIV /
"0111110111000110000000000," + /// TK_MOD %
"0111110111000110000000000," + /// TK_PLUS +四则运算
"0111110111000110000000000," + /// TK_MINUS -四则运算
"0111110111000110000000000," + /// TK_CO ==,>,<,>=,<=,!=
"0111110111000110000000000," + /// TK_AND &&
"0111110111000110000000000," + /// TK_OR ||
"0111110111000110000000000," + /// TK_COLON :
"0111110111000110000000000" /// TK_COMMA ,
"00000000000000000000000000," + /// TK_UNKNOWN
"00000010101110011111111111," + /// TK_STRING 'abc'
"00000010001110011111111111," + /// TK_NUMBER 123
"00000010001110011111111111," + /// TK_BOOL true
"00000000001110011111111111," + /// TK_NULL null
"00000011101110011111111111," + /// TK_IDEN abc
"00000100000000000000000000," + /// TK_DOT .
"01111101111001100000000000," + /// TK_LP (
"01111101110101100000000000," + /// TK_LA [
"01111100000010000000000000," + /// TK_LO {
"00000010101110011111111101," + /// TK_RP )
"00000010101110011111111101," + /// TK_RA ]
"00000010111110011111111101," + /// TK_RO }
"01111101110001100000000000," + /// TK_UNARY +/-单目运算
"01111101110001100000000000," + /// TK_NOT !
"01111101110001100000000000," + /// TK_MULTI *
"01111101110001100000000000," + /// TK_DIV /
"01111101110001100000000000," + /// TK_MOD %
"01111101110001100000000000," + /// TK_PLUS +四则运算
"01111101110001100000000000," + /// TK_MINUS -四则运算
"01111101110001100000000000," + /// TK_CO >,<,>=,<=
"01111101110001100000000000," + /// TK_EO ==,!=
"01111101110001100000000000," + /// TK_AND &&
"01111101110001100000000000," + /// TK_OR ||
"01111101110001100000000000," + /// TK_COLON :
"01111101110001100000000000" /// TK_COMMA ,
).split(","));
4 changes: 4 additions & 0 deletions test/data/test_expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,10 @@ var exprNull = {
['IfNull("12",PN1)', '"12"'],
['IIf(true,"12", PN1)', '"12"'],
['IIf(false,"12", PN1)', 'null'],
['3>2 == 3<2', 'false'],
['3>2 == 2<3', 'true'],
['3>=2 != 3<=2', 'true'],
['3>=2 != 2<=3', 'false']
]
};
var exprErr = {
Expand Down
Loading

0 comments on commit 319883a

Please sign in to comment.