javascript - PEG.JS parsing logical variable names, its operand and value -
getting terrible headache after hours of trying work. using peg.js parsing input query parsed array. right im trying best grammer. operands , connectors static , generated 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 have following input:
"#ctl 1" = "val 1" or "#ctl 2" = "val 2"
this parsed - check / works.
[ { "control": "ctl 1", "operand": "=", "value": "val 1", "connector": "or" }, { "control": "ctl 2", "operand": "=", "value": "val 2", "connector": false }
]
this 1 should result in same output array - check / works.
("#ctl 1" = "val 1" or "#ctl 2" = "val 2")
this 1 half way:
("#ctl 1" = "val 1" or "#ctl 2" = "val 2") , "#ctl 3" = "val 3"
the output 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 "and". there needs kind of ahead (i guess). same one:
("#ctl 1" = "val 1" or "#ctl 2" = "val 2") , ("#ctl 3" = "val 3" or "#ctl 4" = "val 4")
the complicated stuff starts, wenn mixing different level each other:
("#ctl 1" = "val 1" or ("#ctl 2" = "val 2" , "#ctl 3" = "val 3")) or ("#ctl 4" = "val 4" or "#ctl 5" = "val 5")
this not work @ all. examples able find either left or right associative. think neither riquired.
do have clue on how solve issue?
i figured out. hope helps someone:
{ function findfirstleftstatement(arr) { if ( array.isarray(arr) ) { return findfirstleftstatement(arr[0]["left"]); } else if ( typeof arr === "object" ) { return arr; } } function inject(arr, connector) { findfirstleftstatement(arr)["connector"] = connector; return arr; } } start = statement* statement = left:block connector:connector right:statement { return { left: left, right: inject(right, connector) }; } / left: block { return left; } block = popen block:statement* pclose { return block; } / block:assignment { return block; } assignment = control:controlatom operand:operand value:valueatom { return { control: control, operand: operand, value: value }; } controlatom = _ quote "#"atom:(word)* quote _ { return atom.tostring(); } valueatom = _ quote atom:(word)* quote _ { return atom.tostring(); } operand = _ operand:("=" / "in") _ { return operand.tostring(); } connector = _ connector:("or" / "and") _ { return connector.tostring(); } word = w:character+ { return w.join(""); } character = c:[^\r\n\t\"] popen = _ '(' _ pclose = _ ')' _ quote = _ quote:("\"" / """ / "\xa0") _ _ = [ \r\n\t]*
Comments
Post a Comment