首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何干燥这个PEGjs规则?

我如何干燥这个PEGjs规则?
EN

Stack Overflow用户
提问于 2013-01-23 03:21:09
回答 2查看 341关注 0票数 1

下面的工作对我所做的工作很好,但很明显,它是非常重复的。它应与以下示例相匹配:

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

它很容易被使用

代码语言:javascript
复制
id:idShortcut? classes:classShortcut* attrs:fullAttribute* 

但我不希望它匹配,如果所有的三个组成部分是不存在。如何指定由3个可选组件组成的规则,但至少必须有一个组件存在?

代码语言:javascript
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-23 03:42:11

好的,不知道为什么这对我来说是一场斗争,但是这个重构很好地如下所示(并且可能会得到改进:

代码语言:javascript
复制
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]; }
票数 0
EN

Stack Overflow用户

发布于 2013-12-31 01:31:58

这就是什么和谓词是有用的。

只有当id没有定义,类不是空数组,或者attrs不是空数组时,属性才匹配。

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14471921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档