1

以下は、私がやろうとしていることに対してうまく機能しますが、明らかに非常に反復的です。次の例と一致する必要があります。

  • #id.class1.class2 attr="asdsa"
  • .class1.class2 attr="asdsad"
  • attr="asds"

使いたくなる

id:idShortcut? classes:classShortcut* attrs:fullAttribute* 

しかし、3 つのコンポーネントがすべて欠落している場合は一致させたくありません。3 つのオプション コンポーネントのルールを指定するにはどうすればよいですか?ただし、少なくとも 1 つが存在する必要があります。

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;
}
4

2 に答える 2

0

OK、なぜこれが私にとって苦労したのかはわかりませんが、これは次のようにうまくリファクタリングされました (おそらくそれ以上に改善される可能性があります:

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-01-23T03:42:11.160 に答える