我想使用 Raku 的正则表达式/语法引擎解析二进制文件,但我没有找到如何做到这一点,因为输入被强制转换为字符串。
有没有办法避免这种字符串强制并使用Buf或Blob类型的对象?
我在想也许可以改变元模型中的某些东西?
我知道我可以使用unpack,但我真的很想使用安装的语法引擎以获得更大的灵活性和可读性。
我是否遇到了 Raku 功能的固有限制?
在有人告诉我正则表达式用于字符串并且我不应该这样做之前,应该指出 Perl 的正则表达式引擎可以匹配字节,据我所知,我可能可以将它与 Regexp::Grammars 一起使用,但我不想使用 Raku 来代替。
另外,我不明白为什么正则表达式应该只保留给字符串,自动机理论的 NFA 本质上并不是为字符而不是字节而设计的。
我不明白懒惰/渴望在 Raku 中是如何运作的。更准确地说,如何强制渴望。
我知道无限列表是懒惰的。我不明白的是,一些有结尾的 List 是懒惰的,以及为什么在我的情况下 Eager 方法不起作用。
我有这个例子
raku -e 'say (1..*).grep({ .is-prime })[^100]'
Run Code Online (Sandbox Code Playgroud)
当我想获得前 100 个元素时,它工作正常。但是当我想要更多时,比如 200 个,我无法获得这 200 个元素。
我知道我可以用 for 循环遍历它们。像这样
raku -e 'for (1..*).grep({ .is-prime })[0..200] { .say }'
raku -e '.say for (1..*).grep({ .is-prime })[0..200]'
Run Code Online (Sandbox Code Playgroud)
我想要做的是获取具有与上述相同功能语法的元素。(没有 for 循环的那个)
我试过那些,但没有奏效
raku -e 'say (1..*).grep({ .is-prime })[^200].eager'
raku -e 'say (1..*).grep({ .is-prime })[eager ^200]'
raku -e 'say eager (1..*).grep({ .is-prime })[^200]'
raku -e 'say (1..*).grep({ .is-prime })[0..200].eager'
raku -e 'say (1..*).grep({ .is-prime })[eager 0..200]'
raku -e …Run Code Online (Sandbox Code Playgroud) 文档说逗号运算符比赋值=运算符具有更高的优先级,这与 Perl 中特别不同,因此我们可以在某些上下文中删除括号。
这允许我们做这样的事情:
my @array = 1, 2, 3;
Run Code Online (Sandbox Code Playgroud)
我不明白的是为什么要这样做:
sub test() { return 1, 2 }
my ($a, $b);
$a, $b = test();
Run Code Online (Sandbox Code Playgroud)
$b[1 2]在$a没有值的情况下被分配。
虽然我假设以下内容是等效的,因为逗号运算符比赋值更严格。
($a, $b) = test();
Run Code Online (Sandbox Code Playgroud)
Raku 的语义有很多微妙之处,我想我对 Perl 的思考太多了。
就像 raiph 在评论中所说的那样,我最初的假设是逗号运算符比赋值运算符具有更高的优先级,这是错误的。这是由于运算符优先级表的呈现存在问题,该表没有按优先级顺序显示运算符。这解释了我的示例中 Raku 的实际行为。
自从我看到 Jonathan Worthington 在 YouTube 视频 A Raku API to Raku 中展示新的 RakuAST 以来,距离 TRC 2021 为止的旅程已经过去了快一年了。在视频中,他展示了我们可以使用RAKUDO_RAKUAST=1如下方式转储这个新的 RakuAST:
RAKUDO_RAKUAST=1 raku --target=ast -e 'say [*] 1..10'
Run Code Online (Sandbox Code Playgroud)
我正在使用 RakudoStar 的最新版本,但是上面的命令仍然转储旧的 QAST 树。
这里发生了什么?
为什么它不显示新的 RakuAST,我怎样才能以正确的方式编译 rakudo 以便它显示?
对于构建,我使用此页面https://rakudo.org/downloads/rakudo/source for Linux 上的说明,并稍作修改,因为这些说明稍微过时了。这就是我所做的,而不是页面告诉我的(它以前有效,但现在不再有效):
sudo perl Configure.pl --backends=moar --gen-moar --gen-nqp
Run Code Online (Sandbox Code Playgroud) 连接点的想法最初是由达米安·康威(Damian Conway)提出的,目的是模仿量子叠加并表达量子计算算法。
尽管这可能很可爱,但叠加和折叠的概念在编程环境中没有意义,并且评估规则也远不明确。
也就是说,诸如$*scalar、@*array和 之类的变量%*hash。我问这个问题主要是因为我想了解它们对语法/正则表达式引擎的整体性能有多大负担。
为了使我的问题更加精确,我想知道会发生什么:
查找时,
my $var-1 = $*scalar
my $var-2 = @*array[3]
my $var-3 = %*hash<key>
Run Code Online (Sandbox Code Playgroud)
并在插入时,
$*scalar = "new value 1"
@*array[3] = "new value 2"
%*hash{"existing key"} = "new value 3"
%*hash{"new key"} = "new value 3"
Run Code Online (Sandbox Code Playgroud)
与符号表、调用堆栈或任何涉及的数据结构(例如用于处理动态作用域的特殊堆栈,或者可能是堆栈的哈希表)的关系。
我的主要兴趣是数组和哈希,以及每次我们推送/弹出/修改/插入数组元素或插入/修改/删除哈希的键/值对时它们是否完全重复。
编辑:
我对动态范围的假设是错误的。我认为,当修改动态范围的散列时,更改将在进行更改的词法范围的末尾被撤消,类似于 Perl 中使用关键字及其local关联的“临时堆栈”发生的情况,因此我的“数据结构是否重复?” 问题。但这并不是动态范围的含义。
我的假设是以下 Raku 代码等效于以下 Perl 代码。相反,为了复制 Perl 代码的行为,我们必须执行第二段 Raku 代码的操作。
乐1:
my %*hash = (key => "value");
sub test() { …Run Code Online (Sandbox Code Playgroud) 我写了一个对我非常有用的漂亮的小 perl 脚本。它允许我编译和执行 C 指令,就好像它是解释性语言的指令一样。它是我用来学习 C 语言的各种 C 编程 IDE。
这是我如何使用它:
crepl -Istdio 'char * str="text"; printf("%s\n", str);'
OUTPUT
text
crepl -Istdio,string 'char * str="text"; int i; for(i=0; i < strlen(str);i++){printf("%c", str[i]);} printf("\n");'
OUTPUT
text
crepl -Istdio 'char * str="text"; int i=0; while(str[i] != '\''\0'\''){printf("%c", str[i]); i++;} printf("\n");'
OUTPUT
text
Run Code Online (Sandbox Code Playgroud)
这是脚本:
#!/usr/bin/perl
# this script requires this line in /etc/fstab :
#tmpfs /tmp/ram/ tmpfs defaults,noatime,nosuid,nodev,mode=1777,size=32M 0 0
use strict;
use warnings;
use autodie;
my @include;
$,="\n";
$\="\n";
if (not @ARGV) …Run Code Online (Sandbox Code Playgroud) 我是 Common Lisp 的初学者,我想使用一个库。
我找不到加载/要求/使用模块的一个简单示例。我已经像这样安装了 cl-ppcre :
$ sbcl --non-interactive --eval '(ql:quickload "cl-ppcre")'
To load "cl-ppcre":
Load 1 ASDF system:
cl-ppcre
; Loading "cl-ppcre"
..
Run Code Online (Sandbox Code Playgroud)
但我不知道如何实际使用它。我尝试过以下方法和其他十几种方法,但没有一种有效。
$ sbcl --noinform --non-interactive --eval '(progn (require "cl-ppcre") (cl-ppcre:split "\s+" "1 2 3"))'
Unhandled SB-INT:SIMPLE-READER-PACKAGE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
{1004DB8073}>:
Package CL-PPCRE does not exist.
Stream: #<dynamic-extent STRING-INPUT-STREAM (unavailable) from "(progn (...">
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1004DB8073}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SB-INT:SIMPLE-READER-PACKAGE-ERROR "Package ~A does not exist." {1003640A83}> #<unused argument> :QUIT T) …Run Code Online (Sandbox Code Playgroud) 当我在测试中获得一个奇怪的结果时,我正在为 C 制作一个运算符优先级和结合性表,对于 Perl 来说,这是同样奇怪的先验行为。
幂**运算符是右关联的,这意味着表达式是从右到左计算的。
显然,它可以正确地处理算术表达式,但奇怪的是,它不会通过打印函数调用产生预期的结果。
我期望这个输出321
$ perl -E 'print("1") ** print("2") ** print("3"); say ""'
123
Run Code Online (Sandbox Code Playgroud)
但它产生123
用户定义的函数也会发生这种情况:
$ perl -E 'sub my_print { print $_[0] } my_print(1) ** my_print(2) ** my_print(3); say ""'
123
Run Code Online (Sandbox Code Playgroud)
更奇怪的是,
$ perl -E 'sub my_print { say $_[0]; $_[0] } say my_print(2) ** my_print(2) ** my_print(4);'
2
2
4
65536
Run Code Online (Sandbox Code Playgroud)
当我们定义一个有副作用的函数时print,它也会返回一个值。算术表达式的结果具有正确的期望值,并且按照运算符结合性定义的顺序进行求值,但print仍然不符合运算符结合性。
就好像有两个评估顺序。
man perlguts和中解释的“评估顺序传递”期间op.c)。raku ×6
rakudo ×4
perl ×2
asdf ×1
c ×1
common-lisp ×1
gcc ×1
linux ×1
moarvm ×1
operators ×1
parsing ×1
quicklisp ×1
rakudo-star ×1
side-effects ×1
unix ×1