[英]Ambiguous grammar when parsing boolean expressions with Peg.js
I'm writing a parser that generates an abstract syntax tree from boolean expressions. 我正在编写一个从布尔表达式生成抽象语法树的解析器。
I have the following Peg.js grammar that supports ^
and ∨
, as &
and |
我有以下支持
^
和∨
Peg.js语法,分别为&
和|
respectively: 分别:
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 };
}
It successfully parses expressions like a & b
and a & (b | c)
, however it fails if the expression starts with an operation: 它可以成功解析
a & b
和a & (b | c)
之类的表达式,但是如果该表达式以一个运算符开头,则会失败:
(a | b) & c
Line 1, column 8: Expected end of input but " " found.
The expression gets parsed correctly if I surround it with parenthesis: 如果使用括号将表达式正确解析,则可以:
((a | b) & c)
My guess is that Peg.js is only taking (a | b)
as an operation, instead of an operand of the parent operation, thus failing when seeing the & c
. 我的猜测是Peg.js仅将
(a | b)
作为操作,而不是父操作的操作数,因此在看到& c
时失败。
What am I missing? 我想念什么?
Your operation rule says the brackets are optional but having one does not enforce the other to be there. 您的操作规则说,方括号是可选的,但没有一个方括号会强制使用另一个方括号。 Eg,
(a & b
is parsed successfully. 例如,
(a & b
已成功解析。
You need to break it up into smaller parts. 您需要将其分解成较小的部分。 The separate rules for
and
and or
are to allow operator precedence to do its trick. and
和or
的单独规则允许运算符优先级发挥作用。
Try this: 尝试这个:
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]+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.