Skip to content

Commit 6419ae9

Browse files
committed
Added precedence for operators supported in parser.
1 parent e2abf21 commit 6419ae9

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

src/helpers/dependentQuestionsHelper.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,50 @@ class Stack {
4040
return false
4141
}
4242
}
43+
/*eslint quote-props: ["error", "always"]*/
44+
const precedence = {
45+
'(' : 8,
46+
')' : 8,
47+
48+
'!' : 7,
49+
50+
'^' : 6,
51+
52+
'*' : 5,
53+
'/' : 5,
54+
55+
'+' : 4,
56+
'-' : 4,
57+
58+
'contains' : 3,
59+
'hasLength' : 3,
60+
'>' : 3,
61+
'<' : 3,
62+
63+
'==' : 2,
64+
'!=' : 2,
65+
66+
'&&' : 1,
67+
'||' : 1,
68+
}
4369

4470
/**
4571
* ex - 4 * 5 - 2
46-
* @param op2 peeked from ops
47-
* @param op1 found in the expression
72+
* @param opStackTop peeked from ops
73+
* @param currentOp found in the expression
4874
*
4975
* TODO implementation could be more precise and can be based on JS operator precedence values
5076
* see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
5177
*
52-
* @returns true if 'op2' has higher or same precedence as 'op1', otherwise returns false
78+
* @returns true if 'opStackTop' has higher or same precedence as 'currentOp', otherwise returns false
5379
*/
54-
function hasPrecedence(op1, op2) {
55-
if (op2 === '(' || op2 === ')')
56-
return false
57-
if ((op1 === '*' || op1 === '/' || op1 === '!') && (op2 === '+' || op2 === '-' || op2 === '==' || op2 === '>' || op2 === '<' || op2 === 'contains' || op2 === 'hasLength'))
80+
function hasPrecedence(currentOp, opStackTop) {
81+
if (opStackTop === '(' || opStackTop === ')')
5882
return false
59-
else
83+
if (precedence[opStackTop] >= precedence[currentOp])
6084
return true
85+
else
86+
return false
6187
}
6288
/**
6389
* A utility method to apply an operation 'op' on operands

src/helpers/dependentQuestionsHelper.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ describe('Evaluate', () => {
9898
})
9999

100100
describe('logical operators', () => {
101+
102+
it('test plain conditions', () => {
103+
const expression = '(someArrayWithText contains \'a\' || someArrayWithText contains \'d\')'
104+
const result = evaluate(expression, testData)
105+
106+
result.should.equal(true)
107+
})
101108

102109
it('contains \'a\' && hasLength (true)', () => {
103110
const expression = '(someArrayWithText contains \'a\') && (someArrayWithText hasLength 3)'

0 commit comments

Comments
 (0)