我有龙书,但它似乎没有处理那个话题......
在大多数现代语言中,可以使用某些变量,即使它们在代码中的出现是无序的。
示例
class Foo {
void bar() {
plonk = 42;
}
int plonk;
}
在函数之后声明变量plonk 并不重要。
问题
有没有什么最佳实践/有用的模式来实现这个?我想到了两种方法:
在解析时为看不见的符号添加虚拟符号。当声明被解析时,这些虚拟符号会被它们的真实符号所取代。解析后,我们可以检查是否有剩余的虚拟对象,如果有则输出错误。
解析时不要做任何符号的事情,而只创建 AST。在通过 AST 解析步骤后,根据节点添加符号。例如一个类节点添加 child 的符号并在之后处理它们。例如语句 block 逐步遍历子项并在处理子项之前立即添加符号。
我希望方法 1. 对于“导入其他编译单元”之类的东西更容易,也更有用。
编辑:
我在方法 1 中看到的一个问题是需要对有序符号进行某种处理。例如。对于函数,不可能在使用之前使用局部符号。
最佳答案
如果可以,只需在解析期间构建 AST 和符号表。然后传递 AST 以将符号与符号表条目相关联。这基本上是您的策略 #2。
在一般情况下,策略 #1 的问题在于,在看到所有声明之前,您不一定知道同名的两个实例绑定(bind)到同一个符号。例如,考虑一种像 javascript 这样的语言,其中符号的绑定(bind)域是一个功能 block (恕我直言,这是一个错误,但口味各不相同),但符号在使用前不需要声明。在这种情况下,我们将只考虑命名函数的符号。
伪代码(合法的 javascript,事实证明):
function outer() {
return foo();
function inner() {
return foo();
function foo() {
return "inner's foo";
}
}
function foo() {
return "outer's foo";
}
}
foo 的两种用法指的是不同的符号,直到您到达 foo 的最后一个定义,您才能知道这一点。
策略 #2 的问题在于,在不了解所使用的符号的情况下,并不总是可以构建 AST。例如,在 C 中,如果不知道 x 是类型名还是可以取消引用的内容,就无法真正解析像 (x)(y) 这样的表达式功能。 (也是一个错误,恕我直言,但我是谁?)。在 C++ 中,您还需要知道给定符号是否为模板。通常,这被描述为符号的“种类”,而不是“类型”。在C++中,你不需要知道x的“类型”是什么来解析(x)(y);你只需要知道它是否有一个。出于这个原因,C++ 允许在声明之前使用某些符号,但如果声明是 typedef 则不允许。
撇开病理情况和宏处理器不谈,通常可以在解析期间定义范围,并将每个声明附加到一个范围。通常范围以相当简单的方式嵌套,因此一旦构建了范围树,您就可以在给定当前范围节点的情况下查找任何符号,只需沿着树向上走直到找到符号。
在某些语言(如 Python)中,声明是可选的和隐式的;在这种情况下,如果找不到该符号,您可以在第二遍中将新定义附加到当前作用域。
关于c++ - 编译器构造 : Handle references to unordered symbols,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17766992/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc