【发布时间】:2018-10-17 00:55:33
【问题描述】:
在 perl6 语法中,正如 here 所解释的(注意,设计文档不保证在实现完成时是最新的),如果左尖括号后跟一个标识符,那么构造是调用子规则、方法或函数。
如果标识符后面的字符是左括号,则它是对方法或函数的调用,例如:<foo('bar')>。正如页面下方进一步解释的那样,如果标识符之后的第一个字符是空格,那么直到闭合角的字符串的其余部分将被解释为该方法的正则表达式参数 - 引用:
<foo bar>
或多或少等同于
<foo(/bar/)>
使用此功能的正确方法是什么?就我而言,我正在解析面向行的数据,并且我正在尝试声明一个规则,该规则将在正在解析的当前行上发起单独搜索:
#!/usr/bin/env perl6
# use Grammar::Tracer ;
grammar G {
my $SOLpos = -1 ; # Start-of-line pos
regex TOP { <line>+ }
method SOLscan($regex) {
# Start a new cursor
my $cur = self."!cursor_start_cur"() ;
# Set pos and from to start of the current line
$cur.from($SOLpos) ;
$cur.pos($SOLpos) ;
# Run the given regex on the cursor
$cur = $regex($cur) ;
# If pos is >= 0, we found what we were looking for
if $cur.pos >= 0 {
$cur."!cursor_pass"(self.pos, 'SOLscan')
}
self
}
token line {
{ $SOLpos = self.pos ; say '$SOLpos = ' ~ $SOLpos }
[
|| <word> <ws> 'two' { say 'matched two' } <SOLscan \w+> <ws> <word>
|| <word>+ %% <ws> { say 'matched words' }
]
\n
}
token word { \S+ }
token ws { \h+ }
}
my $mo = G.subparse: q:to/END/ ;
hello world
one two three
END
事实上,这段代码产生了:
$ ./h.pl
$SOLpos = 0
matched words
$SOLpos = 12
matched two
Too many positionals passed; expected 1 argument but got 2
in method SOLscan at ./h.pl line 14
in regex line at ./h.pl line 32
in regex TOP at ./h.pl line 7
in block <unit> at ./h.pl line 41
$
第 14 行是$cur.from($SOLpos)。如果注释掉,第 15 行会产生同样的错误。似乎 .pos 和 .from 是只读的......(也许:-)
你知道正确的咒语是什么吗? 请注意,任何提议的解决方案都可能与我在这里所做的相距甚远 - 我真正想做的只是了解如何该机制应该被使用。
【问题讨论】:
-
出于好奇,
cursor_start_cur()和cursor_pass()方法是否记录在任何地方?我在class Cursor 中找不到任何内容 -
以前不是,因为它们被认为是“内部人员”。这有点过时了,但 edument 的 Rakudo 内部课程 (edumentab.github.io/rakudo-and-nqp-internals-course/…) 在“第 2 天”的中途有一些信息。此外,您可以在此处阅读源代码(Luke):github.com/perl6/nqp/blob/master/src/QRegex/Cursor.nqp
-
@Marty 如果它们被认为是内部的,难道不应该有一种方法可以在不使用它们的情况下定义该函数吗?
-
您可以通过从正则表达式返回
Match对象来前进光标。但在这种情况下我无法让它工作。作为参数传递的正则表达式也显示为ForeignCode,而不是Regex,这让我怀疑该功能在Rakudo中可能根本无法正常工作。 -
moritz - 我的猜测是,就主要俚语而言,编译的正则表达式(QAST::Regex 节点)被视为
ForeignCode。
标签: raku regexp-grammars