我想定义一个特殊的代码块,它可以以{[<#
字符的任意组合开头,结尾为}]>#
。
一些例子:
{
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/