使用什么类型的树遍历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) 我正在创建一个能够执行 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
我很感激能学到一些有用的东西,至于现在,我一直在盲目行动。所以问题出在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 …
我有一个像这样的变量形式描述的表达式
'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) 如何使用 Roslyn 语法工厂为整数文字(例如 2)创建表达式?
当我在调试器下查看它时,它看起来有 type NumericLiteralExpression,但我找不到如何创建它?
最近,我发现是SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Token(..)),但我不知道如何创建表示值 2 的标记。
当我用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)
我想这可能是行号内 …
我曾经尝试多种分配与海象运营商,并且已经看到了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) 我为一种简单的编程语言编写了一个解析器和评估器。这是 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",x并y引用值的位置。
所以,我需要做的是重新定义之前的类型,以便它们可以存储不同事物的相关位置。一种选择是为表达式的每个构造函数添加一个位置,如下所示:
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) 我正在阅读 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 ×6
database ×1
haskell ×1
less ×1
node.js ×1
performance ×1
python-3.8 ×1
roslyn ×1
sql ×1
stack ×1