【问题标题】:PEG.JS parsing logical variable names, its operand and valuePEG.JS 解析逻辑变量名称、其操作数和值
【发布时间】:2014-12-01 23:14:53
【问题描述】:

在尝试了几个小时后头疼得厉害。 我正在使用 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"

这被解析为 - 检查/工作。

[
  {
      "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 上的连接符应该是“AND”。所以需要有某种展望(我猜)。 和这个一样:

("#CTL 1" = "VAL 1" or "#CTL 2" = "VAL 2") and ("#CTL 3" = "VAL 3" or "#CTL 4" = "VAL 4")

真正复杂的东西开始了,我们把不同的关卡混在一起:

("#CTL 1" = "VAL 1" or ("#CTL 2" = "VAL 2" and "#CTL 3" = "VAL 3")) or ("#CTL 4" = "VAL 4" or "#CTL 5" = "VAL 5")

这根本不起作用。 我能找到的所有例子都是左联想或右联想。 我认为两者都不是完全需要的。

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

【问题讨论】:

    标签: javascript boolean-logic peg


    【解决方案1】:

    我刚刚想通了。希望它可以帮助某人:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多