如何匹配块的开始和结束

时间:2014-02-14 16:22:43

标签: dart petitparser

我想定义一个特殊的代码块,它可以以{[<#的任意字符组合开头,结尾将是}]>#

一些例子:

{
    block-content
}

{##
    block-content
##}

#[[<{### 
    block-content 
###}>]]#

是否可以使用petitparser-dart

1 个答案:

答案 0 :(得分:2)

是的,可以进行反向引用,但不是那么直截了当。

首先,我们需要一个可以反转分隔符的函数。我想出了以下内容:

String reverseDelimiter(String token) {
  return token.split('').reversed.map((char) {
    if (char == '[') return ']';
    if (char == '{') return '}';
    if (char == '<') return '>';
    return char;
  }).join();
}

然后我们必须声明stopDelimiter解析器。它在这一点上是未定义的,但只要我们知道它就会被真正的解析器取代。

var stopDelimiter = undefined();

startDelimiter的操作中,我们用动态创建的解析器替换stopDelimiter,如下所示:

var startDelimiter = pattern('#<{[').plus().flatten().map((String start) {
  stopDelimiter.set(string(reverseDelimiter(start)).flatten());
  return start;
});

其余的都是微不足道的,但取决于您的确切要求:

var blockContents = any().starLazy(stopDelimiter).flatten();
var parser = startDelimiter & blockContents & stopDelimiter;

上面的代码定义了blockContents解析器,以便在遇到匹配的stopDelimiter之前读取任何内容。提供的示例通过:

print(parser.parse('{ block-content }')); 
  // Success[1:18]: [{,  block-content , }]

print(parser.parse('{## block-content ##}')); 
  // Success[1:22]: [{##,  block-content , ##}]

print(parser.parse('#[[<{### block-content ###}>]]#'));
  // Success[1:32]: [#[[<{###,  block-content , ###}>]]#]

如果要嵌套解析器,上面的代码不起作用。如有必要,可以通过记住之前的stopDelimiter并恢复它来避免这个问题。