How to match the start and end of a block

随声附和 提交于 2019-12-11 08:22:35

问题


I want to define a special code block, which may starts by any combination of characters of {[<#, and the end will be }]>#.

Some example:

{
    block-content
}

{##
    block-content
##}

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

Is it possible with petitparser-dart?


回答1:


Yes, back-references are possible, but it is not that straight-forward.

First we need a function that can reverse our delimiter. I came up with the following:

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

Then we have to declare the stopDelimiter parser. It is undefined at this point, but will be replaced with the real parser as soon as we know it.

var stopDelimiter = undefined();

In the action of the startDelimiter we replace the stopDelimiter with a dynamically created parser as follows:

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

The rest is trivial, but depends on your exact requirements:

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

The code above defines the blockContents parser so that it reads through anything until the matching stopDelimiter is encountered. The provided examples pass:

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 , ###}>]]#]

The above code doesn't work if you want to nest the parser. If necessary, that problem can be avoided by remembering the previous stopDelimiter and restoring it.



来源:https://stackoverflow.com/questions/21784392/how-to-match-the-start-and-end-of-a-block

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!