阅读和观看此演示文稿:
http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
我发现了这种说法——基本上建议我们不要使用语义 Action 。
我必须承认,我已经感受到了类似的感觉:带有语义 Action 的语法实际上看起来有点难看。而且,当我需要扩展/更改它们时,需要大量的“微观管理”来精确地使用语义操作。演示文稿中演示的属性语法方法似乎更加优雅和有前途。
所以我想问一下:这是“官方”观点吗?我应该学习如何使用属性语法并更详细地避免语义 Action 吗?如果是这样——我想要求一些基本的(甚至可能是微不足道的)示例,演示这种方法——LISP 解释器太复杂了,我无法咀嚼......
最佳答案
我相信 Hartmut 会在一秒钟内回答。到那时,这是我的看法:
不这不是官方观点。
语义 Action 有一些缺点
语义 Action 最简单的缺点是关注点分离的风格概念。你想在一个地方表达语法,在另一个地方表达语义。这有助于可维护性(特别是对于编译 Spirit Grammars 的冗长编译时间)
如果它们有副作用(通常是这种情况),则会产生更复杂的影响。想象一下当语义 Action 有副作用时从已解析节点回溯:解析器状态将被恢复,但外部效果不会。
在某种程度上,只使用属性就像在函数式程序中使用确定性的纯函数,更容易推断程序的正确性(或者,在这种情况下,语法 状态机),当它由纯函数组成时。
语义 Action 倾向于(但不一定如此)引入更多的值(value)复制;这与大量回溯相结合,可能会降低性能。当然,如果语义 Action 很“重”,这本身就会影响解析的性能。
语义 Action 适用于各种目的。事实上,如果您需要解析具有上下文敏感性的重要语法,您就无法转义它们。
考虑使用qi::locals<>和继承属性(来自 Mini XML - ASTs! sample 的代码)——它们涉及语义操作:
xml =
start_tag [at_c<0>(_val) = _1]
>> *node
>> end_tag(at_c<0>(_val)) // passing the name from the
// ... start_tag as inherited attribute
;
rule<char const*, locals<char> > rl;
rl = alpha[_a = _1] >> char_(_a); // get two identical characters
test_parser("aa", rl); // pass
test_parser("ax", rl); // fail
IMO,这些语义 Action 通常不会造成什么问题,因为当它们被回溯时,下一次执行通过(相同的)语义 Action 时,本地将被新的,正确,值。
另外,有些工作确实是“快速而肮脏”的,不保证使用 utree 或手动 AST 类型:
qi::phrase_parse(first, last, // imagine qi::istream_iterator...
intesting_string_pattern // we want to match certain patterns on the fly
[ log_interesting_strings ], // and pass them to our logger
noise_skipper // but we skip all noise
);
这里,语义 Action 是解析器函数的核心。它有效,因为在具有语义 Action 的节点级别不涉及回溯。
语义行为是精神业力中语义行为的镜像,通常与气相比,它们造成的问题更少;因此,即使只是为了接口(interface)/API 的一致性,语义操作也是“一件好事”,并从整体上增强了 Boost Spirit 的可用性。
关于c++ - 提升精神: "Semantic actions are evil"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8259440/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas
下面的代码在我第一次运行它时就可以正常工作:require'rubygems'require'spreadsheet'book=Spreadsheet.open'/Users/me/myruby/Mywks.xls'sheet=book.worksheet0row=sheet.row(1)putsrow[1]book.write'/Users/me/myruby/Mywks.xls'当我再次运行它时,我会收到更多消息,例如:/Library/Ruby/Gems/1.8/gems/spreadsheet-0.6.5.9/lib/spreadsheet/excel/reader.rb:11