解决方案
一种描述嵌套大括号的方法(仅此而已)
假设一个名为 &R 的规则,如果我正在编写一个快速的小型一次性脚本,我可能会编写以下模式:
\{ <&R>* \}
如果我正在编写一个应该可维护的大型程序,我可能会编写一个语法,并且使用名为 R 的规则,模式将是:
'{' ~ '}' <R>*
后者避免使用leaning toothpick syndrome 并使用the regex ~ operator。
这些都将解析任意深度嵌套的成对大括号,例如:
say '{{{{}}}}' ~~ token { \{ <&?ROUTINE>* \} } # 「{{{{}}}}」
(&?ROUTINE 指的是它出现的例程。正则表达式是例程。(虽然你不能在用/ ... / 语法声明的正则表达式中使用<&?ROUTINE>。)
regex 与 token
杀死回溯
my regex nested-braces {
:ratchet
用regex 和token 声明的模式之间的唯一区别是前者关闭了棘轮。因此,使用它然后立即打开棘轮 on 是非常不习惯的。而是:
my token nested-braces {
回溯
“正则表达式”机制(基于回溯)
语法/正则表达式引擎将回溯作为一项可选功能包含,因为这有时正是人们想要的。
但是引擎不是“基于回溯”,许多语法/解析器很少或根本不使用回溯。
递归
一个正则表达式可以调用另一个,我在任何地方都没有看到禁止递归调用。
仅此一点对于当代正则表达式引擎来说并没有什么特别之处。
PCRE 从 2000 年开始支持递归,从 2003 年开始支持正则表达式。Perl 的默认正则表达式引擎从 2007 年开始支持这两者。
他们对更深层次的递归和同时存储更多命名正则表达式的支持随着时间的推移而增加。
Damian Conway 的 PPR 使用正则表达式的这些特性来构建非平凡(但仍然很小)的解析树。
能力
能力更强
Raku“正则表达式”可以被视为对正在展开的正则表达式演变的一种清理。在某种程度上,这有助于人们理解它们,太好了。
但实际上,这是一个全新的交易。例如,它们以合理的方式图灵完备,因此能够解析任何内容。
比官方承认
嗯,说起来很奇怪! Raku 的语法经常被吹捧为 Raku 最具创新性的功能之一。
有三个主要的警告:
-
性能当前的主要警告是,编写良好的 C 解析器将击败编写良好的基于 Raku 语法的解析器。
-
回报如果有一个现有的解析器,为非平凡的格式编写一个完全正确的解析器通常是不值得的。
-
左递归 Raku 不会自动重写left recursion(无限循环)。
使用现有的解析器
我知道周围有 BibTeX 解析器,但我需要获取完整的条目以进行进一步处理,同时查看几个键。
在 Raku 中使用外来模块可能会带来一些启示。它不一定像你以前经历过的任何事情。 Raku 的外语适配器可以为您提供智能 marshaling,因此您可以像使用本地 Raku 功能一样。
两个可用的外语适配器已经足够完善,令人惊叹——Perl 和 C 的。
我很确定有一个用于 Perl 的 BibTeX 包,它包装了一个 C BibTeX 解析器。如果您使用它,您希望将所有解析结果都很好地封装到 Raku 对象中,就好像它最初都是 Raku 一样,但保留了 C 代码的大部分高性能。
Raku BibTeX 语法?
也许您确实需要创建和使用小型 Raku 语法。
(也许您这样做部分是为了让自己熟悉 Raku 或 Raku 的正则表达式/语法方面。因为这听起来很理想。)
一旦你开始同时使用多个正则表达式——即使只有两个——你就接近了grammar 领域。毕竟,它们只是一个易于使用的结构,可以同时使用多个正则表达式。
因此,如果您决定坚持在 Raku 中编写解析代码,请编写如下内容:
grammar BiBTeX {
token TOP { ... }
token ...
token ...
}
BiBTeX.parse: my-bib-file
更多详情,请参阅the official doc's Grammar tutorial 或阅读 Moritz 的书。