Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS解析逻辑变量名称、操作数和值_Javascript_Boolean Logic_Peg - Fatal编程技术网

Javascript JS解析逻辑变量名称、操作数和值

Javascript JS解析逻辑变量名称、操作数和值,javascript,boolean-logic,peg,Javascript,Boolean Logic,Peg,经过几个小时的努力,我头痛得厉害。 我使用PEG.js解析将输入查询解析为数组。 现在我正在尽我最大的努力写这本语法书。操作数和连接器是静态的,由应用程序生成 start = start:(statement) statement = statement:block_statement* { return statement; } block_statement = OPENPAREN block:block+ CLOSEPAREN connector:CONNECTOR block2:(b

经过几个小时的努力,我头痛得厉害。 我使用PEG.js解析将输入查询解析为数组。 现在我正在尽我最大的努力写这本语法书。操作数和连接器是静态的,由应用程序生成

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]*
假设我有以下输入:

"#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2"
这被解析为-check/works

[
  {
      "control": "CTL 1",
      "operand": "=",
      "value": "VAL 1",
      "connector": "or"
  },
  {
      "control": "CTL 2",
      "operand": "=",
      "value": "VAL 2",
      "connector": false
  }
("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2")
]

这一个应该产生相同的输出数组-check/works

[
  {
      "control": "CTL 1",
      "operand": "=",
      "value": "VAL 1",
      "connector": "or"
  },
  {
      "control": "CTL 2",
      "operand": "=",
      "value": "VAL 2",
      "connector": false
  }
("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2")
这一个做了一半:

("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2") and "#CTL 3" = "VAL 3"
输出如下所示:

[
   [
      [
         {
            "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
         }
      ]
   ]
]
CTL 2上的接头应为“和”。因此,我想,需要有某种前瞻性。 与此相同:

("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2") and ("#CTL 3" = "VAL 3" or "#CTL 4" = "VAL 4")
真正复杂的事情开始了,wenn将不同的层次混合在一起:

("#CTL 1" = "VAL 1" or ("#CTL 2" = "VAL 2" and "#CTL 3" = "VAL 3")) or ("#CTL 4" = "VAL 4" or "#CTL 5" = "VAL 5")
这根本不起作用。 我能找到的所有例子要么是左联想,要么是右联想。 我认为两者都不是完全必要的


你知道如何解决这个问题吗?

我刚想出来。希望它能帮助某人:

{
  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]*