次のパーサーを作成しました ( 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
と get this:
[
{
"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が試行されることを意味します。2 番目のケースでは、「Paris」は「free text foobar」が Pairs ルールに合格しないため失敗しますが、先に進む代わりに例外をスローするだけです。
ここまで生き残った人におめでとう、私は何を間違っていますか? :) ありがとうございました