Пример #1
0
func (g *nfa) ToDot(w io.Writer) {
	tw := tabwriter.NewWriter(w, 4, 8, 1, '\t', 0)
	w.Write([]byte("digraph {\n"))
	for i, _ := range g.Nodes {
		
		fmt.Fprintf(tw, 
			"\tn%d\t[label=\"%d\"",
			i, i)
		
		if i == g.Start {
			fmt.Fprintf(tw, ",style=solid,fillcolor=green")
		}

		if _, ok := g.Accepting[i]; ok {
			fmt.Fprintf(tw, ",color=red")
		}
		fmt.Fprintf(tw, "];\n")
	}
	for i, node := range g.Nodes {
		for label, to_list := range node.Nodes {
			for _, to := range to_list {
				fmt.Fprintf(tw, "\tn%d -> n%d\t[label=%#v];\n",
					i, to, strconv.Quote(string(byte(label))))
			}
		}
		for _, to := range node.Epsilons {
			fmt.Fprintf(tw, "\tn%d -> n%d\t[label=\"eps\"];\n", i, to)
		}
	}
	tw.Flush()
	fmt.Fprintf(w, "}\n")
}
Пример #2
0
// fprint implements Fprint and takes a nodesSizes map for setting up the printer state.
func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node interface{}, nodeSizes map[ast.Node]int) (written int, err error) {
	// redirect output through a trimmer to eliminate trailing whitespace
	// (Input to a tabwriter must be untrimmed since trailing tabs provide
	// formatting information. The tabwriter could provide trimming
	// functionality but no tabwriter is used when RawFormat is set.)
	output = &trimmer{output: output}

	// setup tabwriter if needed and redirect output
	var tw *tabwriter.Writer
	if cfg.Mode&RawFormat == 0 {
		minwidth := cfg.Tabwidth

		padchar := byte('\t')
		if cfg.Mode&UseSpaces != 0 {
			padchar = ' '
		}

		twmode := tabwriter.DiscardEmptyColumns
		if cfg.Mode&TabIndent != 0 {
			minwidth = 0
			twmode |= tabwriter.TabIndent
		}

		tw = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode)
		output = tw
	}

	// setup printer
	var p printer
	p.init(output, cfg, fset, nodeSizes)
	defer func() {
		written = p.written
		if e := recover(); e != nil {
			err = e.(osError).err // re-panics if it's not a local osError
		}
	}()

	// print node
	switch n := node.(type) {
	case ast.Expr:
		p.useNodeComments = true
		p.expr(n, ignoreMultiLine)
	case ast.Stmt:
		p.useNodeComments = true
		// A labeled statement will un-indent to position the
		// label. Set indent to 1 so we don't get indent "underflow".
		if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt {
			p.indent = 1
		}
		p.stmt(n, false, ignoreMultiLine)
	case ast.Decl:
		p.useNodeComments = true
		p.decl(n, ignoreMultiLine)
	case ast.Spec:
		p.useNodeComments = true
		p.spec(n, 1, false, ignoreMultiLine)
	case *ast.File:
		p.comments = n.Comments
		p.useNodeComments = n.Comments == nil
		p.file(n)
	default:
		panic(osError{fmt.Errorf("printer.Fprint: unsupported node type %T", n)})
	}
	p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF)

	// flush tabwriter, if any
	if tw != nil {
		tw.Flush() // ignore errors
	}

	return
}
Пример #3
0
// Fprint "pretty-prints" an AST node to output and returns the number
// of bytes written and an error (if any) for a given configuration cfg.
// Position information is interpreted relative to the file set fset.
// The node type must be *ast.File, or assignment-compatible to ast.Expr,
// ast.Decl, ast.Spec, or ast.Stmt.
//
func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) (int, os.Error) {
	// redirect output through a trimmer to eliminate trailing whitespace
	// (Input to a tabwriter must be untrimmed since trailing tabs provide
	// formatting information. The tabwriter could provide trimming
	// functionality but no tabwriter is used when RawFormat is set.)
	output = &trimmer{output: output}

	// setup tabwriter if needed and redirect output
	var tw *tabwriter.Writer
	if cfg.Mode&RawFormat == 0 {
		minwidth := cfg.Tabwidth

		padchar := byte('\t')
		if cfg.Mode&UseSpaces != 0 {
			padchar = ' '
		}

		twmode := tabwriter.DiscardEmptyColumns
		if cfg.Mode&TabIndent != 0 {
			minwidth = 0
			twmode |= tabwriter.TabIndent
		}

		tw = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode)
		output = tw
	}

	// setup printer and print node
	var p printer
	p.init(output, cfg, fset)
	go func() {
		switch n := node.(type) {
		case ast.Expr:
			p.nesting = 1
			p.useNodeComments = true
			p.expr(n, ignoreMultiLine)
		case ast.Stmt:
			p.nesting = 1
			p.useNodeComments = true
			// A labeled statement will un-indent to position the
			// label. Set indent to 1 so we don't get indent "underflow".
			if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt {
				p.indent = 1
			}
			p.stmt(n, false, ignoreMultiLine)
		case ast.Decl:
			p.nesting = 1
			p.useNodeComments = true
			p.decl(n, ignoreMultiLine)
		case ast.Spec:
			p.nesting = 1
			p.useNodeComments = true
			p.spec(n, 1, false, ignoreMultiLine)
		case *ast.File:
			p.nesting = 0
			p.comments = n.Comments
			p.useNodeComments = n.Comments == nil
			p.file(n)
		default:
			p.errors <- fmt.Errorf("printer.Fprint: unsupported node type %T", n)
			runtime.Goexit()
		}
		p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF)
		p.errors <- nil // no errors
	}()
	err := <-p.errors // wait for completion of goroutine

	// flush tabwriter, if any
	if tw != nil {
		tw.Flush() // ignore errors
	}

	return p.written, err
}
Пример #4
0
func main() {
	usage()
	tabw := tabwriter.NewWriter(os.Stdout, 1, 8, '\t', 0)
	io.Copy(tabw, os.Stdin)
}
Пример #5
0
// Expand all variables in Vars within the given string.  This does
// not assume any prefix or suffix that sets off a variable from the
// rest of the text, so a var of A set to HI expanded into HAPPY will
// become HHIPPY.
func Expand(x string) string {
	for k, v := range Vars {
		x = strings.Join(strings.Split(x, k), v)
	}
	return x
}

// Override the way help is displayed (not recommended)
var Help = func() string {
	h0 := new(bytes.Buffer)
	h := tabwriter.NewWriter(h0, 0, 8, 2, ' ', 0)
	if len(opts) > 1 {
		fmt.Fprintln(h, "Options:")
	}
	for _, o := range opts {
		fmt.Fprint(h, "  ")
		if len(o.shortnames) > 0 {
			for _, sn := range o.shortnames[0 : len(o.shortnames)-1] {
				fmt.Fprintf(h, "-%c, ", sn)
			}
			fmt.Fprintf(h, "-%c", o.shortnames[len(o.shortnames)-1])
			if o.allowsArg != nil {
				fmt.Fprintf(h, " %s", *o.allowsArg)
			}
		}
		fmt.Fprintf(h, "\t")