pretty print parse tree

master
Jordan Orelli 10 years ago
parent d135ad30c5
commit 0820a130e5

@ -7,16 +7,68 @@ import (
"os" "os"
) )
func check(r io.Reader) { func input() io.ReadCloser {
if flag.Arg(1) == "" {
return os.Stdin
} else {
f, err := os.Open(flag.Arg(1))
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
return f
}
}
func check() {
r := input()
defer r.Close()
_, err := parse(r) _, err := parse(r)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err) fmt.Fprintf(os.Stderr, "%s\n", err)
} }
} }
func lexx() {
r := input()
defer r.Close()
c := lex(r)
for t := range c {
fmt.Println(t)
}
}
func parsse() {
r := input()
defer r.Close()
n, err := parse(r)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s", err)
os.Exit(1)
}
if err := n.pretty(os.Stdout, ""); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
}
func main() { func main() {
flag.Parse() flag.Parse()
if flag.NArg() == 0 { switch flag.Arg(0) {
check(os.Stdin) case "check":
check()
case "lex":
lexx()
case "parse":
parsse()
case "":
fmt.Fprintf(os.Stderr, "specify an action (check)\n")
os.Exit(1)
default:
fmt.Fprintf(os.Stderr, "no such action: %s\n", flag.Arg(0))
os.Exit(1)
} }
} }

@ -1,8 +1,11 @@
package main package main
import ( import (
"bufio"
"bytes" "bytes"
"fmt" "fmt"
"io"
"strings"
) )
type nodeType int type nodeType int
@ -14,9 +17,12 @@ const (
n_assignment n_assignment
) )
var indent = " "
type node interface { type node interface {
Type() nodeType Type() nodeType
parse(*parser) error parse(*parser) error
pretty(io.Writer, string) error
} }
type rootNode struct { type rootNode struct {
@ -73,6 +79,17 @@ func (n *rootNode) String() string {
return buf.String() return buf.String()
} }
func (n *rootNode) pretty(w io.Writer, prefix string) error {
fmt.Fprintf(w, "%sroot{\n", prefix)
for _, child := range n.children {
if err := child.pretty(w, prefix+indent); err != nil {
return err
}
}
fmt.Fprintf(w, "%s}\n", prefix)
return nil
}
type commentNode struct { type commentNode struct {
body string body string
} }
@ -89,6 +106,26 @@ func (n *commentNode) String() string {
return fmt.Sprintf("{comment: %s}", n.body) return fmt.Sprintf("{comment: %s}", n.body)
} }
func (n *commentNode) pretty(w io.Writer, prefix string) error {
r := bufio.NewReader(strings.NewReader(n.body))
fmt.Fprintf(w, "%scomment{\n", prefix)
for {
line, err := r.ReadString('\n')
if err == io.EOF {
if line != "" {
fmt.Fprintf(w, "%s%s%s\n", prefix, indent, line)
}
break
}
if err != nil {
return err
}
fmt.Fprintf(w, "%s%s%s\n", prefix, indent, line)
}
fmt.Fprintf(w, "%s}\n", prefix)
return nil
}
type assignmentNode struct { type assignmentNode struct {
name string name string
value interface{} value interface{}
@ -122,5 +159,13 @@ func (n *assignmentNode) String() string {
return fmt.Sprintf("{assign: name=%s, val=%v}", n.name, n.value) return fmt.Sprintf("{assign: name=%s, val=%v}", n.name, n.value)
} }
func (n *assignmentNode) pretty(w io.Writer, prefix string) error {
fmt.Fprintf(w, "%sassign{\n", prefix)
fmt.Fprintf(w, "%s%sname: %s\n", prefix, indent, n.name)
fmt.Fprintf(w, "%s%svalue: %v\n", prefix, indent, n.value)
fmt.Fprintf(w, "%s}\n", prefix)
return nil
}
type list []interface{} type list []interface{}
type object map[string]interface{} type object map[string]interface{}

Loading…
Cancel
Save