下面的工作对我所做的工作很好,但很明显,它是非常重复的。它应与以下示例相匹配:
它很容易被使用
id:idShortcut? classes:classShortcut* attrs:fullAttribute* 但我不希望它匹配,如果所有的三个组成部分是不存在。如何指定由3个可选组件组成的规则,但至少必须有一个组件存在?
attributes = id:idShortcut classes:classShortcut* attrs:fullAttribute*
{
var ret = [['id', id]];
for(var i = 0; i < classes.length; ++i ) {
ret.push(['class', classes[i]]);
}
for(var i = 0; i < attrs.length; ++i ) {
ret.push(attrs[i]);
}
return ret;
}
/ classes:classShortcut+ attrs:fullAttribute* {
// TODO: how to dry this with the above?
var ret = [];
for(var i = 0; i < classes.length; ++i ) {
ret.push(['class', classes[i]]);
}
for(var i = 0; i < attrs.length; ++i ) {
ret.push(attrs[i]);
}
return ret;
}
/ attrs:fullAttribute+ {
var ret = [];
for(var i = 0; i < attrs.length; ++i ) {
ret.push(attrs[i]);
}
return ret;
}发布于 2013-01-23 03:42:11
好的,不知道为什么这对我来说是一场斗争,但是这个重构很好地如下所示(并且可能会得到改进:
attributes
= a:( attributesAtLeastID
/ attributesAtLeastClass
/ attributesAtFullAttr )
{
var id = a[0];
var classes = a[1];
var attrs = a[2];
var ret = [];
if(id) { ret.push(['id', id]); }
for(var i = 0; i < classes.length; ++i ) {
ret.push(['class', classes[i]]);
}
for(var i = 0; i < attrs.length; ++i ) {
ret.push(attrs[i]);
}
}
attributesAtLeastID = id:idShortcut classes:classShortcut* attrs:fullAttribute* { return [id, classes, attrs]; }
attributesAtLeastClass = classes:classShortcut+ attrs:fullAttribute* { return [null, classes, attrs]; }
attributesAtFullAttr = attrs:fullAttribute+ { return [null, [], attrs]; }发布于 2013-12-31 01:31:58
这就是什么和谓词是有用的。
只有当id没有定义,类不是空数组,或者attrs不是空数组时,属性才匹配。
attributes =
id:idShortcut? classes:classShortcut* attrs:fullAttribute* &{return id !== undefined || classes.length > 0 || attrs.length > 0;}
{
var ret = [];
if (id) {
ret.push(['id', id]);
}
for (var x=0; x < classes.length;x++) {
ret.push(['class', classes[x]);
}
for (var y=0; y < attrs.length;y++) {
ret.push([attrs[y]);
}
return ret;
}https://stackoverflow.com/questions/14471921
复制相似问题