标签: abstract-syntax-tree

ast 模块使用什么类型的树遍历?

使用什么类型的树遍历ast(特别是ast.NodeVisitor())?当我创建一个堆栈并将遍历的每个节点推入堆栈时,结果似乎是“广度优先”树遍历。这意味着顺序取决于树中的级别。

前任。树看起来像

Module
  Assign
    Name
      Store
    Call
      Attribute
        Str
        Load
Run Code Online (Sandbox Code Playgroud)

堆栈看起来像

[Module,Assign,Name,Call,Store,Attribute,Str,Load]
Run Code Online (Sandbox Code Playgroud)

前任。代码

stack = []
class a(ast.NodeTransformer):
    def visit_Num(self,node):
        stack.append(node)
        ...
        return node

    ...                      #this is all the other visit_*() functions

    def visit_Str(self,node):
        stack.append(node)
        ...
        return node

if __name__ == "__main__":
    with open('some_file.py','r') as pt:
        tree = ast.parse(pt)
    new_tree = a()
    new_tree_edit = ast.fix_missing_locations(new_tree.visit(tree)) # I have tried with and without calling fix_missing_locations and got the same results.
    print stack
Run Code Online (Sandbox Code Playgroud)

python stack abstract-syntax-tree tree-traversal

4
推荐指数
1
解决办法
3321
查看次数

AST 与 Postfix 算法

我正在创建一个能够执行 SQL 查询的数据库。我正在使用 Flex / Bison 创建我的 AST(抽象语法树)。例如:select * from table where score> 10 * (age * pay)

在此处输入图片说明

当我评估这个 AST 树时,我遍历这棵树,从左边开始,然后是右边的子树。

与 muparser ( http://muparser.beltoforion.de/ ) 相比,它要快得多。有没有其他方法可以执行此处理?如果我使用 Postfix 算法 ( http://en.wikipedia.org/wiki/Reverse_Polish_notation ) 我会有更好的性能吗?

传统数据库如何执行此任务?

sql database performance abstract-syntax-tree postfix-notation

4
推荐指数
1
解决办法
1894
查看次数

Python AST、ast.NodeTransformer、TypeError:stmt 中缺少必填字段“lineno”

我很感激能学到一些有用的东西,至于现在,我一直在盲目行动。所以问题出在python的ast.NodeTransformer. 我想知道是否可以使用这种方式向现有类添加一个函数,而不是生气。

这就是我到目前为止的处理方式。

import ast, inspect, cla # cla is a name of class to which we want to add a new function

klass = inspect.getsource(cla)
tree = ast.parse(klass)
st = '''def function(): return 1'''
Foo = ast.parse(st)

class AddFunc(ast.NodeTransformer):
      def visit_ClassDef(self, node):
          return node, node.body + Foo.body
          self.generic_visit(node)

inst = AddFunc()
stuff = i.visit(tree)

# now the trouble begins, a compiling..
co = compile(stuff, filename='<ast>', mode='exec')

# i get TypeError: required "lineno" missing from stmt
Run Code Online (Sandbox Code Playgroud)

我已经尝试过(如您可能猜到的那样不成功)通过使用 ast …

python abstract-syntax-tree

4
推荐指数
2
解决办法
1957
查看次数

用AST python中表达式中的实际值替换变量名

我有一个像这样的变量形式描述的表达式

's1*3 - (s2-s1)*1'
Run Code Online (Sandbox Code Playgroud)

我已经给出了可以根据需要改变的 s1 和 s2 的值

我可以使用 python ast模块通过替换各自的 s1 和 s2 值来评估这个表达式 (s1 = 20,s2=30)

import ast
import operator as op

operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul,
             ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor,
             ast.USub: op.neg}

def eval_(node):
    if isinstance(node, ast.Num): # <number>
        return node.n
    elif isinstance(node, ast.BinOp): # <left> <operator> <right>
        return operators[type(node.op)](eval_(node.left), eval_(node.right))
    elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
        return operators[type(node.op)](eval_(node.operand))
    else:
    raise TypeError(node)

>>> str1 = '20*3 - (30-20)*1' …
Run Code Online (Sandbox Code Playgroud)

python abstract-syntax-tree

4
推荐指数
2
解决办法
2518
查看次数

使用 Roslyn 创建整数文字表达式

如何使用 Roslyn 语法工厂为整数文字(例如 2)创建表达式?

当我在调试器下查看它时,它看起来有 type NumericLiteralExpression,但我找不到如何创建它?

最近,我发现是SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Token(..)),但我不知道如何创建表示值 2 的标记。

abstract-syntax-tree roslyn

4
推荐指数
1
解决办法
656
查看次数

如何访问 LESS 生成的 AST?

我想通过访问AST对 LESS 样式表执行一些代码分析。该方案使用的文档只介绍渲染文件或字符串。

如何访问less.js AST?

abstract-syntax-tree less node.js

4
推荐指数
1
解决办法
615
查看次数

抽象语法树中 Python f 字符串的行号

当我用ast模块解析源代码时,为什么linenoa Nameinside a的属性FormattedValue设置为 1,即使 f 字符串不在第 1 行?

我正在尝试查看函数定义中包含哪些源代码行,因此我正在遍历节点下方的抽象语法树FunctionDef节点。我将所有lineno属性收集到一个集合中,这告诉我哪些行是函数定义的一部分。

然而,当f-strings出现在 Python 3.6 中时,他们以某种方式打破了这种技术。下面是问题的一个例子:

import ast

code = """\

f'x{y}'
"""

tree = ast.parse(code)

print(ast.dump(tree, include_attributes=True))
Run Code Online (Sandbox Code Playgroud)

这是该脚本的输出:

Module(body=[Expr(value=JoinedStr(values=[Str(s='x', lineno=2, col_offset=0), FormattedValue(value=Name(id='y', ctx=Load(), lineno=1, col_offset=1), conversion=-1, format_spec=None, lineno=2, col_offset=0)], lineno=2, col_offset=0), lineno=2, col_offset=0)])
Run Code Online (Sandbox Code Playgroud)

我知道这很不可读,所以这里有一些额外的空格相同的输出:

Module(body=[Expr(value=JoinedStr(values=[
    Str(s='x', lineno=2, col_offset=0), 
    FormattedValue(value=Name(id='y',
                              ctx=Load(),
                              lineno=1,
                              col_offset=1),
                   conversion=-1,
                   format_spec=None,
                   lineno=2,
                   col_offset=0)], lineno=2, col_offset=0), lineno=2, col_offset=0)])
Run Code Online (Sandbox Code Playgroud)

唯一的源代码在第 2 行,那么这部分输出是什么?

Name(id='y',
     ctx=Load(),
     lineno=1,
     col_offset=1)
Run Code Online (Sandbox Code Playgroud)

我想这可能是行号内 …

python abstract-syntax-tree

4
推荐指数
1
解决办法
469
查看次数

通过 walrus := 运算符进行多次赋值?

我曾经尝试多种分配与海象运营商,并且已经看到了StackOverflow的问题,比如这个使用海象运营商也无法分配多个变量,只是想知道一个成功的多任务将是什么样子,或者它是否是不可能。

这样做的目的是添加对检测我的库mvdef 中所有分配的变量名称的支持(特别find_assigned_args是在mvdef.src.ast_util模块中的函数内)。

从运行中ast.parse我可以看到:=操作符生成了一个ast.NamedExpr节点,.target它有一个ast.Name对象属性,我可以从对象的.id属性中获取分配的名称。

如果我不得不猜测,我会假设如果有可能的话,该.target属性将是一个ast.Name对象列表而不是单个ast.Name对象,但是我似乎无法得到一个例子的事实使得我想知道这是否不可能,至少暂时是不可能的(在这种情况下,我可以简化我的代码,而不仅仅是猜测实现应该是什么)。

如果有人知道要查看 Python 源代码的哪个特定部分来告诉我这是否可行,那会很有帮助,谢谢!

PS - 从初始提交( via )中Lib/test/test_parser.py提供的测试用例来看,似乎没有海象运算符多次赋值的例子,所以我现在假设这是不可能的(但请注意如果我错了!)

def test_named_expressions(self):
    self.check_suite("(a := 1)")
    self.check_suite("(a := a)")
    self.check_suite("if (match := pattern.search(data)) is None: pass")
    self.check_suite("[y := f(x), y**2, y**3]")
    self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
    self.check_suite("(y := f(x))")
    self.check_suite("y0 …
Run Code Online (Sandbox Code Playgroud)

python abstract-syntax-tree python-3.8

4
推荐指数
1
解决办法
1460
查看次数

我的语言的 AST 类型设计记住令牌位置

我为一种简单的编程语言编写了一个解析器和评估器。这是 AST 类型的简化版本:

data Value = IntV Int | FloatV Float | BoolV Bool
data Expr = IfE Value [Expr] | VarDefE String Value
type Program = [Expr]
Run Code Online (Sandbox Code Playgroud)

我希望错误消息告诉发生错误的源代码的行和列。例如,如果If表达式中的值不是布尔值,我希望求值器显示一个错误,指出"expected boolean at line x, column y",xy引用值的位置。

所以,我需要做的是重新定义之前的类型,以便它们可以存储不同事物的相关位置。一种选择是为表达式的每个构造函数添加一个位置,如下所示:

type Location = (Int, Int)

data Expr = IfE Value [Expr] Location | VarDef String Value Location
Run Code Online (Sandbox Code Playgroud)

这显然不是最优的,因为我必须将这些Location字段添加到每个可能的表达式中,例如,如果一个值包含其他值,我也需要为该值添加位置:

{-
this would turn into FunctionCall String [Value] [Location], 
with one location for each value in …
Run Code Online (Sandbox Code Playgroud)

haskell abstract-syntax-tree

4
推荐指数
1
解决办法
90
查看次数

Python AST 代码示例取自 Serious Python:关于部署、可扩展性、测试等的黑带建议

我正在阅读 Julien Danjou 的《Serious Python: Black-Belt Advice on Deployment, Scalability, Testing, and More》一书,我在第 8 章的代码中遇到了问题。这是代码:

import ast
hello_world = ast.Str(s = 'hello world!', lineno=1, col_offset=1)
print_name = ast.Name(id='print', ctx=ast.Load(), lineno=1, col_offset=1)
print_call =  ast.Call(func=print_name, ctx=ast.Load(), args=[hello_world], keywords=[], lineno=1, col_offset=1)
module = ast.Module(body=[ast.Expr(print_call, lineno=1, col_offset=1)], lineno=1, col_offset=1)
code = compile(module, '', 'exec')
eval(code)
Run Code Online (Sandbox Code Playgroud)

它给了我以下错误:

code = compile(module, '', 'exec')
TypeError: required field "type_ignores" missing from Module
Run Code Online (Sandbox Code Playgroud)

我仔细检查我是否输入错误,但我没有发现任何错误。

有人可以给我一个线索吗?

非常感谢!

python abstract-syntax-tree

4
推荐指数
1
解决办法
64
查看次数