2014-11-04 95 views
0

这更多的是一个简单的个人尝试,以了解Rascal内部发生的事情。必须有更好的(如果尚未支持的话)解决方案。 下面的代码:不能遍历AST的节点,同时为每个节点分配一个ID

fileLoad = |home:///PHPAnalysis/systems/ApilTestScripts/simple1.php|; 
fileAST=loadPHPFile(fileLoad,true,false); 

//assign a simple id to each node 
public map[value,int] assignID12(node N) 
{ 
    myID=(); 
    visit(N) 
    { 
     case node M: 
     { 
      name=getName(M); 
      myID[name] =999; 

     } 
    } 
return myID; 
} 

ids=assignID12(fileAST); 

给我

|stdin:///|(92,4,<1,92>,<1,96>): Expected str, but got value 

loadPHPFile返回类型的节点:列表[语句],其中每个语句是众多类型的语句可能发生在一个程序中的一个(在我的情况下,PHP)。没有进入为什么我会这样做,为什么上面的代码没有工作?尤其令人沮丧的是,在线文档中有一个非常简单的例子。见:http://tutor.rascal-mpl.org/Recipes/Basic/Basic.html#/Recipes/Common/CountConstructors/CountConstructors.html

回答

0

我开始了一个新的控制台,它似乎工作。当然,我将map [value,int]的返回类型更改为map [str,int],就像它最初在示例中一样。

我遇到的问题是我以前可能错误地定义了函数。虽然我很快解决了一个明显的问题,但它一直给我错误。我意识到,在Rascal中,当你启动一个控制台并导入某些定义时,它似乎不可能覆盖这些定义。口译员不断参考您提供的第一个定义。这可能只是解释者进行类型检查,并防止意外和/或不兼容的任务进一步发展。这对变量来说是有意义的(在典型的程序意义上),但它似乎不是强制执行函数(或方法)的最好方法。我感觉它变得很麻烦,因为用户在他/她对功能定义满意之前通常不得不经历一些迭代。只是我的意见,虽然...

0

很可能你已经有了名称ids范围内的类型map[str,int],这将是错误的直接来源。您可以在函数labelScript中查看脚本https://github.com/cwi-swat/php-analysis/blob/master/src/lang/php/analysis/cfg/LabelState.rsc以了解如何在PHP AiR中完成此操作(因此您不需要自己编写此代码)。这将给你一个脚本,其中所有表达式和语句都有一个分配的ID,以及标签状态,它只跟踪此标签操作中使用的一些信息(主要是计数器生成唯一ID)。

至于早期的回应,最好的办法是给你可以导入的模块的定义。如果你这样做,任何对类型等的更改都会被提取出来(如果模块已经被导入,则会自动进行更改,因为如果模块已更改,或者下次导入模块时,Rascal将为您重新导入模块)。但是,如果您直接在控制台中定义某些内容,则不会发生这种情况。把控制台想象成一个不断增加的大型模块。因为我们可以有函数的重载,所以如果你再次定义函数,你确实定义了一个新的函数替代方法,但这可能不会像你期望的那样工作。