Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.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 使用Peg.js解析布尔表达式时语法不明确_Javascript_Peg - Fatal编程技术网

Javascript 使用Peg.js解析布尔表达式时语法不明确

Javascript 使用Peg.js解析布尔表达式时语法不明确,javascript,peg,Javascript,Peg,我正在编写一个解析器,它从布尔表达式生成一个抽象语法树 我有以下支持^和^的Peg.js语法∨, 分别为&和|: start = operation // optional whitespace _ = [ \t\r\n]* operation "operation" = "("? _ left:(operand / operation) _ operator:operator _ right:(operand / operation) _ ")"? { return

我正在编写一个解析器,它从布尔表达式生成一个抽象语法树

我有以下支持^和^的Peg.js语法∨, 分别为&和|:

start
  = operation

// optional whitespace
_  = [ \t\r\n]*

operation "operation"
  = "("? _ left:(operand / operation) _ operator:operator _ right:(operand / operation) _  ")"?
  {
    return {
      operation: operator,
      between: [ left, right ]
    };
  }

operator "operator"
  = operator:["&"|"|"]  
  {
    return operator;
  }

operand "operand"
  = operand:[a-z]
  { 
    return { operand: operand };
  }
它成功解析a&b和a&b | c等表达式,但如果表达式以操作开始,则会失败:

(a | b) & c
Line 1, column 8: Expected end of input but " " found.
如果用括号将表达式括起来,则可以正确解析表达式:

((a | b) & c)
我猜想Peg.js只是将a | b作为一个操作,而不是父操作的操作数,因此在看到&c时失败


我遗漏了什么?

您的操作规则说括号是可选的,但有一个括号并不强制另一个括号在那里。例如,a&b解析成功

你需要把它分成更小的部分。and和or的单独规则是允许运算符优先级发挥作用

试试这个:

start
  = sentence

sentence
  = orSentence

orSentence
  = lhs:andSentence __ '|' __ rhs:orSentence { return { operation: '|', between: [lhs, rhs] }; }
  / andSentence

andSentence
  = lhs:primarySentence __ '&' __ rhs:andSentence { return { operation: '&', between: [lhs, rhs] }; }
  / primarySentence

primarySentence
  = '(' _ sentence:sentence _ ')' { return sentence; }
  / operand

operand
  = operand:[a-z] { return { operand: operand }; }

_ "optionalWhiteSpace"
  = whiteSpace *

__ "mandatoryWhiteSpace"
  = whiteSpace +

whiteSpace
  = [ \t\n\r]+

你的操作规则说括号是可选的,但有一个括号并不强制另一个括号在那里。例如,a&b解析成功

你需要把它分成更小的部分。and和or的单独规则是允许运算符优先级发挥作用

试试这个:

start
  = sentence

sentence
  = orSentence

orSentence
  = lhs:andSentence __ '|' __ rhs:orSentence { return { operation: '|', between: [lhs, rhs] }; }
  / andSentence

andSentence
  = lhs:primarySentence __ '&' __ rhs:andSentence { return { operation: '&', between: [lhs, rhs] }; }
  / primarySentence

primarySentence
  = '(' _ sentence:sentence _ ')' { return sentence; }
  / operand

operand
  = operand:[a-z] { return { operand: operand }; }

_ "optionalWhiteSpace"
  = whiteSpace *

__ "mandatoryWhiteSpace"
  = whiteSpace +

whiteSpace
  = [ \t\n\r]+