0

我编写了以下解析器(粘贴到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 规则,但它只是抛出异常而不是继续。

恭喜幸存到这里的人,我做错了什么?:) 谢谢

4

1 回答 1

0

更多地使用语法,解决方案是使用 !Pair 和(出于某种原因)更改“表达式”规则的顺序:

Expression = FullTextWithPairs / Pairs 

Pairs = (';'? _ p:Pair { return p; })*

FullTextWithPairs = fto:FullText po:Pairs
{ 
	var arr = [];
    if (fto) {
    	arr.push(fto);
     }
     return arr.concat(po);
}
 
FullText = !Pair 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'

_ = ' '*

于 2016-11-01T09:36:56.193 回答