Is there any sample code to generate AST output with xml format

I’m trying to generate the AST for go source code, and I tried the package “go/ast” and “go/parser” but the output was really hard to use. So I am wondering if anyone has any advice to convert the original AST date to xml or json format?

I am not sure I understand your question.

Once that you have a ast.File object, you can just pass it to json.Marshall and get the JSON representation.

What do you want to do with the AST?

Hi Lotti,
Thanks for your reply, in fact, I just want to save the AST data for further analyzing. XML would be helpful since we have existing tools to apply XML formatted AST.
I tried your suggestion, but failed with below simple code(fatal error: stack overflow), could you advise?

package main

import (
    "go/parser"
    "go/token"
    "encoding/json"
    "fmt"
)

func main() {
    name :="./hello.go"

    fset := token.NewFileSet() // positions are relative to fset
    f, err := parser.ParseFile(fset, name, nil, 0)
    if err != nil {
        panic(err)
    }

    jsonout, err := json.Marshal(f)
    fmt.Println("### print the json output ###")
    fmt.Println(string(jsonout))
}

I am very new for golang, so any advice would be helpful.

I am confused by the generated ast.File, and the format is not json or xml at all:

 0  *ast.File {
 1  .  Package: /Users/my/workspace/go/test/hello.go:1:1
 2  .  Name: *ast.Ident {
 3  .  .  NamePos: /Users/my/workspace/go/test/hello.go:1:9
 4  .  .  Name: "main"
 5  .  }
 6  .  Decls: []ast.Decl (len = 2) {
 7  .  .  0: *ast.GenDecl {
 8  .  .  .  TokPos: /Users/my/workspace/go/test/hello.go:3:1
 9  .  .  .  Tok: import
10  .  .  .  Lparen: -
11  .  .  .  Specs: []ast.Spec (len = 1) {
12  .  .  .  .  0: *ast.ImportSpec {
13  .  .  .  .  .  Path: *ast.BasicLit {
14  .  .  .  .  .  .  ValuePos: /Users/my/workspace/go/test/hello.go:3:8
15  .  .  .  .  .  .  Kind: STRING
16  .  .  .  .  .  .  Value: "\"fmt\""
17  .  .  .  .  .  }
18  .  .  .  .  .  EndPos: -
19  .  .  .  .  }
20  .  .  .  }
21  .  .  .  Rparen: -
22  .  .  }
23  .  .  1: *ast.FuncDecl {
24  .  .  .  Name: *ast.Ident {
25  .  .  .  .  NamePos: /Users/my/workspace/go/test/hello.go:5:6
26  .  .  .  .  Name: "main"
27  .  .  .  .  Obj: *ast.Object {
28  .  .  .  .  .  Kind: func
29  .  .  .  .  .  Name: "main"
30  .  .  .  .  .  Decl: *(obj @ 23)
31  .  .  .  .  }
32  .  .  .  }
33  .  .  .  Type: *ast.FuncType {
34  .  .  .  .  Func: /Users/my/workspace/go/test/hello.go:5:1
35  .  .  .  .  Params: *ast.FieldList {
36  .  .  .  .  .  Opening: /Users/my/workspace/go/test/hello.go:5:10
37  .  .  .  .  .  Closing: /Users/my/workspace/go/test/hello.go:5:11
38  .  .  .  .  }
39  .  .  .  }
40  .  .  .  Body: *ast.BlockStmt {
41  .  .  .  .  Lbrace: /Users/my/workspace/go/test/hello.go:5:13
42  .  .  .  .  List: []ast.Stmt (len = 1) {
43  .  .  .  .  .  0: *ast.ExprStmt {
44  .  .  .  .  .  .  X: *ast.CallExpr {
45  .  .  .  .  .  .  .  Fun: *ast.SelectorExpr {
46  .  .  .  .  .  .  .  .  X: *ast.Ident {
47  .  .  .  .  .  .  .  .  .  NamePos: /Users/my/workspace/go/test/hello.go:6:4
48  .  .  .  .  .  .  .  .  .  Name: "fmt"
49  .  .  .  .  .  .  .  .  }
50  .  .  .  .  .  .  .  .  Sel: *ast.Ident {
51  .  .  .  .  .  .  .  .  .  NamePos: /Users/my/workspace/go/test/hello.go:6:8
52  .  .  .  .  .  .  .  .  .  Name: "Println"
53  .  .  .  .  .  .  .  .  }
54  .  .  .  .  .  .  .  }
55  .  .  .  .  .  .  .  Lparen: /Users/my/workspace/go/test/hello.go:6:15
56  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
57  .  .  .  .  .  .  .  .  0: *ast.BasicLit {
58  .  .  .  .  .  .  .  .  .  ValuePos: /Users/my/workspace/go/test/hello.go:6:16
59  .  .  .  .  .  .  .  .  .  Kind: STRING
60  .  .  .  .  .  .  .  .  .  Value: "\"Hello, World!\""
61  .  .  .  .  .  .  .  .  }
62  .  .  .  .  .  .  .  }
63  .  .  .  .  .  .  .  Ellipsis: -
64  .  .  .  .  .  .  .  Rparen: /Users/my/workspace/go/test/hello.go:6:32
65  .  .  .  .  .  .  }
66  .  .  .  .  .  }
67  .  .  .  .  }
68  .  .  .  .  Rbrace: /Users/my/workspace/go/test/hello.go:7:1
69  .  .  .  }
70  .  .  }
71  .  }
72  .  Scope: *ast.Scope {
73  .  .  Objects: map[string]*ast.Object (len = 1) {
74  .  .  .  "main": *(obj @ 27)
75  .  .  }
76  .  }
77  .  Imports: []*ast.ImportSpec (len = 1) {
78  .  .  0: *(obj @ 12)
79  .  }
80  .  Unresolved: []*ast.Ident (len = 1) {
81  .  .  0: *(obj @ 46)
82  .  }
83  }

it include the line number and some ‘.’ for format usage, any advice to convert the above AST data to json or xml?

I do not understand why you need to store AST, but this POST is interesting and maybe it might help you:

https://zupzup.org/ast-manipulation-go/

Thanks for your reply Lucas, but that POST does not work for my request. I still can’t convert the origin data format to XML.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.