EdgeVerve / feel

Expression Language for creating and executing business rules in decision table based on DMN 1.1 specification for conformance level 3
MIT License
93 stars 48 forks source link

or list function results in parse error #22

Closed PaulChernoch-Shell closed 3 years ago

PaulChernoch-Shell commented 3 years ago

This is the rule:

'or(likes)'

This is the context passed in:

  context = {
    "likes": [false, false, true]
  };

This is the exception thrown:

peg$SyntaxError: Expected "(", "-", ".", "<", "<=", ">", ">=", "[", "]", "date and time", "date", "days and time duration", "duration", "every", "for", "function", "if", "not", "some", "time zone", "time", "years and months duration", "{", [0-9], end of input, string, or whitespace but "o" found.
    at peg$buildStructuredError (c:\Users\pchernoch\projects\feel-test\node_modules\js-feel\dist\feel.js:690:12)
    at Object.peg$parse [as parse] (c:\Users\pchernoch\projects\feel-test\node_modules\js-feel\dist\feel.js:8089:11)
    at test_rule (c:\Users\pchernoch\projects\feel-test\test-feel-expression.js:10:24)
    at main (c:\Users\pchernoch\projects\feel-test\test-feel-expression.js:98:9) {
  expected: [
    { type: 'other', description: 'whitespace' },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: 'function', ignoreCase: false },
    { type: 'literal', text: '{', ignoreCase: false },
    { type: 'literal', text: 'for', ignoreCase: false },
    { type: 'literal', text: 'if', ignoreCase: false },
    { type: 'literal', text: 'some', ignoreCase: false },
    { type: 'literal', text: 'every', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    { type: 'literal', text: 'time zone', ignoreCase: false },
    { type: 'literal', text: '-', ignoreCase: false },
    {
      type: 'class',
      parts: [Array],
      inverted: false,
      ignoreCase: false
    },
    { type: 'literal', text: '.', ignoreCase: false },
    { type: 'other', description: 'string' },
    { type: 'literal', text: 'date and time', ignoreCase: false },
    { type: 'literal', text: 'time', ignoreCase: false },
    { type: 'literal', text: 'date', ignoreCase: false },
    { type: 'literal', text: 'duration', ignoreCase: false },
    {
      type: 'literal',
      text: 'years and months duration',
      ignoreCase: false
    },
    {
      type: 'literal',
      text: 'days and time duration',
      ignoreCase: false
    },
    { type: 'literal', text: '<=', ignoreCase: false },
    { type: 'literal', text: '>=', ignoreCase: false },
    { type: 'literal', text: '<', ignoreCase: false },
    { type: 'literal', text: '>', ignoreCase: false },
    { type: 'literal', text: '(', ignoreCase: false },
    { type: 'literal', text: ']', ignoreCase: false },
    { type: 'literal', text: '[', ignoreCase: false },
    { type: 'literal', text: '-', ignoreCase: false },
    { type: 'literal', text: 'not', ignoreCase: false },
    { type: 'literal', text: '-', ignoreCase: false },
    { type: 'end' }
  ],
  found: 'o',
  location: {
    start: { offset: 0, line: 1, column: 1 },
    end: { offset: 1, line: 1, column: 2 }
  }
}

Interestingly, if I create this context with the function named OR (all uppercase) using the same function definition as in the index.js source code for list functions, it works:

  rule = 'OR(likes)';
  context = {
    "OR": (list) => {
      if (!Array.isArray(list)) {
        throw new Error('operation unsupported on element of this type');
      } else {
        return list.reduce((recur, next) => recur || next, false);
      }
    }, 
    "likes": [false, false, true]
  };
deostroll commented 3 years ago

or is part of a disjunction. (Refer rule 49, section 10.3.1.2, pg 109 of DMN v1.1). You've invoked it as a function call, which is why you got the error.

PaulChernoch-Shell commented 3 years ago

Sorry - I was going off an older version of the DMN spec. They changed the function name from "or" to "any" by 1.2, and probably by the final version of 1.1.

PaulChernoch-Shell commented 3 years ago

Name of function was changed from or to any.