Mah*_*van 7 compiler-errors syntax-error perl6
我正在尝试编写如下的紧凑行,代码是脚本的摘录,该脚本使用动态范围的特殊变量$*IN读取STDIN.你能告诉我如何正确写这条线吗?
这有效
for $*IN.lines() {
last when "" ;
say "VERBOSE \"$_ is the string\"";
$i=$i+1;
}
Run Code Online (Sandbox Code Playgroud)
.say "VERBOSE \"$_ is the string\"" for $*IN.lines() last when "";
Run Code Online (Sandbox Code Playgroud)
错误输出:
===SORRY!=== Error while compiling /usr/share/asterisk/agi-bin/agi-t1.p6
Two terms in a row
at /usr/share/asterisk/agi-bin/agi-t1.p6:5
------> .say? "Verbose \"$_\"" for $*IN.lines() last
expecting any of:
infix
infix stopper
statement end
statement modifier
statement modifier loop
Run Code Online (Sandbox Code Playgroud)
===SORRY!=== Error while compiling ...
Run Code Online (Sandbox Code Playgroud)
当您看到a时SORRY!,您就知道编译器正在与您讨论编译期间发生的问题,甚至在尝试运行代码之前.
Two terms in a row
Run Code Online (Sandbox Code Playgroud)
这是编译器关于什么阻止它编译代码的英文摘要.我们稍后再回来.
这------>是编译器说它被你写的东西搞糊涂的方式,并且会在你之后显示你的一些代码------>.
的?,一个字的Unicode它的名字是EJECT SYMBOL,插入到你的代码的显示.它插入的点应该有助于解释错误消息.
在这种情况下,它指向.say和"VERBOSE...".编译器认为这些是连续的两个术语.
请考虑以下代码:
start-time + 42
sum(start-time, 42)
Run Code Online (Sandbox Code Playgroud)
术语有点像数学中的术语.两个示例表达式都包含术语start-time和42.整体表达start-time + 42也是一个术语.表达式sum(start-time, 42)可以称为sum()术语或sum(...)术语.
术语也有点像自然语言中的名词或名词短语.start-time而且42就像名词一样.start-time + 42并且sum(...)像名词短语,每个都是一个术语.
(顺便说一句,术语,相关对这个问题的意义上说,是不是涉及到解析"终端",它有时也被称为"条款").
到目前为止,您可以猜测如果您尝试编译本节开头的示例代码会发生什么:
Two terms in a row across lines (missing semicolon or comma?)
Run Code Online (Sandbox Code Playgroud)
第一行(start-time + 42)是一个术语.sum(start-time, 42)是另一个术语.除了线端之外,它们之间没有任何东西.Perl 6显然不喜欢连续两个术语,没有在它们之间不是一个术语的东西,而且空格和行末端不计算.
我在上面的示例中使用的中缀+,postcircumfix ()和中缀等,运算符可以用于操作员位置(术语之前,之后,之间或周围)以形成表达式.(而整体表达本身就是如上所述的术语.)
关键词像for或者last,在关键词位置使用,也没有条款(除非你是够疯狂重新定义它们为条件,在这种情况下,你可能会得到你应得的奇怪的编译错误.:))但是,像运营商,他们必须被放置在正确的位置或编译器可能认为它们是条款.如果你last写错了地方,编译器可能认为last是一个术语.
编译器认为.say(注意末尾的空格)是一个术语,相当于.say().所以它解释你写的.say() "VERBOSE..."是连续两个术语.
(我建议你只是接受这是如此,但是如果你想深入研究方法调用语法的细节以完全理解为什么invocant.foo ( arrgh, arrgh, ... ) ;也是"连续两个术语",请参阅我的答案,其中包含与常规调用相关的各种语法.)
让我们通过更改.sayto say(不带.)来修复代码:
say "VERBOSE \"$_ is the string\"" for $*IN.lines() last when "";
Run Code Online (Sandbox Code Playgroud)
编译器返回另一个"连续两个术语"错误,但现在它指向$*IN.lines()和last.
该for关键字及其迭代参数必须要么在声明的开头或在语句结束.你最后使用过它们.
但这意味着之后的for是一个术语(它的迭代论证).
$*IN.lines() 可以作为一个术语.
你甚至可以让它成为表达的一部分,例如.for flat $*IN.lines(), $*FOO.lines()从一些其他句柄循环输入行和行.(通过展平两个单独的列表flat创建一个for单独的列表,一个来自$*IN.lines(),另一个来自$*FOO.lines().)
但是你没有构建一个表达式,你只是紧接着$*IN.lines()用last.
因为没有中last缀运算符,并且last必须是语句中的第一个单词才能成为last关键字,编译器会将其解释last为一个术语 - 因此它会看到"连续两个术语".
您需要last成为一个语句关键字,它需要在for循环的上下文中.但是你已经在for循环的上下文中有一个语句,即say ...表达式/术语.您需要一些括号或类似的东西来允许您编写多个语句.这是一种方式:
{ last when ""; say "VERBOSE \"$_ is the string\"" } for $*IN.lines();
Run Code Online (Sandbox Code Playgroud)
现在您的代码有效.
我不妨投入一些最后的调整:
( last when ''; say qq[VERBOSE "$_ is the string"]; $i++ ) for lines ;
Run Code Online (Sandbox Code Playgroud)
我已经从切换{...}到(...).它不是更紧凑,但它表明,当for写为语句修饰符时(即在语句的末尾而不是在开头),您可以使用parens而不是大括号.本{...}而创建一个词法范围(...)没有; 有时候一个或另一个就是你需要的.
你不需要,$*IN.因为有一个lines等同于的子$*IN.lines().
我已经放弃了()之后,lines因为如果在语句之后lines(或$*IN.lines)之前和结束之前没有参数,则不需要它们.
我用过''而不是""因为我认为如果你不需要插值,那么使用非插值引号是一个好习惯.
我已经使用过,qq[...]因为这意味着你不必"在字符串中转义.
我用过$i++而不是$i=$i+1因为它达到了同样的效果,我觉得它看起来更好.
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |