dsc56927 2015-02-24 00:04
浏览 36
已采纳

如何打印手写AST?

I have a set of XML description of network protocol that I'm trying to generate Go code from, therefore I don't have any existing Go code to work with. All of the examples that make use of go/ast (such as go fmt) take existing code, do some transformation on the AST, then write them back out. Since all I have are XML files, the AST that I'm working with have to be written by hand. The problem is that I cannot get my hand-written AST to output.

Example

package main

import (
    "go/ast"
    "go/printer"
    "go/token"
    "os"
)

func main() {
    f := ast.File{
        Name: ast.NewIdent("foo"),
        Decls: []ast.Decl{
            &ast.GenDecl{
                Tok: token.TYPE,
                Specs: []ast.Spec{
                    &ast.TypeSpec{
                        Name: ast.NewIdent("Bar"),
                        Type: ast.NewIdent("uint32"),
                    },
                },
            },
        },
    }
    fset := token.NewFileSet()
    printer.Fprint(os.Stdout, fset, f)
}

Expected output:

package foo

type Bar uint32

Actual output: nothing

How do I get the AST to print?

  • 写回答

1条回答 默认 最新

  • dongshuang0011 2015-02-24 03:38
    关注

    Don't ignore errors!

    Adding:

    err := printer.Fprint(os.Stdout, fset, f)
    if err != nil {
        log.Fatal(err)
    }
    

    Gives: "go/printer: unsupported node type ast.File" which should have been enough to point you in the right direction.

    printer.Fprint's last argument is interface{} so the compiler accepts anything. However, just as parser.ParseFile returns an *ast.File (rather than ast.File) it expects a pointer to a node.

    Passing a pointer gives the output you want (note the &ast.File):

    package main
    
    import (
        "go/ast"
        "go/printer"
        "go/token"
        "log"
        "os"
    )
    
    func main() {
        f := &ast.File{
            Name: ast.NewIdent("foo"),
            Decls: []ast.Decl{
                &ast.GenDecl{
                    Tok: token.TYPE,
                    Specs: []ast.Spec{
                        &ast.TypeSpec{
                            Name: ast.NewIdent("Bar"),
                            Type: ast.NewIdent("uint32"),
                        },
                    },
                },
            },
        }
        fset := token.NewFileSet()
        err := printer.Fprint(os.Stdout, fset, f)
        if err != nil {
            log.Fatal(err)
        }
    }
    

    <kbd>playground</kbd>

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!