getting a terrible headache after hours of trying to get this to work. I am using PEG.js parsing to get an input query parsed into an array. Right now im trying my best with this grammer. Operands and connectors are static and generated by the app.
start = start:(statement)
statement = statement:block_statement* { return statement; }
block_statement = OPENPAREN block:block+ CLOSEPAREN connector:CONNECTOR block2:(block_statement+ / block+) { return [block, block2]; }
/ OPENPAREN block:block+ CLOSEPAREN connector:CONNECTOR* !(block_statement / block) { return block; }
/ block:block
block = control:atom operand:OPERAND atom:atom connector:CONNECTOR* { return { control: control, operand: operand, value: atom, connector: connector[0] || false }; }
atom = _ QUOTE "#"*atom:(word)* QUOTE _ { return atom.toString(); }
OPERAND = _ operand:("=" / "in") _ { return operand.toString(); }
CONNECTOR = _ connector:("or" / "and") _ { return connector.toString(); }
word = w:char+ { return w.join(""); }
char = c:[^\r\n\t\"]
OPENPAREN = _ '(' _
CLOSEPAREN = _ ')' _
QUOTE = _ quote:("\"" / """ / "\xA0") _
_ = [ \r\n\t]*
Let's assume I have the following input:
"#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2"
This is parsed to - check / works.
[
{
"control": "CTL 1",
"operand": "=",
"value": "VAL 1",
"connector": "or"
},
{
"control": "CTL 2",
"operand": "=",
"value": "VAL 2",
"connector": false
}
]
This one should result in the same output array - check / works.
("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2")
This one does it half way:
("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2") and "#CTL 3" = "VAL 3"
The output is like:
[
[
[
{
"control": "CTL 1",
"operand": "=",
"value": "VAL 1",
"connector": "or"
},
{
"control": "CTL 2",
"operand": "=",
"value": "VAL 2",
"connector": false
}
],
[
{
"control": "CTL 3",
"operand": "=",
"value": "VAL 3",
"connector": false
}
]
]
]
The connector on CTL 2 should be "AND". So there needs to be some kind of look ahead (i guess). Same with this one:
("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2") and ("#CTL 3" = "VAL 3" or "#CTL 4" = "VAL 4")
The really complicated stuff starts, wenn mixing different level into each other:
("#CTL 1" = "VAL 1" or ("#CTL 2" = "VAL 2" and "#CTL 3" = "VAL 3")) or ("#CTL 4" = "VAL 4" or "#CTL 5" = "VAL 5")
This does not work at all. All examples I was able to find are either left or right associative. I think neither is fully riquired.
Do you have a clue on how to solve this issue?
I just figured it out. Hope it helps someone: