基于ast的导航系统。

redhawk的Python项目详细描述


===
redhawk
=



redhawk是一个基于语言不可知的解析树思想构建的代码导航系统。它目前支持c&python。

它们要么过于依赖于
语言,要么在本质上非常具有启发性——使用基于regex的解析器。
redhawk试图实现两个世界的最佳结果。它使用标准的、健壮的
解析器来解析每种语言,并将生成的ast转换为一种语言
不可知的ast或last。

可以使用选择器(类似于
jquery)或类似xpath的语法来查询生成的last。redhawk的典型用法如下所示:

$redhawk query'*/definefunction'file1.py file2.c

redhawk目前正在大力开发中。代码可以在
`github`\

redhawk当前需要python 2.6或2.7。


project news
----


一组介绍性的视频,已上载到"youtube"上。

可编辑的quickfix列表)。


从1.1.2版开始,redhawk支持使用
parallel python(pp)模块进行并行查询。这加快了redhawk对大型代码库的查询。查询django中任何地方的闭包(~2200个文件)现在都可以在赛扬上网本上的~20秒内完成。


允许用户以独立于编辑器的方式有效地查找并导航代码。更好的api使用文档和一长串示例,其中
示例脚本使用选择器api。


3。允许将来进行跨语言分析,从而有利于多语言的项目。对于其他工具,通过redhawk api以简单的方式公开最后一个。
这些工具可能涉及缩进代码、建议完成或静态分析。


5。最终允许编辑最后一个,从而实现强大的重构。




dependencies
----

*运行时依赖项*:

*`pycparser``需要将C代码解析为AST。这反过来又取决于python ply(debian ubuntu上的"python ply"。

*可选但强烈建议的依赖项*:

*`pp`-并行运行查询需要并行python。这将使查询速度提高2倍以上。如果要查询大型项目,强烈建议您这样做。使用并行python(向query`
命令传递"-p")可以在不到20秒的时间内查询整个django。这个
包是一个*可选*依赖项,但强烈建议使用。这个包的名字是ubuntu上的python-pygraphviz,依赖于graphviz和dot。(`pip`
似乎很难安装pygraphviz。在node.py中生成AST类需要使用"easy_install"或从发行版的包管理器安装。

*开发(编译时)依赖项*:

*`python yaml``以形成一个简单的配置文件。这个名字叫做python yaml on
debian/ubuntu。

*`noests``是运行测试套件所必需的。

*开发周期*:

*使用bin/start-simple-bash与pythonpath.sh中的"redhawk"一起运行noests。确保测试通过。

*做出惊人的改变!

*向GitHub上的项目提交请求。

在python包索引中,它分别是
debian/ubuntu上的"python pip"和"pip"。命令::

$sudo pip install redhawk

应该安装redhawk及其依赖项pycparser。
但是,建议您也安装其他软件包:

$sudo easy_u install pygraphviz
$sudo pip install nose'pyyaml>;=3.09''nose>;=0.11'

在ubuntu/debian上(ubuntu
lucid似乎有足够多的新软件包)::


$sudo aptitude install python python pygraphviz python yaml python nose


----

1。在pycparser目录中运行`_build_tables.py',预生成lex
和yacc表。这样可以更快地解析c文件。如果pycparser是为所有用户安装的,然后,可能需要

*根特权才能运行生成的"lextab.py"和"yacctab.py"的权限必须更改
,以允许所有用户读取(755)。


redhawk
----

redhawk可以从"redhawk"可执行文件中使用,也可以通过redhawk
api使用。使用"redhawk"程序。
2.通过'import redhawk`



===============================================================================================================================================================================分析树。
查询文件列表或索引中的模式。
从AST索引中删除文件。
显示(可视化)文件为文本,或作为图像。
在其中打印当前redhawk索引的位置(如果有)。
如上所述的"query"命令接受类似xpath的
查询和文件(或目录)列表,并搜索匹配项。

可以使用
`redhawk init`命令创建
`redhawk`语言不可知树(最后一个)数据库。可以使用"redhawk add"命令将项目中的文件添加到数据库中。

"show"命令有助于可视化所使用的内部最后一个结构。
命令::

$redhawk show file.c


将以类似于lisp/scheme(sexp)的语法显示最后一个"file.c"。使用`-i`(或`-e`)
标记可以获得更具描述性的有用可视化效果,这些标记显示图形(使用
`python graphviz`模块使用'graphviz'生成)。这*需要*pygraphviz模块,一个可选的
尽管是推荐的依赖项。命令::

$redhawk show file.c-i


>显示使用默认图像python库的图形。


"提示"命令会将您拖到一个提示中,以便浏览和查询最后一个
。这样就可以使用选择器,这是一种非常强大的方法,可以找到您想要的
。有关选择器的详细信息,请参见::

$pydoc redhawk.common.selector


以获取详细文档。

查询语言简介我们在下面描述
示例。在查询特定构造时,必须知道最后一个节点的名称
。(关于这一点的详细文档即将出现。
现在,可以参考
github上的"node"和"types"yaml配置文件。[1]

对于下面的示例,我们将使用"counter.py"文件。需要注意的是
相同的查询将使用其他语言也支持(目前只支持C)。::


1 def逆时针(init=0):
2 value=[init]
3 def inc():
4 value[0]+=1
5 return value[0]
6 return inc
7
8类逆时针:
9 def_初始化(自我,init=0):
10 self.value=init
11
12 def bump(self):
13 self.value+=1
14 return self.value
15
16 def counter(init=0):
17 while true:
18 init+=1
19 yield init
20
21如果_名称:
22 c1=反诉()
23 c2=反诉()
24 c3=反诉者()
25断言(c1()==c2.bump()==c3.next())
26断言(c1()==c2.bump()==c3.next())
27断言(c1()==c2.bump()==c3.next())
28



在上面的文件中尝试"redhawk show",以了解其结构。您可以在"imgur"查看Graphviz生成的图。


*示例1*:
让我们在"counter.py"计数器中查找模块级的所有函数:


$redhawk query"definefunction"计数器。py

计数器.py:1:def反曝光(init=0):



注意:

>1。对于
行号,结果不一定按排序顺序排列。这并不妨碍使用redhawk进行搜索和
导航。(结果将始终保证按照
文件进行排序)。从好的方面来说,这会让红鹰更快一点。如果order是
必需的,那么简单地调用unix"sort"程序就可以解决这个问题。上面的查询也适用于C程序。对"stats.c"运行相同的查询可以得到:

stats.c:17:浮点方差(float*p,int len)
stats.c:5:浮点平均值(float*p,int len)
stats.c:34:int main()

*示例2*:
让我们在"counter.py"计数器中查找低于模块级别一级的所有函数:

$redhawk query'*/definefunction'计数器。py

init=0):
counter.py:3:def inc():
counter.py:12:def bump(self):


*示例3*:
让我们在程序中的任何位置*查找所有函数。:

$redhawk query'**/definefunction'counter.py

这给了我们::

counter.py:9:def初始化(self,init=0):
counter.py:16:def counter(init=0):
counter.py:3:def inc():
counter.py:1:def逆曝光(init=0):
counter.py:12:def bump(self):

*示例4*:
假设我们想在文件中找到所有闭包。我们可以通过::

$redhawk query'**/definefunction/**/definefunction'counter.py

这给我们提供了::


counter.py:3:def inc():

*示例5*:
让我们找到名称以"counter"开头的所有函数。查看
`node`yaml配置可以告诉我们,`definefunction`有一个名为
name的参数。现在我们只需要测试名称的前7个字母是否是
"counter"::

$redhawk query'**/definefunction@{n.name[:7]="counter"}"counter.py


这给了我们:

counter.py:16:def counter(init=0):
counter.py:1:def反求(init=0):



`@{..}'表示python lambda函数,默认变量为n。
因此,这是提供任意函数以匹配的另一种方式。[2]


提醒读者,所有这些查询都是langauge不可知的,运行上述命令,但在"stats.c"文件中搜索所有在它们中有字母"e"的函数:

$redhawk query'**/definefunction@{n.name.find("e")!=-1}'stats.c

/>stats.c:5:float mean(float*p,int len)

*示例7*:
查找涉及init的所有赋值。再次查看"node"
配置文件,我们发现我们正在寻找"assignment"节点,它有一个名为"init"的"referevariable"子代:

$redhawk query'**/assignment/**/referevariable@[name="init"]'计数器。py

counter.py:2:value=[init]
counter.py:18:init+=1
counter.py:10:self.value=init

注意与xpath类似的`@[..]`语法,用于引用属性。

*示例8*:
如果我们希望设置init而不是引用init赋值,该怎么办?我们将使用一个代码块来查看"assignment"的"lvalue"。:

$redhawk query'**/assignment@{n.lvalue.name=="init"}计数器。py


这给了我们::

计数器。py:18:init+=1

*示例9*:
让我们找到所有以"柜台"。再次查看
`node`\yaml配置,我们发现我们想要找到'callfunction's,其中
function对象的名称以"counter"开头。[3]:函数定义,其第一个参数为"self`[4]:

$redhawk query'**/definefunction/functionarguments/@[name="self"][0]'counter.py


init=0):

下面的查询是*错误*:


$redhawk query'**/definefunction/functionarguments/@[name="self"][-1]'counter.py


为什么?查看"node"配置
文件,我们可以看到,"functionarguments"有三个子项--"arguments"、
"var_arguments"、"kwd_arguments",后两个子项在文件中的任何位置都是"none",因为没有使用变量或关键字参数。因此,"counter.py"文件中处处可见的"functionarguments"的
子元素采用
格式`[[…],none,none`。

我们真正想要的是第一个元素的最后一个元素,即"arguments"列表。这可以表示为如下[4]:

$redhawk query'**/definefunction/functionarguments/@[name="self"][0,-1]'counter.py


this gives us::

counter.py:12:def bump(self):

上例中的查询也可以表示为:


$redhawk query'**/definefunction/functionarguments/@[name="self"][0,0]'counter.py



注意:为了方便起见,即使是`[0,-1,0]`,或`[0,-1,0,0,……,0]`is
定义为返回相同的结果。阅读'redhawk.common.xpath'文档中
的'position syntax'部分了解更多信息。





查询语言的抽象语法可以通过::


$pydoc redhawk.common.xpath

api
----

`redhawk`包也可以作为api使用,方法是导入
`redhawk.common.selector`和相关包。一些有用的包
已经在"redhawk prompt"中为用户导入,是
开始工作的好地方。

*example 1*:
假设在上面的文件中,我们希望找到所有生成器,即函数
定义,这些定义的结果是yield。我们将看到这个查询使用选择器变得多么简单,而且符合逻辑。t::

$redhawk prompt counter.py




将文件转换为与语言无关的ast。
convertcodetoast-将代码片段转换为与语言无关的ast。
help-显示此提示。
showastasimage-使用点将ast显示为图形。


-redhawk.common.selector
x-redhawk.common.xpath
f-redhawk.common.format_position


要再次查看此内容,请使用help()函数。



(有关选择器的内容,请参见"pydoc redhawk.common.selector"
,以及它们的组成方式:

in[1]:function_def=s.s(node_type='definefunction')
in[2]:yield_stmt=s.s(node_type='yield')
in[3]:reqd_selector=function_def.hasdesendant(yield_stmt)


传递的文件的ast位于
trees参数中。因为这个文件是第一个,所以它在[4]:results=list(reqd_selector(trees))


in[5]:results[0]


out[5]:definefunction



这确实是我们想要的函数。为了确定,我们使用
`f.printcontextinfile`函数来打印树的上下文。:

[6]:f.printcontextinfile(结果[0],context=6)
counter.py:10:self.value=init
counter.py:11:
counter.py:12:def bump(self):
counter.py:13:self.value+=1
counter.py:14:return self.value
counter.py:15:
counter.py:16:>;def counteriter(init=0):
counter.py:17:为真时:
counter.py:18:init+=1
counter.py:19:yield init
counter.py:20:
counter.py:21:如果"名称"为"主"时:
counter.py:22:c1=反曝光(



从这个例子中可以看出选择器是高度可组合的,因此
非常强大。希望使用选择器成为编写强大的自定义脚本以查询代码的自然方式。

您可以将其免费用于几乎没有限制的商业或非商业项目。有关许可证的完整文本,请参阅
源发行版中的license.txt文件。

此版本包含此小但重要的修复。

*v1.2.2*


*支持通过python 3运行redhawk。非常感谢
bkabda@和ncoghlan@的更改!

*新pycparser更改的兼容性。

*v1.2.1*


*用符合ansi的c编写的lua源代码,现在可以进行redhawk编辑了!

*v1.2.0*

*为xpath.py添加了新的位置功能!(有关
示例用法,请参见示例10和11 aboev)。
*添加到prompt.py中的默认导入:redhawk.common.nodes,redhawk.common.types,redhawk.common.xpath向redhawk查询添加了一个--show parsed query选项。
*只在默认的详细级别中显示关键消息。

*v1.1.6*

*主要的内部重构涉及get-ast.py
*prompt命令接受目录,可以告诉你不要使用ipython。
*一个名为apply的新的选择器函数,使提示使用变得更容易。

*bug修复了ipython shell和错误处理。

*v1.1.5*

*`vim plugin`发布。

*patch to formatposition to not strip line when context=0.

*v1.1.4版*

*在xpath.py中修复了错误,并为parallel
python对nodematchquery类进行了酸洗。



readme的rst语法中修复了错误。

*v1.1.2*

*redhawk现在可以使用parallel python(在同一台机器上)在代码基上执行查询。这使redhawk的速度(几乎)与您计算机上的核数成正比。RedHawk现在只需大约20秒就可以在Django中查询
闭包。


*更友好的使用字符串和帮助消息。

*v1.1.1*

*python2.7兼容性:ast.parse(感谢NAFAI77)

*profiled,通过切换到deque,性能提高了15%,并缓存
压扁的子对象。

*提供了一个bin/start-simple-bash-with-u-redhawk-in-pythonpath.sh以输入
临时shell-with-redhawk-in-pythonpath(用于dev)。


*v1.1.0*

*足够快,可以在django上工作-在
代码库中的任何位置查询defineclass(~2300个python文件),在赛扬上网本上只需45秒。
每个文件19毫秒!

*使用shelve模块而不是pickle模块来减少redhawk数据库的读取和写入时间。

*redhawk支持三个新命令-"listfiles"、"remove"、"where"、"query"和"show",命令使用一个额外的参数"-s",决定是否应向数据库中添加新的树。


*如果存在语法分析器错误,请跳过文件。

…[1]"ast_gen.py`"使用这些yaml配置文件生成"node.py`"和"types.py`"。[2]实际上,'@{..}'中的部分只是附加到一个'lambda n:'和'eval'-ed以获得一个函数。

[3]注意'callFunction'没有直接的名称。这是因为函数对象不同于函数定义,它可以是一个值。可以这样做(f.g[x])(y),诸如此类。[4]这些查询实际上找到的是参数,而不是函数本身。但当我们有相同的定义时,这就不重要了。





_ vim插件:http://www.vim.org/scripts/script.php?脚本ID=3586
…_ imgur:http://imgur.com/cbhcx
。_ counter.py:https://github.com/spranesh/redhawk/tree/master/redhawk/test/files/examples/counter.py
。_ stats.c:https://github.com/spranesh/redhawk/tree/master/redhawk/test/files/examples/stats.c
。_ ast_gen.py:https://github.com/spranesh/redhawk/blob/master/redhawk/common/_ast_gen.py
。_ node.py:https://github.com/spranesh/redhawk/blob/master/redhawk/common/node.py
。_ types.py:https://github.com/spranesh/redhawk/blob/master/redhawk/common/types.py
。_节点:https://github.com/spranesh/redhawk/blob/master/redhawk/common/_node_cfg.yaml
…_类型:https://github.com/spranesh/redhawk/blob/master/redhawk/common/\u types\u cfg.yaml
。_这里是:http://pycparser.googlecode.com/hg/readme.html安装过程
…_ pip:http://pypi.python.org/pypi/pip
。_ github:http://www.github.com/spranesh/redhawk
。_ python graphviz:http://networkx.lanl.gov/pygraphviz/
。_ pycparser:http://code.google.com/p/pycparser/
。_ pp:http://pypi.python.org/pypi/pp
。_ python yaml:http://www.pyyaml.org
。_鼻测试:http://somethingaboutorange.com/mrl/projects/nose/1.0.0/
。_ YouTube:http://www.youtube.com/watch?V=Azaxpahrxww

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
创建返回java测试结果的selenium测试方法   java Play2长期socket连接和多线程   java Spring引导Soap web服务创建Jaxb2插件错误   编译器构造如何将三地址码(TAC)转换为Java字节码?   java(泛型)无法对非静态类型T进行静态引用   java Kafka如何向多消费者发送消息   具有复杂类型的动态属性的java Odata   java Apache HttpClient线程   ${catalina.base}/lib子目录中的java属性文件解析   JApplet上的java分层对象(扩展JComponet)   java如何回滚Firebase Realitime数据库Android中的更改   Java正在尝试制作计时器   如何解决java。安卓中的lang.OutOfMemory异常?   将Objective C转换为Java Android没有什么问题   在java中,我不能将两个相同的变量设置为不同的值,但在python中我可以?   c#客户端和java服务器之间的身份验证错误   使用asynctask更改活动时发生java 安卓 admob错误