Mik*_*kel 5 regex grammar perl6
在阅读perl6的Xml语法时(https://github.com/supernovus/exemel/blob/master/lib/XML/Grammar.pm6),我在理解以下令牌时遇到了一些困难.
token pident {
<!before \d> [ \d+ <.ident>* || <.ident>+ ]+ % '-'
}
Run Code Online (Sandbox Code Playgroud)
更具体地说<.ident>,没有其他身份定义,所以我假设它是一个保留的术语.虽然我无法在perl6.org上找到合适的定义.有谁知道这意味着什么?
TL;DR我将从一个精确且相对简洁的答案开始。这个答案的其余部分是为那些想要更多地了解一般内置规则和/或ident特别深入研究的人准备的。
<.ident>功能/捕获
由于., <.ident>only 匹配,它不会捕获[1]。对于这个答案的其余部分,我通常会省略 the.因为除了捕获方面之外,它对规则的含义没有任何影响。
正如您可以在编程语言中调用(又名“调用”)另一个函数的声明中的一个函数一样,您也可以在其中调用规则/令牌/正则表达式/方法(此后我通常只使用术语“规则”)另一条规则的声明。<foo>是用于调用名为 的规则的语法foo;所以<ident>调用一个名为ident.
在我写这篇文章的时候,XML::Grammar语法本身并没有定义/声明一个名为ident. 这意味着调用最终被分派到具有该名称的内置声明。
内置ident规则与声明为完全相同:
token ident {
[ <alpha> ]
[ <alnum> ]*
}
Run Code Online (Sandbox Code Playgroud)
在官方预定义字符类文档应提供准确的定义<alpha>和<alnum>。或者,相关详细信息也稍后包含在此答案中。
底线是ident匹配一个或多个“字母数字”字符的字符串,但第一个字符不能是“数字”。
因此两者abc或def123匹配而123abc不会。
对于那些对值得了解的细节感兴趣的人,我写了以下部分:
Raku(标准语言和课程详情)
Rakudo(高级实现)
NQP(中级实施)
MoarVM(低级实现)
的规格和“规格” ident
(更正)<ident>,“字符类”和“标识符”的文档
identvs 乐标识符
XML::Grammar是用户定义的 Raku 语法。Raku 语法是一个类。(“语法实际上只是稍微专业化的课程”。)
一个乐规则是一个正则表达式是一个方法:
grammar foo { rule ident { ... } }
say foo.^lookup('ident').WHAT; # (Regex)
say Regex ~~ Method; # True
Run Code Online (Sandbox Code Playgroud)
规则调用,如<ident>语法中的 ,通常作为调用.parse或类似语法的结果而被调用。该.parse呼叫根据语法规则输入字符串相匹配。
当在匹配期间评估发生的<ident>内XML::Grammar时,结果是ident对实例的方法(规则)调用XML::Grammar(.parse如果它只是一个类型对象,则调用会创建其调用者的实例)。
因为XML::Grammar它本身并没有定义该名称的规则/方法,所以ident根据标准方法解析,呃,规则来分派调用。(我在这里使用的“规则”一词是通用的非 Raku 特定意义上的。啊,语言。)
在 Raku 中,使用表单声明创建的任何类都会grammar foo { ... }自动继承自Grammar该类,而该类又继承自Match该类:
say .^mro given grammar foo {} # ((foo) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))
Run Code Online (Sandbox Code Playgroud)
ident可以在内置Match类中找到。
在Rakudo编译器,在Match类 does的角色 NQPMatchRole。
这NQPMatchRole是找到最高级别实现的ident地方。
NQPMatchRole是用 nqp 语言编写的,它是 Raku 的一个子集,用于引导完整的 Raku,也是NQP的核心,一个编译器工具包。
摘编和重新格式化刚刚从最突出的代码的ident声明,本场比赛的第一个字符归结为:
nqp::ord($target, $!pos) == 95
|| nqp::iscclass(nqp::const::CCLASS_ALPHABETIC, $target, $!pos)
Run Code Online (Sandbox Code Playgroud)
此匹配,如果第一字符是任一个_(95在ASCII码/ Unicode的码点用于下划线)或匹配NQP定义的字符类的字符称为CCLASS_ALPHABETIC。
另一部分显着代码是:
nqp::findnotcclass( nqp::const::CCLASS_WORD
Run Code Online (Sandbox Code Playgroud)
这匹配字符类中的零个或多个后续字符CCLASS_WORD。
对 NQPCCLASS_ALPHABETIC的搜索显示了多个匹配项。最有用的似乎是NQP 测试文件。虽然此文件明确说明它CCLASS_WORD是 的超集CCLASS_ALPHABETIC,但并没有说明这些类实际匹配什么。
NQP 针对多个“后端”或具体的虚拟机。鉴于 Rakudo/NQP doc/tests 对这些规则和字符类实际匹配的内容的相对缺乏,人们必须查看其后端之一来验证什么是什么。
MoarVM是唯一官方支持的后端。
对 MoarVMCCLASS的搜索显示了几个匹配项。
重要的似乎是ops.c,其中包含一个switch (cclass)语句,该语句又包含对应于 NQP 的类似命名常量的情况MVM_CCLASS_ALPHABETIC和MVM_CCLASS_WORD对应的情况。
根据代码的注释:
CCLASS_ALPHABETIC当前匹配与完整 Raku 或 NQP<:L>规则完全相同的字符,即 Unicode 分类为“字母”的字符。
我认为这意味着<alpha>相当于CCLASS_ALPHABETIC和_(下划线)的并集。
CCLASS_WORD匹配相同的加号<:Nd>,即十进制数字(在任何人类语言中,而不仅仅是英语)。
我认为这意味着 Raku/NQP<alnum>规则等效于CCLASS_WORD.
identRaku的官方规范体现在烤[2] 中。
一个搜索烤的ident演出几场比赛。
大多数<ident>只是偶然使用,作为测试其他东西的一部分。规范要求它们按所示工作,但您不会<ident>通过查看偶然使用来理解应该做什么。
三项测试清楚地测试<ident>自己。其中一个基本上是多余的,剩下两个。我看到这两个匹配项的6.c和6.c.errata版本之间没有变化:
ok ('2+3 ab2' ~~ /<ident>/) && matchcheck($/, q/mob<ident>: <ab2 @ 4>/), 'capturing builtin <ident>';
Run Code Online (Sandbox Code Playgroud)
ok测试它的第一个参数返回True. 此调用测试<ident>跳过2+3和匹配ab2.
is $latin-chars.comb(/<ident>/).join(" "), "ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ª µ º ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö øùúûüýþÿ", 'ident chars';
Run Code Online (Sandbox Code Playgroud)
is测试它的第一个参数是否与第二个参数匹配。此调用测试ident规则与由前 256 个 Unicode 代码点(Latin-1 字符集)组成的字符串匹配的内容。
这是此测试的一个变体,它更清楚地显示了发生的匹配:
say ~$_ for $latin-chars ~~ m:g/<ident>/;
Run Code Online (Sandbox Code Playgroud)
印刷:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
_
abcdefghijklmnopqrstuvwxyz
ª
µ
º
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ
ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö
øùúûüýþÿ
Run Code Online (Sandbox Code Playgroud)
但是<ident>将匹配来自 Latin-1 的超过一百个左右的字符。因此,尽管上述测试涵盖哪些<ident>是官方指定/测试匹配,他们显然没有涵盖的全貌。
那么让我们来看看官方的猜测,小心翼翼地认为与“规范”有关。
首先,我们注意到顶部的警告:
Note: these documents may be out of date.
For Perl 6 documentation see docs.perl6.org;
for specs, see the official test suite.
Run Code Online (Sandbox Code Playgroud)
此警告中的术语“规格”是“规格”的缩写。正如已经解释过的,官方规范测试套件是烤的,而不是任何人类语言的措辞。
(有些人仍然认为这些历史设计文档也被称为“规范”,并将它们称为“规范”,但官方的观点是“规范”应用于设计文档时,应该被认为是“的缩写”推测”以强调它们不是完全可以依赖的东西。)
一个用于搜索ident在design.raku.org显示了若干场比赛。
这些是任何语法或正则表达式的一些预定义子规则:
呃...
<ident>,“字符类”和“标识符”的文档 Class Description
<ident> Identifier. Also a default rule.
Run Code Online (Sandbox Code Playgroud)
这在三个方面具有误导性:
ident是不是 一个字符类。字符类匹配该字符类中的单个字符;如果与量词一起使用,它们只匹配一串这样的字符,每个字符都可以是该类中的任何字符。相反,<ident>匹配特定的字符模式。它可能是一个角色,但你无法控制它;规则是贪婪的,匹配符合模式的字符数。如果应用量词,它控制整个规则的重复,而不是规则的单个匹配项中包含多少个字符。
所有内置规则都是默认规则。我认为默认注释是为了强调ident如果您不喜欢内置模式,您可以编写自己的规则。这适用于所有规则,尽管覆盖诸如<lower>(小写)之类的规范字符类之类的内置函数通常意义不大。
ident它不符合标识符!或者,更准确地说,对于大多数 Raku 标识符,它本身并没有这样做。有关详细信息,请参阅下一节。
identvs 乐标识符my @Identifiers = < $bar %hash Foo Foo::Bar your_ident anothers' my-ident >;
say (~$/ if m/^<ident>$/ for @Identifiers); # (Foo your_ident)
say (~$/ if m/ <ident> / for @Identifiers); # (bar hash Foo Foo your_ident anothers my)
Run Code Online (Sandbox Code Playgroud)
在 NQP 的Grammar.nqp 中定义的 nqp语法中,有:
token identifier { <.ident> [ <[\-']> <.ident> ]* }
Run Code Online (Sandbox Code Playgroud)
在 Raku 的Grammar.nqp 中定义的 Raku 语法中,有些代码看起来略有不同,但具有完全相同的效果:
token apostrophe { <[ ' \- ]> }
token identifier { <.ident> [ <.apostrophe> <.ident> ]* }
Run Code Online (Sandbox Code Playgroud)
因此<identifier>匹配包含一个或多个<ident>s 且<apostrophe>s 介于两者之间的模式。
该ident方法是NQPMatchRole,这意味着它是一个内置的的用户语法的规则命名空间的一部分。
但是这些identifier方法不是由 Raku 或 nqp 导出的。所以它们不是用户语法的规则命名空间的一部分。
如果我们编写自己的indentifier令牌,我们可以看到它的实际效果:
my token identifier { <.ident> [ <[\-']> <.ident> ]* }
my token sigil { <[$@%&]> }
say (~$/ if m/^ <sigil>? <identifier> $/ for @Identifiers)
Run Code Online (Sandbox Code Playgroud)
显示:
($bar %hash Foo your_ident my-ident)
Run Code Online (Sandbox Code Playgroud)
总结上述和其他一些注意事项:
<ident>只匹配部分的什么<identifier>比赛(尽管它们是简单的名称相同)。考虑is-prime。这是一个 Raku 标识符,但包含两个 <ident>匹配项(is和prime)。
<identifier>仅匹配零件“乐标识符”(虽然他们的简单名称相同)的。考虑infix:<+>。这有时被称为 Raku 标识符,但需要<identifier>匹配和匹配:<+>。
乐标识符本身只是部分的名称(虽然他们对于最简单的名称相同)。考虑Foo-Bar::Baz-Qux哪个包含两个 <identifier>匹配项(每个又包含两个<ident>匹配项)。
[2]乐的官方规范是一种称为烘烤测试套件-所述ř epository ø ˚F甲LL小号pecification Ť的EST。特定烤肉分支的最新版本定义了特定版本的 Raku。当我第一次写这个答案时,只有两个官方分支/版本的烤肉,因此是 Raku。第一个是6.c又名6.Christmas。这是在 2015 年圣诞节那天被剪掉的,从那天起就被故意冻结了。第二个是6.c.errata,它保守地添加了更正6.c被认为足够重要且向后兼容以包含在(当时)当前官方推荐的 Raku 版本中。一个“正式兼容”的 Raku 编译器通过了一些官方的烤肉分支。Rakudo 编译器(当时)通过了6.c.errata. 如果您阅读了所有涉及某个功能的测试,例如,6.c.errata烘焙分支,那么您将阅读该功能在 Raku 语言版本中的官方指定含义的完整定义6.c.errata。
通常,查找文档的位置是Perl6文档.这是正则表达式的一部分,你可以在字符类的定义中找到它.它匹配Perl6标识符.什么.前面ident所做的是要抑制捕获.
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |