我编写了以下解析器(粘贴到http://pegjs.org/online并且它可以工作):
Expression = Pairs / FullTextWithPairs
Pairs = (';'? _ p:Pair { return p; })*
FullTextWithPairs = fto:FullText po:Pairs
{
var arr = [];
if (fto) {
arr.push(fto);
}
return arr.concat(po);
}
FullText = ft:ValueString ';'
{
return {'key' : 'fullText', 'op': '=', 'value': ft};
}
Pair = k:Field op:Operator v:ValueString
{
var res = {'key' : k, 'op': op, 'value': v};
console.log(res);
return res;
}
Operator = ('<>' / [=><])
ValueString = vs:[^;]+ {return vs.join('');}
Field = 'location' / 'application' / 'count'
_ = ' '*
它解析这个键值对字符串:location=USA; application<>app; count>5
到这个:
[
{
"key": "location",
"op": "=",
"value": "USA"
},
{
"key": "application",
"op": "<>",
"value": "app"
},
{
"key": "count",
"op": ">",
"value": "5"
}
]
问题是我也想启用自由文本搜索,它在键值对之前输入,例如: this:free text foobar; location=USA; application<>app; count>5
并得到这个:
[
{
"key": "fullText",
"op": "=",
"value": "free text foobar"
},
{
"key": "location",
"op": "=",
"value": "USA"
},
{
"key": "application",
"op": "<>",
"value": "app"
},
{
"key": "count",
"op": ">",
"value": "5"
}
]
解析器应该识别出第一部分不是键值对(根据“Pair”规则)并将其作为“fullText”对象插入。
根据我在文档中阅读的内容,基本上“表达式”规则应该这样做 - A / B 表示如果 A 没有通过,则尝试 B。在第二种情况下,“Paris”失败,因为“free text foobar”没有通过 Pairs 规则,但它只是抛出异常而不是继续。
恭喜幸存到这里的人,我做错了什么?:) 谢谢