使用 ast.NodeTransformer 时,是否有一种简单的方法可以返回多个节点来替换单个节点?例如,假设我想重写以下形式的所有表达式
f(g())到_x1 = g(); g(_x1)
visit_Expr如果可以返回多个节点而不是单个节点,那么做到这一点将非常容易。但我似乎无法让它发挥作用,所以我认为这不是这样做的方法。任何建议将不胜感激。
[Update]
作为更新,我有一个工作版本,它将新节点和旧节点累积在列表中,并将它们分配给封闭范围节点的主体(例如For、While、Module节点等)。这绝对是一种很奇怪的方法,并且怀疑还有更好的方法。我会保留这个以防有人知道这种情况。
[final update]查看文档,NodeTransformer如果节点是语句集合的一部分,实际上完全有可能返回节点列表。
我正在尝试构建一个抽象语法树,允许使用 monaddo表示法进行定义,如下所示:
ast = do
Variable uint8 "i"
Function Void "f" $ do
Variable uint8 "local_y"
Comment "etc. etc."
Run Code Online (Sandbox Code Playgroud)
我在这里展示的结构是从Text.Blaze.Html中收集的,它用于定义 HTML 树。
问题分散在以下各个部分。主要问题是如何正确地做到这一点。当然,任何有助于理解此结构的输入都将受到高度赞赏。
因此,首先,这是一个虽小、有缺陷但“有效”的示例。它是一个语法树,其中包含特定类型的变量和函数的声明、注释行以及用于替换的占位符声明:
{-# LANGUAGE ExistentialQuantification #-}
module Question
where
import Control.Applicative
import Data.Monoid (Monoid, (<>))
import Data.String.Utils (rstrip)
type NumberOfBits = Word
type VariableName = String
data Type = UInt NumberOfBits
| Int NumberOfBits
| Void
uint8 = UInt 8
int8 = Int 8
instance Show Type where
show (UInt w) = "uint" <> …Run Code Online (Sandbox Code Playgroud) 问题描述
我正在编写一个简单的JSON分析器,以实现JSON字符串的语法分析。我收到随机结构 JSON 字符串,并且想要导出语法结构。因此,我想要一个树结构,它描述 JSON 字符串的格式(键、值、数组等)和每个元素的类型。我已经找到了JSON的语法定义(如下所述)
object
{}
{ members }
members
pair
pair , members
pair
string : value
array
[]
[ elements ]
elements
value
value , elements
value
string
number
object
array
true
false
null
Run Code Online (Sandbox Code Playgroud)
例子
JSON 字符串:
{"widget": {
"null": null,
"window": {
153: "This is string",
"boolean": true,
"int": 500,
"float": 5.555
}
}}
Run Code Online (Sandbox Code Playgroud)
我想要得到类似的东西:
{ KEY_STR : {
KEY_STR : null
KEY_ARRAY : {
KEY_INT: VALUE_STR,
KEY_STR: VALUE_BOOL,
KEY_STR: VALUE_INT,
KEY_STR: VALUE_FLOAT …Run Code Online (Sandbox Code Playgroud) 我需要将字符串转换为遵守特定语法规则的对象(类似 AST)。
我基本上有3种表达方式('@', '$' and '#')。'#'类型的表达式写为,#something而其他两个写为@something==somethingelse和$something==somethingelse。
这些表达式可以使用连词 ( 'and', 'or') 进行分组,并且可以使用括号修改运算顺序。
下面是一个完整表达式的示例:
const expression =
`#buy
&& (@car == white || @bike == blue)
&& $user==authenticated`;
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种使用 javascript 或基于 javascript 的工具(将在 React 项目中使用)将其转换为对象(类似 AST)的方法。
const ast = {
type: 'expression',
conjunction: 'null',
expressions: [{
type: 'expression',
conjunction: null,
expressions: [{
type: '#',
left: 'buy',
operator: null,
right: null
}]
},
{
type: 'expression',
conjunction: '&&',
expressions: [{
type: 'expression',
conjunction: 'null', …Run Code Online (Sandbox Code Playgroud) javascript compiler-construction parsing abstract-syntax-tree
eval我想创建一个稍后可以重用的代码对象。我需要根据ast以编程方式生成的一些节点来执行此操作,因此我无法将代码作为字符串传递给compile函数。如何构造一个有效的ast编译节点?以下是我尝试过的一些事情:
tree = ast.parse("2+2")
exe = compile(tree.body[0], filename="", mode="eval")
Run Code Online (Sandbox Code Playgroud)
类型错误:预期的表达式节点,得到 Expr
tree = ast.BinOp(left=ast.Num(n=2), right=ast.Num(n=2), op=ast.Add())
exe = compile(tree, filename="", mode="eval")
Run Code Online (Sandbox Code Playgroud)
类型错误:预期的表达式节点,得到 BinOp
tree = ast.BinOp(left=ast.Num(n=2), right=ast.Num(n=2), op=ast.Add())
expr = ast.Expression(body=[tree])
ast.fix_missing_locations(expr)
exe = compile(expr, filename="", mode="eval")
Run Code Online (Sandbox Code Playgroud)
类型错误:expr 中缺少必填字段“lineno”
我正在使用 clang 通过 python 接口提供的抽象语法树,尝试解析包含 std::vector 的简单结构:
#include <vector>
struct outer_t
{
std::vector<int> vec_of_ints;
};
Run Code Online (Sandbox Code Playgroud)
我想获取向量的模板参数,但在 AST 的相应节点中找不到对它的引用。get_num_template_arguments() 成员函数返回 -1。因此我认为 get_template_* 函数不能使用。我尝试了以下方法:
import sys
import clang.cindex
clang.cindex.Config.set_library_file("/usr/lib/llvm-6.0/lib/libclang.so.1")
class Walker:
def __init__(self, filename):
self.filename = filename
def walk(self, node):
node_in_file = bool(node.location.file and node.location.file.name == self.filename)
if node_in_file:
print(f"node.spelling = {node.spelling:14}, node.kind = {node.kind}")
if node.kind == clang.cindex.CursorKind.TEMPLATE_REF:
print(f"node.get_num_template_arguments = {node.get_num_template_arguments()}")
for child in node.get_children():
self.walk(child)
filename = sys.argv[1]
index = clang.cindex.Index.create()
translation_unit = index.parse(filename)
root = translation_unit.cursor
walker = Walker(filename) …Run Code Online (Sandbox Code Playgroud) 我需要跟踪 AST 的范围,以便使用 JS 中的 acorn-walk 将所有表达式排列到层次结构中。文档很少,所以我很无能。感谢您的帮助!
我维护doctest。该库使用 ECMAScript 解析器 (Esprima) 从 JavaScript 源文件中提取注释,然后在这些注释中识别 \xe2\x80\x9cdoctests\xe2\x80\x9d。例如:
\n\'use strict\';\n\n// identity :: a -> a\n//\n// > identity (42)\n// 42\nconst identity = x => x;\nRun Code Online (Sandbox Code Playgroud)\n然后 AST 被丢弃,JavaScript 代码被拼接到原始源文本中代替文档测试。想象一下类似下面的事情:
\n\'use strict\';\n\n// identity :: a -> a\n//\n__doctest.enqueue (() => {\n assert.strictEqual (identity (42), 42);\n});\nconst identity = x => x;\nRun Code Online (Sandbox Code Playgroud)\n然后,修改后的源文本将保存到文件系统中。最后,新创建的文件通过 导入require。
这种方法有效,但比较迂回:
\nSourceFile -> SourceText -> AST -> SourceText -> SourceFile -> SourceText -> AST -> Result\n=(foo.js)= (original) --------> (modified) =(tmp.js)= ====(require)====\n …Run Code Online (Sandbox Code Playgroud) 有一个 ESTree 规范描述了 JavaScript AST 格式,该格式在多个库中用于 JS 代码转换(重构、转译、缩小等)。
是否有任何具有 API 的工具/库专注于从头开始(而不是从现有的 JS 代码)生成ESTree AST 并对其进行操作?最好在 TypeScript 中获得 ESTree 节点静态类型的优势。
javascript compiler-construction code-generation abstract-syntax-tree typescript
我正在寻找一个 Python 库,用于将代码解析为其抽象语法树表示形式。存在一个内置模块,名为ast,但是,据我了解,它只是为解析 Python 代码而设计的。我想知道是否有一个类似的 Python 库可以满足相同的目的,但可以与其他编程语言一起使用。特别是,我正在寻找一种可以解析 JavaScript 代码的工具。
如果不存在,有什么指导我如何开始设计自己的吗?
javascript ×5
python ×4
parsing ×2
acorn ×1
c++ ×1
clang ×1
evaluation ×1
free-monad ×1
gson ×1
haskell ×1
java ×1
json ×1
libraries ×1
monads ×1
node.js ×1
templates ×1
tree ×1
typescript ×1