【问题标题】:Is this the correct behavior of ast parsing这是 ast 解析的正确行为吗
【发布时间】:2021-07-03 21:19:09
【问题描述】:

我正在学习如何使用以及如何使用 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()))
}

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)

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

编辑:

围绕这个有一个庞大的代码库,所以演示这个的代码将包括 sn-ps。

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

parsedFile, parseErr := parser.ParseFile(fset, filePath, nil, parser.ParseComments)

【问题讨论】:

  • 您还应该包含您的 ast 代码并演示您是如何解决这个问题的。
  • 调用NewPackage解析id。
  • Type checking ast 可能会有所帮助。
  • @CeriseLimón 就是这样!根据文档It resolves unresolved identifiers across files and updates each file's Unresolved list accordingly。对于任何想知道我使用的代码的人是ast.NewPackage(fset, parsableFiles, nil, nil)

标签: go abstract-syntax-tree


【解决方案1】:

调用 ast.NewPackage 解析 AST 中的标识符:

fset := token.NewFileSet()
files := make(map[string]*ast.File)
for _, name := range []string{"unbounded_executor.go", "log.go"} {
    f, err := parser.ParseFile(fset, name, nil, parser.ParseComments)
    if err != nil {
        log.Fatal(err)
    }
    files[name] = f
}

ast.NewPackage(fset, files, nil, nil)

ast.Inspect(files["unbounded_executor.go"], func(n ast.Node) bool {
    if n, ok := n.(*ast.Ident); ok && n.Name == "ErrorLogger" {
        fmt.Println(n.Obj)
    }
    return true
})

由于没有提供合适的导入器,并且文件列表不包括包中的所有文件,NewPackage 返回未解决的符号错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    相关资源
    最近更新 更多