标签: abstract-syntax-tree

从基于 Ruby 的源文件中提取代码片段

我最近一直在玩flog,它是一个非常好的工具,可以为 ruby​​ 应用程序生成代码复杂性报告。在项目代码库上运行的结果是, flog您会得到类似于以下内容的输出:

  1272.3: flog total
     7.3: flog/method average

    62.2: MyClass#foobar lib/myclass#foobar:123
    ... more similar lines ...
Run Code Online (Sandbox Code Playgroud)

上面的示例提供了方法的分数,并引用了定义该方法的源代码中的确切行号。这可以是常规实例/类方法或任何其他“动态”方法,例如。耙子任务等等。

因此,目标是从源文件中提取一段代码(很可能是一个方法),该代码以 flog 输出中定义的行号开头。然后,该代码片段可以在某些 Web UI 中用于显示各种代码指标(基于其他工具,例如flay)和/或存储在数据库中。据我所知,这个任务涉及将 ruby​​ 代码解析为 AST,然后遍历树找到相应的起始行并找出结束行号。我已经用这个库做了一些实验 - https://github.com/whitequark/parser,大部分时间都有效,但获得正确的结果有点棘手。

还有其他解决方案可以从用 ruby​​ 编写的源文件中快速提取方法代码吗?

ruby parsing abstract-syntax-tree code-complexity

2
推荐指数
1
解决办法
919
查看次数

如何找出 python 函数返回的输出数量?

假设有两个 Python 函数:

def f1(x):
    return x

def f2(x):
    return x,x**2
Run Code Online (Sandbox Code Playgroud)

我想知道 . 返回了多少个输出f1以及 . 返回了多少个输出f2

我想避免以下解决方案:

result = f1(1)
no_outputs = len(result) if type(result) == tuple else 1
Run Code Online (Sandbox Code Playgroud)

由于当函数返回元组时此解决方案会失败。

我开始使用 python ast(抽象语法树)库,并且想知道是否有任何方法可以解析函数的语法树以计算出返回的输出数量?

大致如下:

import inspect
import ast

src = inspect.getsourcelines(f1)[0]

string = ''.join(src)
ast_   = ast.parse(string)
Run Code Online (Sandbox Code Playgroud)

我探索过ast_但无法找到回报是什么。

python function abstract-syntax-tree output

2
推荐指数
1
解决办法
1832
查看次数

有没有办法访问手写笔 AST

我需要访问 stylus 生成的 CSS 样式的抽象语法树 (AST),而无需再次解析它(通过 css-parse)。我想知道生成的样式的 AST 是否公开。

css stylus abstract-syntax-tree

2
推荐指数
1
解决办法
308
查看次数

特定节点上的 AST 匹配器

我编写了一个 AST 匹配器来查找特定类型语句。在匹配的节点中,我计算了该节点的邻居兄弟节点。现在我需要在邻居节点上运行匹配器来验证它们是否满足我的条件。clang AST 匹配器将整个树节点一一匹配。我想针对特定节点运行匹配器,如果该节点符合我所需的条件,则返回 true。这可能吗?

matcher clang abstract-syntax-tree

2
推荐指数
1
解决办法
1195
查看次数

LibClang clang_getArgType() 返回错误类型

我尝试使用 libClang 解析 C++ 方法,但是当尝试获取函数的参数/参数时,有时会给出错误的类型。

例子:

我有两种不同的方法

std::string Method::exportMethod(std::map<std::string, std::string> &defines) const
Run Code Online (Sandbox Code Playgroud)

std::string Field::exportField(std::map<std::string, std::string> &defines) const
Run Code Online (Sandbox Code Playgroud)

我打印 AST(用于调试目的)

CXChildVisitResult printer::printVisitor(CXCursor c, CXCursor parent, CXClientData clientData) {
    recursivePrintData data = *static_cast<recursivePrintData *>(clientData);

    *(data.stream) <<
                   data.indent <<
                   clang_getCursorKindSpelling(clang_getCursorKind(c)) <<
                   "; name: " << clang_getCursorSpelling(c) <<
                   ", type: " << clang_getCursorType(c) <<
                   ", arg0Type: " << clang_getArgType(clang_getCursorType(c), 0) <<
                   std::endl;

    recursivePrintData newDat(data);
    data.indent += "    ";

    clang_visitChildren(c, printVisitor, (void *) &data);

    return CXChildVisit_Recurse;
}
Run Code Online (Sandbox Code Playgroud)

(recursivePrintData 是一个包含输出流和当前缩进级别的结构)

对于这两种方法,输出如下:

导出方法:

    CXXMethod; name: exportMethod, …
Run Code Online (Sandbox Code Playgroud)

c++ clang abstract-syntax-tree libclang

2
推荐指数
1
解决办法
522
查看次数

这是 ast 解析的正确行为吗

我正在学习如何使用以及 golang 的 ast 库是如何工作的。我正在解析https://github.com/modern-go/concurrent,避免测试文件和 go_below_19.go 因为它会导致错误。

我的问题是解析文件中的这些行unbounded_executor.go

var HandlePanic = func(recovered interface{}, funcName string) {
    ErrorLogger.Println(fmt.Sprintf("%s panic: %v", funcName, recovered))
    ErrorLogger.Println(string(debug.Stack()))
}
Run Code Online (Sandbox Code Playgroud)

ErrorLogger两个实例中的 ast.Ident都有一个 nil obj。

但是,我认为它不应该是 nil 并且应该引用这些行log.go

// ErrorLogger is used to print out error, can be set to writer other than stderr
var ErrorLogger = log.New(os.Stderr, "", 0)
Run Code Online (Sandbox Code Playgroud)

我错了,还是解析器有问题?我遵循了几个关于解析文件的参考资料,并在每个文件中重用了 *token.FileSet 并使用 ParseComments 作为模式。

编辑:

围绕此有大量代码库,因此演示此内容的代码将包含片段。

这是在所有非测试 go 文件中使用相同的 fset 执行的,没有会阻止代码与 1.16 一起使用的构建限制

parsedFile, parseErr := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
Run Code Online (Sandbox Code Playgroud)

abstract-syntax-tree go

2
推荐指数
1
解决办法
60
查看次数

如何使用 typescript 编译器 api 更新或插入导入?

我使用transformtypescript 编译器 api 中的函数来更改我的代码。

该函数是递归的并访问每个节点。

当我找到一个StringLiteral时,foo我想添加foo到导入位置,my-lib如下所示:

import { foo } from 'my-lib';
Run Code Online (Sandbox Code Playgroud)

该代码可能已经导入了其他内容,my-lib例如:

import { bar } from 'my-lib';
Run Code Online (Sandbox Code Playgroud)

我想避免这种结果(重复导入):

import { foo } from 'my-lib';
import { bar } from 'my-lib';
Run Code Online (Sandbox Code Playgroud)

我能找到的最接近的解决方案是:

const file = (node as ts.Node) as ts.SourceFile;
const update = ts.updateSourceFileNode(file, [
  ts.createImportDeclaration(
    undefined,
    undefined,
    ts.createImportClause(
      undefined,
      ts.createNamedImports([ts.createImportSpecifier(ts.createIdentifier("default"), ts.createIdentifier("salami"))])
    ),
    ts.createLiteral('salami')
  ),
  ...file.statements
]);
Run Code Online (Sandbox Code Playgroud)

但这些功能已被弃用。我无法返回,ts.createImportDeclaration因为我将得到 的而不是的import代码。StringLiteralfoo

是否有一个函数说“将 y …

abstract-syntax-tree typescript

2
推荐指数
1
解决办法
2638
查看次数

Mono.Cecil中的以下结构在C#中引用了什么?

有人会解释这些是指什么?

MemberReference, TypeReference, ExternType, Override, NestedType,
PInvokeInfo, SecurityDeclaration and CustomAttribute and MarshalSpec
Run Code Online (Sandbox Code Playgroud)

如果你能举例说明,那将是理想的.

我正在尝试写一个访客模式Mono.Cecil.

c# mono abstract-syntax-tree visitor-pattern mono.cecil

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

使用eclipse插件将修改后的AST保存在新文件中

我有一个eclipse插件代码来操作项目/工作区中的类(smcho.Hello).我可以创建一个CompilationUnit并对其进行一些修改,但我需要将结果保存在不同的文件中以检查两个版本之间的差异.

这是我获取CompilationUnit的代码.

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject("Hello");
project.open(null);
IJavaProject javaProject = JavaCore.create(project);
IType lwType = javaProject.findType("smcho.Hello");
org.eclipse.jdt.core.ICompilationUnit lwCompilationUnit = lwType.getCompilationUnit();
final ASTParser parser = ASTParser.newParser(AST.JLS3); 
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(lwCompilationUnit);
parser.setResolveBindings(true); // we need bindings later on
CompilationUnit unit = (CompilationUnit) parser.createAST(null /* IProgressMonitor */); 
// modify the unit AST node
Run Code Online (Sandbox Code Playgroud)

如何将此修改后的单元保存到新文件中?

java eclipse eclipse-plugin abstract-syntax-tree eclipse-jdt

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

获得ast的子树

我有一个布尔抽象语法树

type bast =
    True
  | False
  | Not of bast 
  | Or of bast * bast 
  | And of bast * bast 
Run Code Online (Sandbox Code Playgroud)

我想在它上面应用一个函数并获得所有为此函数返回true的子树.

我的尝试:

let findtrees f (ast: bast ) =
    let rec findtree (tree: bast ) (mylist: bast list) = match tree with
        | True ->
            if (f tree)=true then mylist@[tree] else []
        | False ->
            if (f tree)=true then mylist@[tree] else []
        | Not e     ->  Not (findtree e subtrees)
        | And (e1,e2) ->  And (findtree e1 …
Run Code Online (Sandbox Code Playgroud)

ocaml functional-programming abstract-syntax-tree

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