标签: abstract-syntax-tree

我可以从实时scala代码中获取AST吗?

我说"实时代码"因为我的意思不是来自文本源文件或源字符串,而是来自partialFunctions/lambdas.(我知道Ruby1.8的parseTree和C#linq可以做到)

考虑一个partialFunction f:

val f = (i: Int, j: Int) => (i + j) * 2
Run Code Online (Sandbox Code Playgroud)

我希望有一些工具像这样:

getBodyAstFrom(f) //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))
Run Code Online (Sandbox Code Playgroud)

我不关心语义事物(上下文解析和implicits太复杂,对我来说是不必要的),我只需要实时代码的语法树,是否可能?

检查其他人的代码可能存在问题,但我自己的代码呢?以下事情可能吗?

val f = AstFunction(i: Int, j: Int){(i + j) * 2}
f(5, 6) //=> 22
f.ast   //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))
Run Code Online (Sandbox Code Playgroud)

它似乎需要一些黑客入侵编译器,嗯......

scala abstract-syntax-tree

12
推荐指数
1
解决办法
2101
查看次数

ast.literal_eval()支持Python 2.7中的集合文字?

Python 2.7中的新功能文档中,它表示对集合文字的支持是从Python 3.1反向移植的.但是,似乎这种支持没有扩展到ast模块的literal_eval()功能,如下所示.

这是故意的,疏忽的还是其他的 - 从字符串表示创建文字集的最简洁的解决方法是什么?(我假设以下工作在Python 3.1+中,对吧?)

import ast
a_set = {1,2,3,4,5}
print a_set 
print ast.literal_eval('{1,2,3,4,5}')
Run Code Online (Sandbox Code Playgroud)

输出显示错误消息:

set([1, 2, 3, 4, 5])
Traceback (most recent call last):
  File "...\setliterals.py", line 4, in <module>
    print ast.literal_eval('{1,2,3,4,5}')
  File "...\Python\lib\ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "...\Python\lib\ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string
Run Code Online (Sandbox Code Playgroud)

PS我能想到的唯一解决方法就是使用eval().

python set literals abstract-syntax-tree

12
推荐指数
1
解决办法
7350
查看次数

获取C++的AST?

我想获得一个用于C++的AST,然后我可以使用外部程序进行解析.哪些程序适合为C++生成AST?我不关心它实现的语言或输出格式(只要它易于解析).

我的总体目标是将C++单元测试台转换为相应的C#包装器测试台.

c++ abstract-syntax-tree

12
推荐指数
2
解决办法
6157
查看次数

如何手动遍历clang AST?

我可以使用recursivevisitor类遍历clang AST的特定子树,但我想要做的是按节点遍历clang AST节点.

如果有人能帮助我,我真的很感激.

提前致谢.

c++ traversal clang abstract-syntax-tree

12
推荐指数
1
解决办法
4121
查看次数

在Python中获取AST节点的父节点

我正在使用Python 3中的抽象语法树.该ast库提供了许多方法来获取节点的子节点(您可以使用iter_child_nodes()walk())但没有办法获得一个父节点.此外,每个节点都有指向其子节点的链接,但它没有指向其父节点的链接.

如果我不想给ast库写一些插件,我怎么能得到AST节点的父节点

这样做最正确的方法是什么?

python abstract-syntax-tree python-3.x

12
推荐指数
2
解决办法
1713
查看次数

Python ast包:遍历对象层次结构

以下是使用astsymtable 包的Python代码段.我试图解析代码并检查类型.但我不明白如何遍历对象以获取被引用的实际变量.

下面的代码实现了一个NodeVisitor,并且一个函数被呈现给编译器并由编译器和ast走了.正在分析的函数(eval_types)传递了几个对象.

下面是构成示例的代码块.我为每个块添加了一些注释.要运行代码,需要重新组装"块".

导入和用于解压缩代码块的函数.

import inspect
import ast
import symtable
from tokenize import generate_tokens, untokenize, INDENT
from cStringIO import StringIO

# _dedent borrowed from the myhdl package (www.myhdl.org)
def _dedent(s):
    """Dedent python code string."""

    result = [t[:2] for t in generate_tokens(StringIO(s).readline)]
    # set initial indent to 0 if any
    if result[0][0] == INDENT:
        result[0] = (INDENT, '')
    return untokenize(result)
Run Code Online (Sandbox Code Playgroud)

以下是节点访问者,它具有通用的未处理和名称访问者重载.

class NodeVisitor(ast.NodeVisitor):
    def __init__(self, SymbolTable):
        self.symtable = SymbolTable
        for child in SymbolTable.get_children():
            self.symtable = …
Run Code Online (Sandbox Code Playgroud)

python abstract-syntax-tree myhdl

11
推荐指数
1
解决办法
2687
查看次数

优雅的AST模型

我正在使用scala编写玩具编译器.目标语言本身看起来像scala,但它是一个开放的实验领域.

在几次大型重构之后,我找不到一种模拟抽象语法树的好方法.我想使用scala模式匹配的设施,问题是树在编译过程中携带移动信息(如类型,符号).

我可以看到几个解决方案,我都不喜欢它们:

  • 具有可变字段的case类(我相信scala编译器会这样做):问题是这些字段不存在于编译的每个阶段,因此必须被置为空(或者选项)并且调试/它变得非常繁重写代码.此外,如果例如,我在键入阶段后找到一个空类型的节点我很难找到错误的原因.

  • 巨大的特质/案例类层次结构:像Node,NodeWithSymbol,NodeWithType,......似乎很难写和使用

  • 完全用提取器手工制作的东西

我也不确定使用完全不可变的AST是否是一个好习惯,特别是在scala中没有隐式共享(因为编译器不知道不变性)并且它可能会损害性能以便始终复制树.

你能想到使用scala强大的类型系统来模拟我的树的优雅模式吗?

compiler-construction scala abstract-syntax-tree

11
推荐指数
2
解决办法
744
查看次数

如何在clang库中执行模板替换?

具体来说,我们有一个像这样的C++源文件:

template <int n>
struct N {};

struct B {
    template <typename M>
    using A = typename std::conditional<std::is_same<M, N<4>>::value,
                                        int*, void*>::type;
};

template <typename T, T value>
struct F : B {};

template <>
struct F<decltype(&fopen), &fopen> : B {
    template <typename M>
    using A = double*;
};

template <>
struct F<decltype(&fclose), &fclose> : B {
    template <typename M>
    using A = typename std::conditional<std::is_same<M, N<16>>::value,
                                        void*, char**>::type;
};

// More specialization of 'F' follows.
Run Code Online (Sandbox Code Playgroud)

这是很容易找到ClassTemplateDeclNF …

c++ clang abstract-syntax-tree

11
推荐指数
1
解决办法
817
查看次数

带有clang的多个源文件的AST

我正在用clang进行程序间数据流分析.目前我正在使用libtooling来解析源文件并调用AST访问者.问题是如何为几个.c文件创建单个AST?

我曾尝试使用ASTImport类,但它不支持导入某些AST节点.而且,当我创建和操作CompilerIstance并且它在析构函数中崩溃时,我做错了什么.

一个非常相似的选项是ASTImportAction,但在这种情况下我不太清楚哪些命令行参数应传递给ClangTool.

第三种选择是为每个.c文件创建ASTUnits并在每个文件中查找定义,不清楚如何找到用户定义类型之间的对应关系,例如记录.在ASTImport中,它们使用IsStructurallyEquivalent()函数,但它在匿名命名空间中声明,因此我只能将所有这些代码复制到我的程序中.并且它再次支持不是所有AST节点.

从互联网上链接http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-August/023865.html似乎是最合适的,但对我来说,解决方案的技术细节并不清楚.

欢迎任何建议.非常感谢.

c static-analysis clang abstract-syntax-tree

11
推荐指数
1
解决办法
1274
查看次数

导航和修改在Haskell中的Free monad上构建的AST

我试图根据我在网上阅读的一些有用的文献,使用Free monad构建AST.

我有一些关于在实践中使用这些AST的问题,我已经归结为以下示例.

假设我的语言允许以下命令:

{-# LANGUAGE DeriveFunctor #-}

data Command next
  = DisplayChar Char next
  | DisplayString String next
  | Repeat Int (Free Command ()) next
  | Done
  deriving (Eq, Show, Functor)
Run Code Online (Sandbox Code Playgroud)

我手动定义了Free monad样板:

displayChar :: Char -> Free Command ()
displayChar ch = liftF (DisplayChar ch ())

displayString :: String -> Free Command ()
displayString str = liftF (DisplayString str ())

repeat :: Int -> Free Command () -> Free Command ()
repeat times block = liftF (Repeat times …
Run Code Online (Sandbox Code Playgroud)

haskell abstract-syntax-tree free-monad

11
推荐指数
3
解决办法
1540
查看次数