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

一些例子:

{
    block-content
}

{##
    block-content
##}

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

petitparser-dart是否可以?

最佳答案

是的,可以使用向后引用,但不是那么简单。

首先,我们需要一个可以反转定界符的函数。我想出了以下几点:

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并将其还原来避免该问题。

关于dart - 如何匹配块的开始和结束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21784392/

10-10 22:14