EricSmekens / jsep

JavaScript Expression Parser
http://ericsmekens.github.io/jsep/
MIT License
835 stars 136 forks source link

Parse multiple binary operators on the root level #244

Closed bertyhell closed 1 year ago

bertyhell commented 1 year ago

When i parse multiple binary operators on the root level i get an unexpected AST:

jsep.addBinaryOp("AND");
jsep.addBinaryOp("OR");

let parseTree = jsep("a AND b AND c AND d OR e");

result:

{
  "type": "Compound",
  "body": [
    {
      "type": "BinaryExpression",
      "operator": "AND",
      "left": {
        "type": "Identifier",
        "name": "a"
      },
      "right": {
        "type": "Identifier",
        "name": "b"
      }
    },
    {
      "type": "Identifier",
      "name": "AND"
    },
    {
      "type": "BinaryExpression",
      "operator": "AND",
      "left": {
        "type": "Identifier",
        "name": "c"
      },
      "right": {
        "type": "Identifier",
        "name": "d"
      }
    },
    {
      "type": "Identifier",
      "name": "OR"
    },
    {
      "type": "Identifier",
      "name": "e"
    }
  ]
}

expected result:

{
  "type": "BinaryExpression",
  "operator": "OR",
  "left": {
    "type": "BinaryExpression",
    "operator": "AND",
    "left": {
      "type": "BinaryExpression",
      "operator": "AND",
      "left": {
        "type": "BinaryExpression",
        "operator": "AND",
        "left": {
          "type": "Identifier",
          "name": "a"
        },
        "right": {
          "type": "Identifier",
          "name": "b"
        }
      },
      "right": {
        "type": "Identifier",
        "name": "c"
      }
    },
    "right": {
      "type": "Identifier",
      "name": "d"
    }
  },
  "right": {
    "type": "Identifier",
    "name": "e"
  }
}

I can get the desired result by adding brackets, but is it possible without the user having to add all the brackets?

let parseTree = jsep("(((a AND b) AND c) AND d) OR e");

The strange thing is that this expression does provide the expected nested tree of binary operators:

let parseTree = jsep("a * b * c * d + e");
6utt3rfly commented 1 year ago

@bertyhell - you should be setting the operator precedence by passing a second argument to addBinaryOp, like addBinaryOp('OR', 1) and addBinaryOp('AND', 2) (see source code for default precedence) and the readme for usage instructions

bertyhell commented 1 year ago

that's it indeed, thank you