PageRenderTime 34ms CodeModel.GetById 19ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/parser/parser_redux.go

https://code.google.com/p/gosandbox/
Go | 190 lines | 149 code | 22 blank | 19 comment | 15 complexity | cb42ee02e4d008b808137a923f51f338 MD5 | raw file
  1// Reference:
  2// -http://golang.org/src/pkg/go/ast/ast.go
  3// -http://golang.org/src/pkg/go/ast/walk.go 
  4
  5package main
  6
  7import (
  8	"go/ast"
  9	"go/parser"
 10	"go/token"
 11	"fmt"
 12	"flag"
 13	"os"
 14	"reflect"
 15	"strings"
 16)
 17
 18// Avoid typing "fmt.Printf("...\n", ...) every time
 19func printf(format string, v ...interface{}) (n int, errno os.Error) {
 20	return fmt.Printf(format + "\n", v...)
 21}
 22
 23// Visitor for ast.Walk
 24type printVisitor struct {
 25	weight float
 26        priorWeight float
 27}
 28
 29func (f *printVisitor) Visit(node ast.Node) ast.Visitor {
 30
 31	if node == nil {
 32		return f
 33	}
 34
 35	typ := reflect.NewValue(node).Type().String()
 36	// Get rid of redundant package prefix
 37	typ = strings.Split(typ, ".", -1)[1]
 38
 39	w := 1.0
 40	// If statement then add weight
 41	if strings.Contains(typ, "Stmt") {
 42		w = f.weight
 43	}
 44	if strings.Contains(typ, "CaseClause") || strings.Contains(typ, "CommClause") {
 45		w = f.priorWeight
 46	}
 47	printf("%s: %f", typ, w)
 48	printf("%s.Pos: %d", typ, node.Pos()) // All nodes have Pos accessor method
 49
 50	// 3 classes of nodes: Expression & type nodes,
 51	// statement nodes, and declaration nodes
 52	switch n := node.(type) {
 53
 54	// Comments
 55	case *ast.Comment:
 56		printf("%s.Text.Length: %d", typ, len(n.Text))
 57	case *ast.CommentGroup:
 58		printf("%s.List.Length: %d", typ, len(n.List))
 59
 60	// Expressions
 61	case *ast.Field:
 62		printf("%s.Names.Length: %d", typ, len(n.Names))
 63	case *ast.FieldList:
 64		printf("%s.List.Length: %d", typ, len(n.List))
 65		printf("%s.Closing: %d", typ, n.Closing)
 66		printf("%s.NumFields: %d", typ, n.NumFields())
 67	case *ast.Ident:
 68		printf("%s.Name.Length: %d", typ, len(n.Name))
 69	case *ast.CompositeLit:
 70		printf("%s.Lbrace: %d", typ, n.Lbrace)
 71		printf("%s.Elts.Length: %d", typ, len(n.Elts))
 72		printf("%s.Rbrace: %d", typ, n.Rbrace)
 73	case *ast.ParenExpr:
 74		printf("%s.Lparen: %d", typ, n.Lparen)
 75		printf("%s.Rparen: %d", typ, n.Rparen)
 76	case *ast.CallExpr:
 77		printf("%s.Lparen: %d", typ, n.Lparen)
 78		printf("%s.Args.Length: %d", typ, len(n.Args))
 79		printf("%s.Ellipsis: %d", typ, n.Ellipsis)
 80		printf("%s.Rparen: %d", typ, n.Rparen)
 81	case *ast.KeyValueExpr:
 82		printf("%s.Colon: %d", typ, n.Colon)
 83	case *ast.BinaryExpr:
 84		fmt.Println("Binary expression")
 85
 86	// Types
 87	case *ast.StructType:
 88		printf("%s.Fields.Length: %d", typ, len(n.Fields.List))
 89	case *ast.FuncType:
 90		printf("%s.Params.Length: %d", typ, n.Params.NumFields())
 91		printf("%s.Results.Length: %d", typ, n.Results.NumFields())
 92	case *ast.InterfaceType:
 93		printf("%s.Methods.Length: %d", typ, len(n.Methods.List))
 94
 95	// Statements
 96	case *ast.AssignStmt:
 97		printf("%s.Lhs.Length: %d", typ, len(n.Lhs))
 98		// Usage of "=" vs. ":="
 99		if n.Tok == token.DEFINE {
100			printf("%s.Tok.DEFINE: 1", typ)
101			return f
102		}
103		printf("%s.Tok.ASSIGN: 1", typ)
104	case *ast.ReturnStmt:
105		printf("%s.Results.Length: %d", typ, len(n.Results))
106	case *ast.BlockStmt:
107		printf("%s.Lbrace: %d", typ, n.Lbrace)
108		printf("%s.List.Length: %d", typ, len(n.List))
109		printf("%s.Rbrace: %d", typ, n.Rbrace)
110	case *ast.CaseClause:
111		printf("%s.Colon: %d", typ, n.Colon)
112		printf("%s.Body.Length: %d", typ, len(n.Body))
113	case *ast.TypeCaseClause:
114		printf("%s.Types.Length: %d", typ, len(n.Types))
115		printf("%s.Colon: %d", typ, n.Colon)
116		printf("%s.Body.Length: %d", typ, len(n.Body))
117	case *ast.CommClause:
118		printf("%s.Colon: %d", typ, n.Colon)
119		printf("%s.Body.Length: %d", typ, len(n.Body))
120	// Handle weighting
121	case *ast.IfStmt:
122		var t printVisitor
123		t.weight = f.weight/2
124		t.priorWeight = f.weight
125		return &t
126	case *ast.SwitchStmt:
127	case *ast.SelectStmt:
128	case *ast.TypeSwitchStmt:
129		numCases := len(n.Body.List)
130		var t printVisitor
131		t.weight = f.weight/float(numCases)
132		t.priorWeight = f.weight
133		return &t
134
135	// Declarations
136	case *ast.ValueSpec:
137		printf("%s.Names.Length: %d", typ, len(n.Names))
138	case *ast.GenDecl:
139		printf("%s.Lparen: %d", typ, n.Lparen)
140		printf("%s.Rparen: %d", typ, n.Rparen)
141	case *ast.FuncDecl:
142		if n.Recv != nil {
143			printf("%s.Recv", typ)
144		}
145		printf("%s.Name.Length: %d", typ, len(n.Name.Name))
146		printf("%s.Body.List.Length: %d", typ, len(n.Body.List))
147
148	// Files & packages?
149
150	default:
151		return f
152
153	} // End cases
154
155	return f
156}
157
158
159// File size in kB of a file
160func size(name string) int64 {
161	file, _ := os.Open(name, os.O_RDONLY, 0)
162	defer file.Close()
163	var buf [100]byte
164	len := 0
165	for {
166		n, e := file.Read(buf[0:])
167		len += n
168		if e == os.EOF {
169			break
170		}
171	}
172	return int64(len)
173}
174
175
176func main() {
177	flag.Parse()
178	filename := flag.Arg(0)
179	file, err := parser.ParseFile(token.NewFileSet(), filename, nil, 0)
180	if err != nil {
181		fmt.Println(filename + "\t" + err.String())
182		return
183	}
184	fmt.Printf("FileSizeKB: %d\n", size(filename)/1000)
185	// Instance
186	var f printVisitor
187	f.weight = 1
188        f.priorWeight = 1
189	ast.Walk(&f, file)
190}