加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

宏 – 如何编写perl6宏来引用文本?

发布时间:2020-12-15 22:06:34 所属栏目:大数据 来源:网络整理
导读:我想在P6中创建一个宏,将其参数转换为字符串. 这是我的宏: macro tfilter($expr) { quasi { my $str = Q ({{{$expr}}}); filter-sub $str; };} 以下是我称之为: my @some = tfilter(age 50); 但是,当我运行程序时,我得到错误: Unable to parse expression
我想在P6中创建一个宏,将其参数转换为字符串.
这是我的宏:
macro tfilter($expr) {
        quasi {
                my $str = Q ({{{$expr}}});
                filter-sub $str;   
        };
}

以下是我称之为:

my @some = tfilter(age < 50);

但是,当我运行程序时,我得到错误:

Unable to parse expression in quote words; couldn't find final '>'

我该如何解决?

解决方法

您的用例,通过宏将一些代码转换为字符串是非常合理的.虽然我遇到了同样的用例,但是还没有一个已建立的API(即使在我脑海中).在以下情况下会很好:
assert a ** 2 + b ** 2 == c ** 2;

这个断言语句宏可以评估它的表达式,如果失败,它可以打印出来.打印出来需要对其进行字符串化. (事实上??,在这种情况下,拥有文件和行信息也会很好.)

(编辑:007是一个语言实验室,用于在Perl 6中充实宏.)

现在在007中,如果你对Q对象(AST)进行字符串化,你会获得AST本身的精简对象表示,而不是它所代表的代码:

$bin/007 -e='say(~quasi { 2 + 2 })'
Q::Infix::Addition {
    identifier: Q::Identifier "infix:+",lhs: Q::Literal::Int 2,rhs: Q::Literal::Int 2
}

这比输出源代码更有意义和更直接.还要考虑这样一个事实:首先可以构建永远不是源代码的AST. (人们应该这样做.并将这些“合成Qtrees”与程序中的自然Qtrees混合在一起.)

所以我们正在看的是Q节点上的一个名为.source的属性.然后我们就能做到这一点:

$bin/007 -e='say((quasi { 2 + 2 }).source)'
 2 + 2

(注意:还不行.)

这是一个有趣的问题.source应该输出合成Qtrees.它应该抛出异常吗?或者只输出<黑盒源>?或者尽最大努力将自己变成字符串化的来源?

回到原始代码,这条线让我着迷:

my $str = Q ({{{$expr}}});

它实际上是一个非常有说服力的尝试来表达你想要做的事情(将AST转换成它的字符串表示).但我怀疑它是否会按原样运作.最后,它仍然基于源代码作为字符串的C语言思想.它的基本问题是你放置{{{$expr}}}的地方(在字符串引用环境)不是表达式AST能够到达的地方.从AST节点类型的角度来看,它没有进行类型检查,因为表达式不是引用环境的子类型.

希望有所帮助!

(PS:退后一步,我认为你通过使filter-sub接受一个字符串参数来做你自己的伤害.你会对这个函数内部的字符串做什么?解析它以获取信息?在这种情况下你会最好分析AST,而不是字符串.)

(PPS:#perl6上的Moritz指出,年龄<50时存在一个不相关的语法错误需要解决.Perl 6在使用之前对于定义的东西很挑剔;宏不会更改这个等式.因此,Perl 6解析器将假设age是一个你尚未声明的函数.然后它会考虑<一个开头的引号字符.最后它会失望的是没有>.再次,宏不会拯救你不需要事先声明你的变量.(虽然参见#159进一步讨论.))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读