面向人的ast分析器
horast的Python项目详细描述
python 3的面向人的抽象语法树(ast)解析器/分析器,它不丢弃注释。
此包提供了新的ast节点类型(comment和directive),这些类型继承自type\ast.ast3模块中的节点。 此外,它还为扩展的ast提供了解析器和unparser的实现 直接可读的代码生成。
如何使用此软件包的简单示例:
fromhorastimportparse,unparsetree=parse("""a = 1 # a equals one after this""")print(unparse(tree))# this will print the code with original comment
examples.ipynb中的更多示例。
技术细节
解析器基于内置的tokenize模块,以及社区包asttokens和typed-ast。
unparser本质上是来自静态类型包的unparser类的扩展。
horast提供和处理的节点如下所示。
评论
当整行和行尾注释位于外部时,它们将被正确地分析/取消分析 多行表达式。
目前,多行表达式中注释的处理仅部分实现。
blockcomment
尚未实现。
此节点类型用于在 单个ast节点,因此简化了对大型注释块的处理。
指令
由于python不提供用代码直接传递指令的方式, 以下列前缀开头的注释将不被分类 作为典型注释,但作为指令:
- 如果
- 否则
- endif
- 定义
- 未设防
- ifdef
- ifndef
然而,在python代码中,它们仍然保持通常的注释。
例如,下面代码中的注释都将被归类为指令。
#ifdef DEBUGdebugging=True#elsedebugging=False#fi
但是,当作为python执行时,debugging将始终以^{tt2}结尾$ 因为在python中,指令和通常的注释一样被保留,因此 他们被忽视了。
因此,Directive节点不是用来启用 Python,至少现在是这样。
注意:前缀是正确的。请参见以下示例:
#if something# if some other thing
第一行的注释将成为Directive对象,而 在第二个like将变成Comment对象。
目前,此节点旨在实现 python和其他语言,帮助从python ast生成代码 在其他语言中,一个这样的用例是 *transpyle* project。
杂注
Pragma节点遵循与Directive节点相同的一般规则,即 作为注释存储在python代码中,但是注释将被分类为pragma 当前缀是预定义的前缀时:
- " pragma:"
另外,在horast中定义了pragma的两个子类,每个子类都有 基于泛型pragma前缀的自有前缀:
- OpenMpPragma类定义前缀" pragma: omp"并存储openmp pragmas。
- OpenAccPragma类定义前缀" pragma: acc"并存储openacc pragmas。
下面的代码片段包含所有3种pragma类型。
# pragma: onceuse_openmp=Trueuse_openacc=True...a,b=np.ndarray(...)c=np.zeros(...)# pragma: acc parallel copyin(a,b) copyout(c)# pragma: acc loop gangforyinrange(ymax):# type: np.int32# pragma: acc loop workerforiinrange(imax):# type: np.int32# pragma: acc loop vector reduction(+: c[y][x])forxinrange(xmax):# type: np.int32c[y,x]+=a[y,i]*b[i,x]# pragma: acc end parallel...# pragma: omp parallel doforiinrange(input_data.size):# type: int# here we compute spam spam spamheavy_compute(input_data[i])...
因此,在上面的例子中:
- 所有以" pragma: omp"开头的注释都变成OpenMpPragma对象,
- 所有以" pragma: acc"开头的注释都变成OpenAccPragma对象,
- 以" pragma:"开头的所有其他注释都变成Pragma对象,
- 类型注释将被忽略,并且
- 所有其他注释都成为Comment对象。
另外,horast模块提供了一个可扩展的基础设施来定义 自定义Pragma子类,允许用户为 实验。提供的openmp和openacc pragma定义提供 作为如何使用此功能的示例。
包括
类似于如何处理pragma,如果注释以^{tt21}开头$ 前缀,它将被归类为一种特殊的include direct我爱你。
同样,这将在python代码中保留为注释,但它很有用 用于增强python与其他语言之间的语法兼容性,特别是 静态编译语言。