以下是使用ast和symtable 包的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) 如何使用PEG.js为左关联运算符构建AST(抽象语法树)?
我试图根据我在互联网上找到的信息编写一些代码,但我似乎犯了一个错误.
我编写的代码为大多数表达式生成了不正确的AST.
12-6-4-2*1-1
Run Code Online (Sandbox Code Playgroud)
{
"left": {
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": 1
}
},
"operator": "-",
"right": 1
}
Run Code Online (Sandbox Code Playgroud)
{
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": {
"left": 1,
"operator": "-", …Run Code Online (Sandbox Code Playgroud) 我正在使用Parsec编写Delphi代码解析器,我目前的AST数据结构如下所示:
module Text.DelphiParser.Ast where
data TypeName = TypeName String [String] deriving (Show)
type UnitName = String
data ArgumentKind = Const | Var | Out | Normal deriving (Show)
data Argument = Argument ArgumentKind String TypeName deriving (Show)
data MethodFlag = Overload | Override | Reintroduce | Static | StdCall deriving (Show)
data ClassMember =
ConstField String TypeName
| VarField String TypeName
| Property String TypeName String (Maybe String)
| ConstructorMethod String [Argument] [MethodFlag]
| DestructorMethod String [Argument] [MethodFlag]
| ProcMethod …Run Code Online (Sandbox Code Playgroud) 使用clang-check转储源代码的AST,可以用下面的命令来完成:
$ clang-check -ast-dump file.c --
Run Code Online (Sandbox Code Playgroud)
但是,此命令的输出将在终端内显示为彩色.
当我将输出定向到文件时,我会遇到所有颜色转义码:
$ clang-check -ast-dump file.c -- > out.txt
Run Code Online (Sandbox Code Playgroud)
例:
[0;1;32mTranslationUnitDecl[0m[0;33m 0x227c5c0[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227cac0[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __int128_t[0m [0;32m'__int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227cb20[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __uint128_t[0m [0;32m'unsigned __int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227ce70[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __builtin_va_list[0m [0;32m'__va_list_tag [1]'[0m
...
Run Code Online (Sandbox Code Playgroud)
在clang-check中是否有禁用颜色的标志?
我尝试添加以下标志,但它不起作用:
--extra-arg="--no-color-diagnostics"
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写Python表达式评估可视化工具,它将显示如何逐步评估Python表达式(用于教育目的).Philip Guo的Python Tutor很棒,但它逐行评估Python程序,我发现学生有时不理解单行表达式sorted([4, 2, 3, 1] + [5, 6])[1] == 2是如何评估的,我想要想象这个过程.(似乎没有人做过 - 至少我什么也没发现.)理想的解决方案是创建一系列字符串,如下所示:
sorted([4, 2, 3, 1] + [5, 6])[1] == 2
sorted( >> [4, 2, 3, 1] + [5, 6] << )[1] == 2
>> sorted([4, 2, 3, 1, 5, 6]) << [1] == 2
>> [1 2 3 4 5 6][1] << == 2
>> 2 == 2 <<
True
Run Code Online (Sandbox Code Playgroud)
这里>>和<<用来突出显示对当前步骤评估,然后通过它的值替换表达式的一部分.(也许,我会尝试将此序列转换为某种动画.)
我当前的策略是使用ast.parse()将字符串解析为AST,然后找到一个将首先评估的节点,用它评估它eval(compile(node, '', 'eval'))(我绝对不想重新实现整个Python :)),将评估结果转换为AST节点(有repr,然后ast.parse() …
我正在创建一个树来代表一种简单的语言.我非常熟悉抽象语法树,并且已经开发了用于在C++中构建和使用它们的框架.是否有用于指定或操纵任意AST的标准python库?如果失败了,是否有一个树库可用于同一目的?
注意,我不是在操纵Python AST,所以我认为AST模块不适合.
假设我已经在解释器中导入了一个python模块.如何在解释器中获取导入模块的抽象语法树(及其中的任何函数和类)?我不想重新解析源文件.谢谢!
我一直在python中试验AST.我想通过在运行时转换AST来修改方法.
我可以使用预编译方法的源代码inspect.getsource(),并且可以根据需要使用AST访问者修改AST.
这可能很天真,但我希望能够编译AST并做类似的事情:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
Run Code Online (Sandbox Code Playgroud)
但是compile只接受以ast.Module为根的AST.有没有办法只编译ast.FunctionDef,或从编译(和其他空)模块代码中检索功能代码对象?
任何指向信息的指针都会受到赞赏.我见过的AST例子只处理简单的表达式.
我意识到我只需要在命名空间中执行模块,然后我就可以访问正常的结构了.所以模式是:
src = inspect.getsource(myClass.myMethod)
astFromSrc = ast.parse(unindent(src)) # need to remove extra indent from method
transform(astFromSrc.body) # transform the AST as you need
ast.fix_missing_locations(astFromSrc) # fix up line numbers etc
compiled = compile(astFromSrc, '<string>', 'exec') # compile the module AST
####### From here is the part I was missing
myScope = {} # make an empty namespace
exec compiled in myScope # now myScope contains a proper compiled …Run Code Online (Sandbox Code Playgroud) 我目前正在寻找一个Java 6/7解析器,它生成一些(可能是标准化的)表单抽象语法树.
我已经发现ANTLR有一个Java 6语法,但似乎它只生成解析树,而不是语法树.我还读过有关Java编译器API的文章 - 但是所有提到的资源都是过度设计并且记录不完整(如果它确实生成了AST,我还没发现).
你知道任何好的解析器库,可能作为标准化输出吗?
谢谢
我正在尝试将AST与ANTLR4一起使用,包含以下文件:
Builder.java
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
public class Builder
{
public static void main(String[] args)
{
CharStream input = new ANTLRInputStream("ON M1==2 && M3 == 5 && (M2 > 1 || M5 <= 5.0) "
+ "DO P5:42 P4:10");
ExprLexer lexer = new ExprLexer(input);
TokenStream tokens = new CommonTokenStream(lexer);
ExprParser parser = new ExprParser(tokens);
parser.addParseListener(new ExprTestListener());
ExprParser.ExpressionContext uu = parser.expression();
}
}
Run Code Online (Sandbox Code Playgroud)
ExprTestListener:
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.tree.ErrorNode;
public class ExprTestListener extends ExprBaseListener …Run Code Online (Sandbox Code Playgroud)