This commit is contained in:
Lucas Serven
2019-01-18 02:50:10 +01:00
commit e989f0a25f
1789 changed files with 680059 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
before_install:
- ./install-godeps.sh
script:
- make travis
language: go
go:
- 1.8

15
vendor/github.com/awalterschulze/gographviz/AUTHORS generated vendored Normal file
View File

@@ -0,0 +1,15 @@
# This is the official list of GoGraphviz authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS file, which
# lists people. For example, employees are listed in CONTRIBUTORS,
# but not in AUTHORS, because the employer holds the copyright.
# Names should be added to this file as one of
# Organization's name
# Individual's name <submission email address>
# Individual's name <submission email address> <email2> <emailN>
# Please keep the list sorted.
Vastech SA (PTY) LTD
Xavier Chassin <xavier.chassin@live.fr>
Walter Schulze <awalterschulze@gmail.com>

View File

@@ -0,0 +1,5 @@
Robin Eklind <r.eklind.87@gmail.com>
Walter Schulze <awalterschulze@gmail.com>
Xuanyi Chew <chewxy@gmail.com>
Nathan Kitchen <nathan.kitchen@gmail.com>
Ruud Kamphuis <https://github.com/ruudk>

46
vendor/github.com/awalterschulze/gographviz/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,46 @@
Copyright 2013 GoGraphviz Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------------------
Portions of gocc's source code has been derived from Go, and are covered by the
following license:
-------------------------------------------------------------------------------
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

16
vendor/github.com/awalterschulze/gographviz/Makefile generated vendored Normal file
View File

@@ -0,0 +1,16 @@
regenerate:
go install github.com/goccmack/gocc
gocc -zip -o ./internal/ dot.bnf
find . -type f -name '*.go' | xargs goimports -w
test:
go test ./...
travis:
make regenerate
go build ./...
go test ./...
errcheck -ignore 'fmt:[FS]?[Pp]rint*' ./...
gofmt -l -s -w .
golint -set_exit_status
git diff --exit-code

39
vendor/github.com/awalterschulze/gographviz/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,39 @@
Parses the Graphviz DOT language and creates an interface, in golang, with which to easily create new and manipulate existing graphs which can be written back to the DOT format.
This parser has been created using [gocc](http://code.google.com/p/gocc).
### Example (Parse and Edit) ###
```
graphAst, _ := gographviz.ParseString(`digraph G {}`)
graph := gographviz.NewGraph()
if err := gographviz.Analyse(graphAst, graph); err != nil {
panic(err)
}
graph.AddNode("G", "a", nil)
graph.AddNode("G", "b", nil)
graph.AddEdge("a", "b", true, nil)
output := graph.String()
```
### Documentation ###
The [godoc](https://godoc.org/github.com/awalterschulze/gographviz) includes some more examples.
### Installation ###
go get github.com/awalterschulze/gographviz
### Tests ###
[![Build Status](https://travis-ci.org/awalterschulze/gographviz.svg?branch=master)](https://travis-ci.org/awalterschulze/gographviz)
### Users ###
- [aptly](https://github.com/smira/aptly) - Debian repository management tool
- [gorgonia](https://github.com/chewxy/gorgonia) - A Library that helps facilitate machine learning in Go
- [imagemonkey](https://imagemonkey.io/graph?editor=true) - Let's create our own image dataset
- [depviz](https://github.com/moul/depviz) - GitHub dependency visualizer (auto-roadmap)
### Mentions ###
[Using Golang and GraphViz to Visualize Complex Grails Applications](http://ilikeorangutans.github.io/2014/05/03/using-golang-and-graphviz-to-visualize-complex-grails-applications/)

188
vendor/github.com/awalterschulze/gographviz/analyse.go generated vendored Normal file
View File

@@ -0,0 +1,188 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"github.com/awalterschulze/gographviz/ast"
)
// NewAnalysedGraph creates a Graph structure by analysing an Abstract Syntax Tree representing a parsed graph.
func NewAnalysedGraph(graph *ast.Graph) (*Graph, error) {
g := NewGraph()
if err := Analyse(graph, g); err != nil {
return nil, err
}
return g, nil
}
// Analyse analyses an Abstract Syntax Tree representing a parsed graph into a newly created graph structure Interface.
func Analyse(graph *ast.Graph, g Interface) error {
gerr := newErrCatcher(g)
graph.Walk(&graphVisitor{gerr})
return gerr.getError()
}
type nilVisitor struct {
}
func (w *nilVisitor) Visit(v ast.Elem) ast.Visitor {
return w
}
type graphVisitor struct {
g errInterface
}
func (w *graphVisitor) Visit(v ast.Elem) ast.Visitor {
graph, ok := v.(*ast.Graph)
if !ok {
return w
}
w.g.SetStrict(graph.Strict)
w.g.SetDir(graph.Type == ast.DIGRAPH)
graphName := graph.ID.String()
w.g.SetName(graphName)
return newStmtVisitor(w.g, graphName, nil, nil)
}
func newStmtVisitor(g errInterface, graphName string, nodeAttrs, edgeAttrs map[string]string) *stmtVisitor {
nodeAttrs = ammend(make(map[string]string), nodeAttrs)
edgeAttrs = ammend(make(map[string]string), edgeAttrs)
return &stmtVisitor{g, graphName, nodeAttrs, edgeAttrs, make(map[string]string), make(map[string]struct{})}
}
type stmtVisitor struct {
g errInterface
graphName string
currentNodeAttrs map[string]string
currentEdgeAttrs map[string]string
currentGraphAttrs map[string]string
createdNodes map[string]struct{}
}
func (w *stmtVisitor) Visit(v ast.Elem) ast.Visitor {
switch s := v.(type) {
case ast.NodeStmt:
return w.nodeStmt(s)
case ast.EdgeStmt:
return w.edgeStmt(s)
case ast.NodeAttrs:
return w.nodeAttrs(s)
case ast.EdgeAttrs:
return w.edgeAttrs(s)
case ast.GraphAttrs:
return w.graphAttrs(s)
case *ast.SubGraph:
return w.subGraph(s)
case *ast.Attr:
return w.attr(s)
case ast.AttrList:
return &nilVisitor{}
default:
//fmt.Fprintf(os.Stderr, "unknown stmt %T\n", v)
}
return w
}
func ammend(attrs map[string]string, add map[string]string) map[string]string {
for key, value := range add {
if _, ok := attrs[key]; !ok {
attrs[key] = value
}
}
return attrs
}
func overwrite(attrs map[string]string, overwrite map[string]string) map[string]string {
for key, value := range overwrite {
attrs[key] = value
}
return attrs
}
func (w *stmtVisitor) addNodeFromEdge(nodeID string) {
if _, ok := w.createdNodes[nodeID]; !ok {
w.createdNodes[nodeID] = struct{}{}
w.g.AddNode(w.graphName, nodeID, w.currentNodeAttrs)
}
}
func (w *stmtVisitor) nodeStmt(stmt ast.NodeStmt) ast.Visitor {
nodeID := stmt.NodeID.String()
var defaultAttrs map[string]string
if _, ok := w.createdNodes[nodeID]; !ok {
defaultAttrs = w.currentNodeAttrs
w.createdNodes[nodeID] = struct{}{}
}
// else the defaults were already inherited
attrs := ammend(stmt.Attrs.GetMap(), defaultAttrs)
w.g.AddNode(w.graphName, nodeID, attrs)
return &nilVisitor{}
}
func (w *stmtVisitor) edgeStmt(stmt ast.EdgeStmt) ast.Visitor {
attrs := stmt.Attrs.GetMap()
attrs = ammend(attrs, w.currentEdgeAttrs)
src := stmt.Source.GetID()
srcName := src.String()
if stmt.Source.IsNode() {
w.addNodeFromEdge(srcName)
}
srcPort := stmt.Source.GetPort()
for i := range stmt.EdgeRHS {
directed := bool(stmt.EdgeRHS[i].Op)
dst := stmt.EdgeRHS[i].Destination.GetID()
dstName := dst.String()
if stmt.EdgeRHS[i].Destination.IsNode() {
w.addNodeFromEdge(dstName)
}
dstPort := stmt.EdgeRHS[i].Destination.GetPort()
w.g.AddPortEdge(srcName, srcPort.String(), dstName, dstPort.String(), directed, attrs)
src = dst
srcPort = dstPort
srcName = dstName
}
return w
}
func (w *stmtVisitor) nodeAttrs(stmt ast.NodeAttrs) ast.Visitor {
w.currentNodeAttrs = overwrite(w.currentNodeAttrs, ast.AttrList(stmt).GetMap())
return &nilVisitor{}
}
func (w *stmtVisitor) edgeAttrs(stmt ast.EdgeAttrs) ast.Visitor {
w.currentEdgeAttrs = overwrite(w.currentEdgeAttrs, ast.AttrList(stmt).GetMap())
return &nilVisitor{}
}
func (w *stmtVisitor) graphAttrs(stmt ast.GraphAttrs) ast.Visitor {
attrs := ast.AttrList(stmt).GetMap()
for key, value := range attrs {
w.g.AddAttr(w.graphName, key, value)
}
w.currentGraphAttrs = overwrite(w.currentGraphAttrs, attrs)
return &nilVisitor{}
}
func (w *stmtVisitor) subGraph(stmt *ast.SubGraph) ast.Visitor {
subGraphName := stmt.ID.String()
w.g.AddSubGraph(w.graphName, subGraphName, w.currentGraphAttrs)
return newStmtVisitor(w.g, subGraphName, w.currentNodeAttrs, w.currentEdgeAttrs)
}
func (w *stmtVisitor) attr(stmt *ast.Attr) ast.Visitor {
w.g.AddAttr(w.graphName, stmt.Field.String(), stmt.Value.String())
return w
}

684
vendor/github.com/awalterschulze/gographviz/ast/ast.go generated vendored Normal file
View File

@@ -0,0 +1,684 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//Abstract Syntax Tree representing the DOT grammar
package ast
import (
"errors"
"fmt"
"math/rand"
"sort"
"strings"
"github.com/awalterschulze/gographviz/internal/token"
)
var (
r = rand.New(rand.NewSource(1234))
)
type Visitor interface {
Visit(e Elem) Visitor
}
type Elem interface {
String() string
}
type Walkable interface {
Walk(v Visitor)
}
type Attrib interface{}
type Bool bool
const (
FALSE = Bool(false)
TRUE = Bool(true)
)
func (this Bool) String() string {
if this {
return "true"
}
return "false"
}
func (this Bool) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type GraphType bool
const (
GRAPH = GraphType(false)
DIGRAPH = GraphType(true)
)
func (this GraphType) String() string {
if this {
return "digraph"
}
return "graph"
}
func (this GraphType) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type Graph struct {
Type GraphType
Strict bool
ID ID
StmtList StmtList
}
func NewGraph(t, strict, id, l Attrib) (*Graph, error) {
g := &Graph{Type: t.(GraphType), Strict: bool(strict.(Bool)), ID: ID("")}
if id != nil {
g.ID = id.(ID)
}
if l != nil {
g.StmtList = l.(StmtList)
}
return g, nil
}
func (this *Graph) String() string {
var s string
if this.Strict {
s += "strict "
}
s += this.Type.String() + " " + this.ID.String() + " {\n"
if this.StmtList != nil {
s += this.StmtList.String()
}
s += "\n}\n"
return s
}
func (this *Graph) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Type.Walk(v)
this.ID.Walk(v)
this.StmtList.Walk(v)
}
type StmtList []Stmt
func NewStmtList(s Attrib) (StmtList, error) {
ss := make(StmtList, 1)
ss[0] = s.(Stmt)
return ss, nil
}
func AppendStmtList(ss, s Attrib) (StmtList, error) {
this := ss.(StmtList)
this = append(this, s.(Stmt))
return this, nil
}
func (this StmtList) String() string {
if len(this) == 0 {
return ""
}
s := ""
for i := 0; i < len(this); i++ {
ss := this[i].String()
if len(ss) > 0 {
s += "\t" + ss + ";\n"
}
}
return s
}
func (this StmtList) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type Stmt interface {
Elem
Walkable
isStmt()
}
func (this NodeStmt) isStmt() {}
func (this EdgeStmt) isStmt() {}
func (this EdgeAttrs) isStmt() {}
func (this NodeAttrs) isStmt() {}
func (this GraphAttrs) isStmt() {}
func (this *SubGraph) isStmt() {}
func (this *Attr) isStmt() {}
type SubGraph struct {
ID ID
StmtList StmtList
}
func NewSubGraph(id, l Attrib) (*SubGraph, error) {
g := &SubGraph{ID: ID(fmt.Sprintf("anon%d", r.Int63()))}
if id != nil {
if len(id.(ID)) > 0 {
g.ID = id.(ID)
}
}
if l != nil {
g.StmtList = l.(StmtList)
}
return g, nil
}
func (this *SubGraph) GetID() ID {
return this.ID
}
func (this *SubGraph) GetPort() Port {
return NewPort(nil, nil)
}
func (this *SubGraph) String() string {
gName := this.ID.String()
if strings.HasPrefix(gName, "anon") {
gName = ""
}
s := "subgraph " + this.ID.String() + " {\n"
if this.StmtList != nil {
s += this.StmtList.String()
}
s += "\n}\n"
return s
}
func (this *SubGraph) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.ID.Walk(v)
this.StmtList.Walk(v)
}
type EdgeAttrs AttrList
func NewEdgeAttrs(a Attrib) (EdgeAttrs, error) {
return EdgeAttrs(a.(AttrList)), nil
}
func (this EdgeAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `edge ` + s
}
func (this EdgeAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type NodeAttrs AttrList
func NewNodeAttrs(a Attrib) (NodeAttrs, error) {
return NodeAttrs(a.(AttrList)), nil
}
func (this NodeAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `node ` + s
}
func (this NodeAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type GraphAttrs AttrList
func NewGraphAttrs(a Attrib) (GraphAttrs, error) {
return GraphAttrs(a.(AttrList)), nil
}
func (this GraphAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `graph ` + s
}
func (this GraphAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type AttrList []AList
func NewAttrList(a Attrib) (AttrList, error) {
as := make(AttrList, 0)
if a != nil {
as = append(as, a.(AList))
}
return as, nil
}
func AppendAttrList(as, a Attrib) (AttrList, error) {
this := as.(AttrList)
if a == nil {
return this, nil
}
this = append(this, a.(AList))
return this, nil
}
func (this AttrList) String() string {
s := ""
for _, alist := range this {
ss := alist.String()
if len(ss) > 0 {
s += "[ " + ss + " ] "
}
}
if len(s) == 0 {
return ""
}
return s
}
func (this AttrList) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
func PutMap(attrmap map[string]string) AttrList {
attrlist := make(AttrList, 1)
attrlist[0] = make(AList, 0)
keys := make([]string, 0, len(attrmap))
for key := range attrmap {
keys = append(keys, key)
}
sort.Strings(keys)
for _, name := range keys {
value := attrmap[name]
attrlist[0] = append(attrlist[0], &Attr{ID(name), ID(value)})
}
return attrlist
}
func (this AttrList) GetMap() map[string]string {
attrs := make(map[string]string)
for _, alist := range this {
for _, attr := range alist {
attrs[attr.Field.String()] = attr.Value.String()
}
}
return attrs
}
type AList []*Attr
func NewAList(a Attrib) (AList, error) {
as := make(AList, 1)
as[0] = a.(*Attr)
return as, nil
}
func AppendAList(as, a Attrib) (AList, error) {
this := as.(AList)
attr := a.(*Attr)
this = append(this, attr)
return this, nil
}
func (this AList) String() string {
if len(this) == 0 {
return ""
}
str := this[0].String()
for i := 1; i < len(this); i++ {
str += `, ` + this[i].String()
}
return str
}
func (this AList) Walk(v Visitor) {
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type Attr struct {
Field ID
Value ID
}
func NewAttr(f, v Attrib) (*Attr, error) {
a := &Attr{Field: f.(ID)}
a.Value = ID("true")
if v != nil {
ok := false
a.Value, ok = v.(ID)
if !ok {
return nil, errors.New(fmt.Sprintf("value = %v", v))
}
}
return a, nil
}
func (this *Attr) String() string {
return this.Field.String() + `=` + this.Value.String()
}
func (this *Attr) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Field.Walk(v)
this.Value.Walk(v)
}
type Location interface {
Elem
Walkable
isLocation()
GetID() ID
GetPort() Port
IsNode() bool
}
func (this *NodeID) isLocation() {}
func (this *NodeID) IsNode() bool { return true }
func (this *SubGraph) isLocation() {}
func (this *SubGraph) IsNode() bool { return false }
type EdgeStmt struct {
Source Location
EdgeRHS EdgeRHS
Attrs AttrList
}
func NewEdgeStmt(id, e, attrs Attrib) (*EdgeStmt, error) {
var a AttrList = nil
var err error = nil
if attrs == nil {
a, err = NewAttrList(nil)
if err != nil {
return nil, err
}
} else {
a = attrs.(AttrList)
}
return &EdgeStmt{id.(Location), e.(EdgeRHS), a}, nil
}
func (this EdgeStmt) String() string {
return strings.TrimSpace(this.Source.String() + this.EdgeRHS.String() + this.Attrs.String())
}
func (this EdgeStmt) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Source.Walk(v)
this.EdgeRHS.Walk(v)
this.Attrs.Walk(v)
}
type EdgeRHS []*EdgeRH
func NewEdgeRHS(op, id Attrib) (EdgeRHS, error) {
return EdgeRHS{&EdgeRH{op.(EdgeOp), id.(Location)}}, nil
}
func AppendEdgeRHS(e, op, id Attrib) (EdgeRHS, error) {
erhs := e.(EdgeRHS)
erhs = append(erhs, &EdgeRH{op.(EdgeOp), id.(Location)})
return erhs, nil
}
func (this EdgeRHS) String() string {
s := ""
for i := range this {
s += this[i].String()
}
return strings.TrimSpace(s)
}
func (this EdgeRHS) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type EdgeRH struct {
Op EdgeOp
Destination Location
}
func (this *EdgeRH) String() string {
return strings.TrimSpace(this.Op.String() + this.Destination.String())
}
func (this *EdgeRH) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Op.Walk(v)
this.Destination.Walk(v)
}
type NodeStmt struct {
NodeID *NodeID
Attrs AttrList
}
func NewNodeStmt(id, attrs Attrib) (*NodeStmt, error) {
nid := id.(*NodeID)
var a AttrList = nil
var err error = nil
if attrs == nil {
a, err = NewAttrList(nil)
if err != nil {
return nil, err
}
} else {
a = attrs.(AttrList)
}
return &NodeStmt{nid, a}, nil
}
func (this NodeStmt) String() string {
return strings.TrimSpace(this.NodeID.String() + ` ` + this.Attrs.String())
}
func (this NodeStmt) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.NodeID.Walk(v)
this.Attrs.Walk(v)
}
type EdgeOp bool
const (
DIRECTED EdgeOp = true
UNDIRECTED EdgeOp = false
)
func (this EdgeOp) String() string {
if this == DIRECTED {
return "->"
}
return "--"
}
func (this EdgeOp) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type NodeID struct {
ID ID
Port Port
}
func NewNodeID(id, port Attrib) (*NodeID, error) {
if port == nil {
return &NodeID{id.(ID), Port{"", ""}}, nil
}
return &NodeID{id.(ID), port.(Port)}, nil
}
func MakeNodeID(id string, port string) *NodeID {
p := Port{"", ""}
if len(port) > 0 {
ps := strings.Split(port, ":")
p.ID1 = ID(ps[0])
if len(ps) > 1 {
p.ID2 = ID(ps[1])
}
}
return &NodeID{ID(id), p}
}
func (this *NodeID) String() string {
return this.ID.String() + this.Port.String()
}
func (this *NodeID) GetID() ID {
return this.ID
}
func (this *NodeID) GetPort() Port {
return this.Port
}
func (this *NodeID) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.ID.Walk(v)
this.Port.Walk(v)
}
//TODO semantic analysis should decide which ID is an ID and which is a Compass Point
type Port struct {
ID1 ID
ID2 ID
}
func NewPort(id1, id2 Attrib) Port {
port := Port{ID(""), ID("")}
if id1 != nil {
port.ID1 = id1.(ID)
}
if id2 != nil {
port.ID2 = id2.(ID)
}
return port
}
func (this Port) String() string {
if len(this.ID1) == 0 {
return ""
}
s := ":" + this.ID1.String()
if len(this.ID2) > 0 {
s += ":" + this.ID2.String()
}
return s
}
func (this Port) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.ID1.Walk(v)
this.ID2.Walk(v)
}
type ID string
func NewID(id Attrib) (ID, error) {
if id == nil {
return ID(""), nil
}
id_lit := string(id.(*token.Token).Lit)
return ID(id_lit), nil
}
func (this ID) String() string {
return string(this)
}
func (this ID) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}

559
vendor/github.com/awalterschulze/gographviz/attr.go generated vendored Normal file
View File

@@ -0,0 +1,559 @@
//Copyright 2017 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http)://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import "fmt"
// Attr is an attribute key
type Attr string
// NewAttr creates a new attribute key by checking whether it is a valid key
func NewAttr(key string) (Attr, error) {
a, ok := validAttrs[key]
if !ok {
return Attr(""), fmt.Errorf("%s is not a valid attribute", key)
}
return a, nil
}
const (
// Damping http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:Damping
Damping Attr = "Damping"
// K http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:K
K Attr = "K"
// URL http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:URL
URL Attr = "URL"
// Background http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:_background
Background Attr = "_background"
// Area http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:area
Area Attr = "area"
// ArrowHead http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:arrowhead
ArrowHead Attr = "arrowhead"
// ArrowSize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:arrowsize
ArrowSize Attr = "arrowsize"
// ArrowTail http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:arrowtail
ArrowTail Attr = "arrowtail"
// BB http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:bb
BB Attr = "bb"
// BgColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:bgcolor
BgColor Attr = "bgcolor"
// Center http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:center
Center Attr = "center"
// Charset http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:charset
Charset Attr = "charset"
// ClusterRank http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:clusterrank
ClusterRank Attr = "clusterrank"
// Color http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:color
Color Attr = "color"
// ColorScheme http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:colorscheme
ColorScheme Attr = "colorscheme"
// Comment http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:comment
Comment Attr = "comment"
// Compound http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:compound
Compound Attr = "compound"
// Concentrate http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:concentrate
Concentrate Attr = "concentrate"
// Constraint http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:constraint
Constraint Attr = "constraint"
// Decorate http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:decorate
Decorate Attr = "decorate"
// DefaultDist http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:defaultdist
DefaultDist Attr = "defaultdist"
// Dim http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:dim
Dim Attr = "dim"
// Dimen http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:dimen
Dimen Attr = "dimen"
// Dir http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:dir
Dir Attr = "dir"
// DirEdgeConstraints http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:dir
DirEdgeConstraints Attr = "diredgeconstraints"
// Distortion http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:distortion
Distortion Attr = "distortion"
// DPI http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:dpi
DPI Attr = "dpi"
// EdgeURL http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::edgeURL
EdgeURL Attr = "edgeURL"
// EdgeHREF http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::edgehref
EdgeHREF Attr = "edgehref"
// EdgeTarget http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::edgetarget
EdgeTarget Attr = "edgetarget"
// EdgeTooltip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::edgetooltip
EdgeTooltip Attr = "edgetooltip"
// Epsilon http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::epsilon
Epsilon Attr = "epsilon"
// ESep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d::epsilon
ESep Attr = "esep"
// FillColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fillcolor
FillColor Attr = "fillcolor"
// FixedSize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fixedsize
FixedSize Attr = "fixedsize"
// FontColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fontcolor
FontColor Attr = "fontcolor"
// FontName http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fontname
FontName Attr = "fontname"
// FontNames http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fontnames
FontNames Attr = "fontnames"
// FontPath http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fontpath
FontPath Attr = "fontpath"
// FontSize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:fontsize
FontSize Attr = "fontsize"
// ForceLabels http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:forcelabels
ForceLabels Attr = "forcelabels"
// GradientAngle http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:gradientangle
GradientAngle Attr = "gradientangle"
// Group http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:group
Group Attr = "group"
// HeadURL http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headURL
HeadURL Attr = "headURL"
// HeadLP http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:head_lp
HeadLP Attr = "head_lp"
// HeadClip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headclip
HeadClip Attr = "headclip"
// HeadHREF http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headhref
HeadHREF Attr = "headhref"
// HeadLabel http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headlabel
HeadLabel Attr = "headlabel"
// HeadPort http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headport
HeadPort Attr = "headport"
// HeadTarget http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headtarget
HeadTarget Attr = "headtarget"
// HeadTooltip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:headtooltip
HeadTooltip Attr = "headtooltip"
// Height http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:height
Height Attr = "height"
// HREF http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:href
HREF Attr = "href"
// ID http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:id
ID Attr = "id"
// Image http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:image
Image Attr = "image"
// ImagePath http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:imagepath
ImagePath Attr = "imagepath"
// ImageScale http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:imagescale
ImageScale Attr = "imagescale"
// InputScale http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:inputscale
InputScale Attr = "inputscale"
// Label http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:label
Label Attr = "label"
// LabelURL http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelURL
LabelURL Attr = "labelURL"
// LabelScheme http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:label_scheme
LabelScheme Attr = "label_scheme"
// LabelAngle http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelangle
LabelAngle Attr = "labelangle"
// LabelDistance http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labeldistance
LabelDistance Attr = "labeldistance"
// LabelFloat http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelfloat
LabelFloat Attr = "labelfloat"
// LabelFontColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelfontcolor
LabelFontColor Attr = "labelfontcolor"
// LabelFontName http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelfontname
LabelFontName Attr = "labelfontname"
// LabelFontSize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelfontsize
LabelFontSize Attr = "labelfontsize"
// LabelHREF http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelhref
LabelHREF Attr = "labelhref"
// LabelJust http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labeljust
LabelJust Attr = "labeljust"
// LabelLOC http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labelloc
LabelLOC Attr = "labelloc"
// LabelTarget http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labeltarget
LabelTarget Attr = "labeltarget"
// LabelTooltip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:labeltooltip
LabelTooltip Attr = "labeltooltip"
// Landscape http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:landscape
Landscape Attr = "landscape"
// Layer http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layer
Layer Attr = "layer"
// LayerListSep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layerlistsep
LayerListSep Attr = "layerlistsep"
// Layers http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layers
Layers Attr = "layers"
// LayerSelect http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layerselect
LayerSelect Attr = "layerselect"
// LayerSep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layersep
LayerSep Attr = "layersep"
// Layout http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:layout
Layout Attr = "layout"
// Len http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:len
Len Attr = "len"
// Levels http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:levels
Levels Attr = "levels"
// LevelsGap http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:levelsgap
LevelsGap Attr = "levelsgap"
// LHead http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:lhead
LHead Attr = "lhead"
// LHeight http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:lheight
LHeight Attr = "lheight"
// LP http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:lp
LP Attr = "lp"
// LTail http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:ltail
LTail Attr = "ltail"
// LWidth http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:lwidth
LWidth Attr = "lwidth"
// Margin http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:margin
Margin Attr = "margin"
// MaxIter http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:maxiter
MaxIter Attr = "maxiter"
// MCLimit http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:mclimit
MCLimit Attr = "mclimit"
// MinDist http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:mindist
MinDist Attr = "mindist"
// MinLen http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:mindist
MinLen Attr = "minlen"
// Mode http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:mode
Mode Attr = "mode"
// Model http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:model
Model Attr = "model"
// Mosek http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:mosek
Mosek Attr = "mosek"
// NewRank http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:newrank
NewRank Attr = "newrank"
// NodeSep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:nodesep
NodeSep Attr = "nodesep"
// NoJustify http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:nojustify
NoJustify Attr = "nojustify"
// Normalize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:normalize
Normalize Attr = "normalize"
// NoTranslate http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:notranslate
NoTranslate Attr = "notranslate"
// NSLimit http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:nslimit
NSLimit Attr = "nslimit"
// NSLimit1 http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:nslimit1
NSLimit1 Attr = "nslimit1"
// Ordering http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:nslimit1
Ordering Attr = "ordering"
// Orientation http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:orientation
Orientation Attr = "orientation"
// OutputOrder http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:outputorder
OutputOrder Attr = "outputorder"
// Overlap http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:overlap
Overlap Attr = "overlap"
// OverlapScaling http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:overlap_scaling
OverlapScaling Attr = "overlap_scaling"
// OverlapShrink http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:overlap_shrink
OverlapShrink Attr = "overlap_shrink"
// Pack http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:pack
Pack Attr = "pack"
// PackMode http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:packmode
PackMode Attr = "packmode"
// Pad http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:pad
Pad Attr = "pad"
// Page http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:page
Page Attr = "page"
// PageDir http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:pagedir
PageDir Attr = "pagedir"
// PenColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:pencolor
PenColor Attr = "pencolor"
// PenWidth http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:penwidth
PenWidth Attr = "penwidth"
// Peripheries http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:peripheries
Peripheries Attr = "peripheries"
// Pin http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:peripheries
Pin Attr = "pin"
// Pos http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:pos
Pos Attr = "pos"
// QuadTree http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:quadtree
QuadTree Attr = "quadtree"
// Quantum http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:quantum
Quantum Attr = "quantum"
// Rank http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rank
Rank Attr = "rank"
// RankDir http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rankdir
RankDir Attr = "rankdir"
// RankSep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:ranksep
RankSep Attr = "ranksep"
// Ratio http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:ratio
Ratio Attr = "ratio"
// Rects http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rects
Rects Attr = "rects"
// Regular http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:regular
Regular Attr = "regular"
// ReMinCross http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:remincross
ReMinCross Attr = "remincross"
// RepulsiveForce http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:repulsiveforce
RepulsiveForce Attr = "repulsiveforce"
// Resolution http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:resolution
Resolution Attr = "resolution"
// Root http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:root
Root Attr = "root"
// Rotate http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rotate
Rotate Attr = "rotate"
// Rotation http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:rotation
Rotation Attr = "rotation"
// SameHead http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:samehead
SameHead Attr = "samehead"
// SameTail http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:sametail
SameTail Attr = "sametail"
// SamplePoints http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:samplepoints
SamplePoints Attr = "samplepoints"
// Scale http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:scale
Scale Attr = "scale"
// SearchSize http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:searchsize
SearchSize Attr = "searchsize"
// Sep http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:sep
Sep Attr = "sep"
// Shape http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:shape
Shape Attr = "shape"
// ShapeFile http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:shapefile
ShapeFile Attr = "shapefile"
// ShowBoxes http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:showboxes
ShowBoxes Attr = "showboxes"
// Sides http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:sides
Sides Attr = "sides"
// Size http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:size
Size Attr = "size"
// Skew http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:skew
Skew Attr = "skew"
// Smoothing http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:smoothing
Smoothing Attr = "smoothing"
// SortV http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:sortv
SortV Attr = "sortv"
// Splines http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:splines
Splines Attr = "splines"
// Start http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:start
Start Attr = "start"
// Style http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:style
Style Attr = "style"
// StyleSheet http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:stylesheet
StyleSheet Attr = "stylesheet"
// TailURL http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailURL
TailURL Attr = "tailURL"
// TailLP http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tail_lp
TailLP Attr = "tail_lp"
// TailClip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailclip
TailClip Attr = "tailclip"
// TailHREF http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailhref
TailHREF Attr = "tailhref"
// TailLabel http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:taillabel
TailLabel Attr = "taillabel"
// TailPort http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailport
TailPort Attr = "tailport"
// TailTarget http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailtarget
TailTarget Attr = "tailtarget"
// TailTooltip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tailtooltip
TailTooltip Attr = "tailtooltip"
// Target http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:target
Target Attr = "target"
// Tooltip http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tooltip
Tooltip Attr = "tooltip"
// TrueColor http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:tooltip
TrueColor Attr = "truecolor"
// Vertices http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:vertices
Vertices Attr = "vertices"
// ViewPort http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:viewport
ViewPort Attr = "viewport"
// VoroMargin http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:voro_margin
VoroMargin Attr = "voro_margin"
// Weight http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:weight
Weight Attr = "weight"
// Width http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:width
Width Attr = "width"
// XDotVersion http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:xdotversion
XDotVersion Attr = "xdotversion"
// XLabel http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:xlabel
XLabel Attr = "xlabel"
// XLP http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:xlp
XLP Attr = "xlp"
// Z http://graphviz.gitlab.io/_pages/doc/info/attrs.html#d:z
Z Attr = "z"
// MinCross is not in the documentation, but found in the Ped_Lion_Share (lion_share.gv.txt) example
MinCross Attr = "mincross"
// SSize is not in the documentation, but found in the siblings.gv.txt example
SSize Attr = "ssize"
// Outline is not in the documentation, but found in the siblings.gv.txt example
Outline Attr = "outline"
// F is not in the documentation, but found in the transparency.gv.txt example
F Attr = "f"
)
var validAttrs = map[string]Attr{
string(Damping): Damping,
string(K): K,
string(URL): URL,
string(Background): Background,
string(Area): Area,
string(ArrowHead): ArrowHead,
string(ArrowSize): ArrowSize,
string(ArrowTail): ArrowTail,
string(BB): BB,
string(BgColor): BgColor,
string(Center): Center,
string(Charset): Charset,
string(ClusterRank): ClusterRank,
string(Color): Color,
string(ColorScheme): ColorScheme,
string(Comment): Comment,
string(Compound): Compound,
string(Concentrate): Concentrate,
string(Constraint): Constraint,
string(Decorate): Decorate,
string(DefaultDist): DefaultDist,
string(Dim): Dim,
string(Dimen): Dimen,
string(Dir): Dir,
string(DirEdgeConstraints): DirEdgeConstraints,
string(Distortion): Distortion,
string(DPI): DPI,
string(EdgeURL): EdgeURL,
string(EdgeHREF): EdgeHREF,
string(EdgeTarget): EdgeTarget,
string(EdgeTooltip): EdgeTooltip,
string(Epsilon): Epsilon,
string(ESep): ESep,
string(FillColor): FillColor,
string(FixedSize): FixedSize,
string(FontColor): FontColor,
string(FontName): FontName,
string(FontNames): FontNames,
string(FontPath): FontPath,
string(FontSize): FontSize,
string(ForceLabels): ForceLabels,
string(GradientAngle): GradientAngle,
string(Group): Group,
string(HeadURL): HeadURL,
string(HeadLP): HeadLP,
string(HeadClip): HeadClip,
string(HeadHREF): HeadHREF,
string(HeadLabel): HeadLabel,
string(HeadPort): HeadPort,
string(HeadTarget): HeadTarget,
string(HeadTooltip): HeadTooltip,
string(Height): Height,
string(HREF): HREF,
string(ID): ID,
string(Image): Image,
string(ImagePath): ImagePath,
string(ImageScale): ImageScale,
string(InputScale): InputScale,
string(Label): Label,
string(LabelURL): LabelURL,
string(LabelScheme): LabelScheme,
string(LabelAngle): LabelAngle,
string(LabelDistance): LabelDistance,
string(LabelFloat): LabelFloat,
string(LabelFontColor): LabelFontColor,
string(LabelFontName): LabelFontName,
string(LabelFontSize): LabelFontSize,
string(LabelHREF): LabelHREF,
string(LabelJust): LabelJust,
string(LabelLOC): LabelLOC,
string(LabelTarget): LabelTarget,
string(LabelTooltip): LabelTooltip,
string(Landscape): Landscape,
string(Layer): Layer,
string(LayerListSep): LayerListSep,
string(Layers): Layers,
string(LayerSelect): LayerSelect,
string(LayerSep): LayerSep,
string(Layout): Layout,
string(Len): Len,
string(Levels): Levels,
string(LevelsGap): LevelsGap,
string(LHead): LHead,
string(LHeight): LHeight,
string(LP): LP,
string(LTail): LTail,
string(LWidth): LWidth,
string(Margin): Margin,
string(MaxIter): MaxIter,
string(MCLimit): MCLimit,
string(MinDist): MinDist,
string(MinLen): MinLen,
string(Mode): Mode,
string(Model): Model,
string(Mosek): Mosek,
string(NewRank): NewRank,
string(NodeSep): NodeSep,
string(NoJustify): NoJustify,
string(Normalize): Normalize,
string(NoTranslate): NoTranslate,
string(NSLimit): NSLimit,
string(NSLimit1): NSLimit1,
string(Ordering): Ordering,
string(Orientation): Orientation,
string(OutputOrder): OutputOrder,
string(Overlap): Overlap,
string(OverlapScaling): OverlapScaling,
string(OverlapShrink): OverlapShrink,
string(Pack): Pack,
string(PackMode): PackMode,
string(Pad): Pad,
string(Page): Page,
string(PageDir): PageDir,
string(PenColor): PenColor,
string(PenWidth): PenWidth,
string(Peripheries): Peripheries,
string(Pin): Pin,
string(Pos): Pos,
string(QuadTree): QuadTree,
string(Quantum): Quantum,
string(Rank): Rank,
string(RankDir): RankDir,
string(RankSep): RankSep,
string(Ratio): Ratio,
string(Rects): Rects,
string(Regular): Regular,
string(ReMinCross): ReMinCross,
string(RepulsiveForce): RepulsiveForce,
string(Resolution): Resolution,
string(Root): Root,
string(Rotate): Rotate,
string(Rotation): Rotation,
string(SameHead): SameHead,
string(SameTail): SameTail,
string(SamplePoints): SamplePoints,
string(Scale): Scale,
string(SearchSize): SearchSize,
string(Sep): Sep,
string(Shape): Shape,
string(ShapeFile): ShapeFile,
string(ShowBoxes): ShowBoxes,
string(Sides): Sides,
string(Size): Size,
string(Skew): Skew,
string(Smoothing): Smoothing,
string(SortV): SortV,
string(Splines): Splines,
string(Start): Start,
string(Style): Style,
string(StyleSheet): StyleSheet,
string(TailURL): TailURL,
string(TailLP): TailLP,
string(TailClip): TailClip,
string(TailHREF): TailHREF,
string(TailLabel): TailLabel,
string(TailPort): TailPort,
string(TailTarget): TailTarget,
string(TailTooltip): TailTooltip,
string(Target): Target,
string(Tooltip): Tooltip,
string(TrueColor): TrueColor,
string(Vertices): Vertices,
string(ViewPort): ViewPort,
string(VoroMargin): VoroMargin,
string(Weight): Weight,
string(Width): Width,
string(XDotVersion): XDotVersion,
string(XLabel): XLabel,
string(XLP): XLP,
string(Z): Z,
string(MinCross): MinCross,
string(SSize): SSize,
string(Outline): Outline,
string(F): F,
}

99
vendor/github.com/awalterschulze/gographviz/attrs.go generated vendored Normal file
View File

@@ -0,0 +1,99 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"sort"
)
// Attrs represents attributes for an Edge, Node or Graph.
type Attrs map[Attr]string
// NewAttrs creates an empty Attributes type.
func NewAttrs(m map[string]string) (Attrs, error) {
as := make(Attrs)
for k, v := range m {
if err := as.Add(k, v); err != nil {
return nil, err
}
}
return as, nil
}
// Add adds an attribute name and value.
func (attrs Attrs) Add(field string, value string) error {
a, err := NewAttr(field)
if err != nil {
return err
}
attrs.add(a, value)
return nil
}
func (attrs Attrs) add(field Attr, value string) {
attrs[field] = value
}
// Extend adds the attributes into attrs Attrs type overwriting duplicates.
func (attrs Attrs) Extend(more Attrs) {
for key, value := range more {
attrs.add(key, value)
}
}
// Ammend only adds the missing attributes to attrs Attrs type.
func (attrs Attrs) Ammend(more Attrs) {
for key, value := range more {
if _, ok := attrs[key]; !ok {
attrs.add(key, value)
}
}
}
func (attrs Attrs) toMap() map[string]string {
m := make(map[string]string)
for k, v := range attrs {
m[string(k)] = v
}
return m
}
type attrList []Attr
func (attrs attrList) Len() int { return len(attrs) }
func (attrs attrList) Less(i, j int) bool {
return attrs[i] < attrs[j]
}
func (attrs attrList) Swap(i, j int) {
attrs[i], attrs[j] = attrs[j], attrs[i]
}
func (attrs Attrs) sortedNames() []Attr {
keys := make(attrList, 0)
for key := range attrs {
keys = append(keys, key)
}
sort.Sort(keys)
return []Attr(keys)
}
// Copy returns a copy of the attributes map
func (attrs Attrs) Copy() Attrs {
mm := make(Attrs)
for k, v := range attrs {
mm[k] = v
}
return mm
}

101
vendor/github.com/awalterschulze/gographviz/catch.go generated vendored Normal file
View File

@@ -0,0 +1,101 @@
//Copyright 2017 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"fmt"
"strings"
)
type errInterface interface {
SetStrict(strict bool)
SetDir(directed bool)
SetName(name string)
AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string)
AddEdge(src, dst string, directed bool, attrs map[string]string)
AddNode(parentGraph string, name string, attrs map[string]string)
AddAttr(parentGraph string, field, value string)
AddSubGraph(parentGraph string, name string, attrs map[string]string)
String() string
getError() error
}
func newErrCatcher(g Interface) errInterface {
return &errCatcher{g, nil}
}
type errCatcher struct {
Interface
errs []error
}
func (e *errCatcher) SetStrict(strict bool) {
if err := e.Interface.SetStrict(strict); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) SetDir(directed bool) {
if err := e.Interface.SetDir(directed); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) SetName(name string) {
if err := e.Interface.SetName(name); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) {
if err := e.Interface.AddPortEdge(src, srcPort, dst, dstPort, directed, attrs); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) AddEdge(src, dst string, directed bool, attrs map[string]string) {
if err := e.Interface.AddEdge(src, dst, directed, attrs); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) AddAttr(parentGraph string, field, value string) {
if err := e.Interface.AddAttr(parentGraph, field, value); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) AddSubGraph(parentGraph string, name string, attrs map[string]string) {
if err := e.Interface.AddSubGraph(parentGraph, name, attrs); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) AddNode(parentGraph string, name string, attrs map[string]string) {
if err := e.Interface.AddNode(parentGraph, name, attrs); err != nil {
e.errs = append(e.errs, err)
}
}
func (e *errCatcher) getError() error {
if len(e.errs) == 0 {
return nil
}
ss := make([]string, len(e.errs))
for i, err := range e.errs {
ss[i] = err.Error()
}
return fmt.Errorf("errors: [%s]", strings.Join(ss, ","))
}

292
vendor/github.com/awalterschulze/gographviz/dot.bnf generated vendored Normal file
View File

@@ -0,0 +1,292 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//This bnf has been derived from https://graphviz.gitlab.io/_pages/doc/info/lang.html
//The rules have been copied and are shown in the comments, with their derived bnf rules below.
// ### [ Tokens ] ##############################################################
// The keywords node, edge, graph, digraph, subgraph, and strict are case-
// independent.
node
: 'n' 'o' 'd' 'e'
| 'N' 'o' 'd' 'e'
| 'N' 'O' 'D' 'E'
;
edge
: 'e' 'd' 'g' 'e'
| 'E' 'd' 'g' 'e'
| 'E' 'D' 'G' 'E'
;
// TODO: Rename graphx to graph once gocc#20 is fixed [1].
//
// [1]: https://github.com/goccmack/gocc/issues/20
graphx
: 'g' 'r' 'a' 'p' 'h'
| 'G' 'r' 'a' 'p' 'h'
| 'G' 'R' 'A' 'P' 'H'
;
digraph
: 'd' 'i' 'g' 'r' 'a' 'p' 'h'
| 'D' 'i' 'g' 'r' 'a' 'p' 'h'
| 'd' 'i' 'G' 'r' 'a' 'p' 'h'
| 'D' 'i' 'G' 'r' 'a' 'p' 'h'
| 'D' 'I' 'G' 'R' 'A' 'P' 'H'
;
subgraph
: 's' 'u' 'b' 'g' 'r' 'a' 'p' 'h'
| 'S' 'u' 'b' 'g' 'r' 'a' 'p' 'h'
| 's' 'u' 'b' 'G' 'r' 'a' 'p' 'h'
| 'S' 'u' 'b' 'G' 'r' 'a' 'p' 'h'
| 'S' 'U' 'B' 'G' 'R' 'A' 'P' 'H'
;
strict
: 's' 't' 'r' 'i' 'c' 't'
| 'S' 't' 'r' 'i' 'c' 't'
| 'S' 'T' 'R' 'I' 'C' 'T'
;
// An arbitrary ASCII character except null (0x00), double quote (0x22) and
// backslash (0x5C).
_ascii_char
// skip null (0x00)
: '\x01' - '\x21'
// skip double quote (0x22)
| '\x23' - '\x5B'
// skip backslash (0x5C)
| '\x5D' - '\x7F'
;
_ascii_letter
: 'a' - 'z'
| 'A' - 'Z'
;
_ascii_digit : '0' - '9' ;
_unicode_char
: _ascii_char
| _unicode_byte
;
_unicode_byte
: '\u0080' - '\uFFFC'
// skip invalid code point (\uFFFD)
| '\uFFFE' - '\U0010FFFF'
;
_letter : _ascii_letter | _unicode_byte | '_' ;
_decimal_digit : _ascii_digit ;
_decimals : _decimal_digit { _decimal_digit } ;
// An ID is one of the following:
//
// 1) Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores
// ('_') or digits ([0-9]), not beginning with a digit;
//
// 2) a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
//
// 3) any double-quoted string ("...") possibly containing escaped quotes
// (\");
//
// 4) an HTML string (<...>).
id
: _letter { _letter | _decimal_digit }
| _int_lit
| _string_lit
| _html_lit
;
_int_lit
: [ '-' ] '.' _decimals
| [ '-' ] _decimals [ '.' { _decimal_digit } ]
;
// In quoted strings in DOT, the only escaped character is double-quote (").
// That is, in quoted strings, the dyad \" is converted to "; all other
// characters are left unchanged. In particular, \\ remains \\.
_escaped_char : '\\' ( _unicode_char | '"' | '\\' ) ;
_char : _unicode_char | _escaped_char ;
_string_lit : '"' { _char } '"' ;
// An arbitrary HTML character except null (0x00), left angle bracket (0x3C) and
// right angle bracket (0x3E).
_html_char
// skip null (0x00)
: '\x01' - '\x3B'
// skip left angle bracket (0x3C)
| '\x3D'
// skip right angle bracket (0x3E)
| '\x3F' - '\xFF'
;
_html_chars : { _html_char } ;
_html_tag : '<' _html_chars '>' ;
_html_lit : '<' { _html_chars | _html_tag } '>' ;
// The language supports C++-style comments: /* */ and //. In addition, a line
// beginning with a '#' character is considered a line output from a C
// preprocessor (e.g., # 34 to indicate line 34 ) and discarded.
_line_comment
: '/' '/' { . } '\n'
| '#' { . } '\n'
;
_block_comment : '/' '*' { . | '*' } '*' '/' ;
!comment : _line_comment | _block_comment ;
!whitespace : ' ' | '\t' | '\r' | '\n' ;
// ### [ Syntax ] ##############################################################
<< import "github.com/awalterschulze/gographviz/ast" >>
//graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'
DotGraph
: graphx "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, nil) >>
| strict graphx "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, nil) >>
| graphx Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, nil) >>
| strict graphx Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, $2, nil) >>
| graphx "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, $2) >>
| graphx Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, $3) >>
| strict graphx "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, $3) >>
| strict graphx Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, $2, $4) >>
| digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, nil) >>
| strict digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, nil) >>
| digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, $1, nil) >>
| strict digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, $2, nil) >>
| digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, $2) >>
| digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, $1, $3) >>
| strict digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, $3) >>
| strict digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, $2, $4) >>
;
//stmt_list : [ stmt [ ';' ] [ stmt_list ] ]
StmtList
: Stmt1 << ast.NewStmtList($0) >>
| StmtList Stmt1 << ast.AppendStmtList($0, $1) >>
;
Stmt1
: Stmt << $0, nil >>
| Stmt ";" << $0, nil >>
;
//stmt : node_stmt | edge_stmt | attr_stmt | (ID '=' ID) | subgraph
Stmt
: Id "=" Id << ast.NewAttr($0, $2) >>
| NodeStmt << $0, nil >>
| EdgeStmt << $0, nil >>
| AttrStmt << $0, nil >>
| SubGraphStmt << $0, nil >>
;
//attr_stmt : (graph | node | edge) attr_list
AttrStmt
: graphx AttrList << ast.NewGraphAttrs($1) >>
| node AttrList << ast.NewNodeAttrs($1) >>
| edge AttrList << ast.NewEdgeAttrs($1) >>
;
//attr_list : '[' [ a_list ] ']' [ attr_list ]
AttrList
: "[" "]" << ast.NewAttrList(nil) >>
| "[" AList "]" << ast.NewAttrList($1) >>
| AttrList "[" "]" << ast.AppendAttrList($0, nil) >>
| AttrList "[" AList "]" << ast.AppendAttrList($0, $2) >>
;
//a_list : ID [ '=' ID ] [ ',' ] [ a_list ]
AList
: Attr << ast.NewAList($0) >>
| AList Attr << ast.AppendAList($0, $1) >>
| AList "," Attr << ast.AppendAList($0, $2) >>
;
//An a_list clause of the form ID is equivalent to ID=true.
Attr
: Id << ast.NewAttr($0, nil) >>
| Id "=" Id << ast.NewAttr($0, $2) >>
;
//edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
EdgeStmt
: NodeId EdgeRHS << ast.NewEdgeStmt($0, $1, nil) >>
| NodeId EdgeRHS AttrList << ast.NewEdgeStmt($0, $1, $2) >>
| SubGraphStmt EdgeRHS << ast.NewEdgeStmt($0, $1, nil) >>
| SubGraphStmt EdgeRHS AttrList << ast.NewEdgeStmt($0, $1, $2) >>
;
//edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
EdgeRHS
: EdgeOp NodeId << ast.NewEdgeRHS($0, $1) >>
| EdgeOp SubGraphStmt << ast.NewEdgeRHS($0, $1) >>
| EdgeRHS EdgeOp NodeId << ast.AppendEdgeRHS($0, $1, $2) >>
| EdgeRHS EdgeOp SubGraphStmt << ast.AppendEdgeRHS($0, $1, $2) >>
;
//node_stmt : node_id [ attr_list ]
NodeStmt
: NodeId << ast.NewNodeStmt($0, nil) >>
| NodeId AttrList << ast.NewNodeStmt($0, $1) >>
;
//node_id : ID [ port ]
NodeId
: Id << ast.NewNodeID($0, nil) >>
| Id Port << ast.NewNodeID($0, $1) >>
;
//compass_pt : (n | ne | e | se | s | sw | w | nw | c | _)
//Note also that the allowed compass point values are not keywords,
//so these strings can be used elsewhere as ordinary identifiers and,
//conversely, the parser will actually accept any identifier.
//port : ':' ID [ ':' compass_pt ]
// | ':' compass_pt
Port
: ":" Id << ast.NewPort($1, nil), nil >>
| ":" Id ":" Id << ast.NewPort($1, $3), nil >>
;
//TODO: Semicolons aid readability but are not required except in the rare case that a named subgraph with no body immediately preceeds an anonymous subgraph,
//since the precedence rules cause this sequence to be parsed as a subgraph with a heading and a body. Also, any amount of whitespace may be inserted between terminals.
//subgraph : [ subgraph [ ID ] ] '{' stmt_list '}'
SubGraphStmt
: "{" StmtList "}" << ast.NewSubGraph(nil, $1) >>
| subgraph "{" StmtList "}" << ast.NewSubGraph(nil, $2) >>
| subgraph Id "{" StmtList "}" << ast.NewSubGraph($1, $3) >>
| subgraph "{" "}" << ast.NewSubGraph(nil, nil) >>
| subgraph Id "{" "}" << ast.NewSubGraph($1, nil) >>
;
//An edgeop is -> in directed graphs and -- in undirected graphs.
EdgeOp
: "->" << ast.DIRECTED, nil >>
| "--" << ast.UNDIRECTED, nil >>
;
Id
: id << ast.NewID($0) >>
;

119
vendor/github.com/awalterschulze/gographviz/edges.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"sort"
)
// Edge represents an Edge.
type Edge struct {
Src string
SrcPort string
Dst string
DstPort string
Dir bool
Attrs Attrs
}
// Edges represents a set of Edges.
type Edges struct {
SrcToDsts map[string]map[string][]*Edge
DstToSrcs map[string]map[string][]*Edge
Edges []*Edge
}
// NewEdges creates a blank set of Edges.
func NewEdges() *Edges {
return &Edges{make(map[string]map[string][]*Edge), make(map[string]map[string][]*Edge), make([]*Edge, 0)}
}
// Add adds an Edge to the set of Edges.
func (edges *Edges) Add(edge *Edge) {
if _, ok := edges.SrcToDsts[edge.Src]; !ok {
edges.SrcToDsts[edge.Src] = make(map[string][]*Edge)
}
if _, ok := edges.SrcToDsts[edge.Src][edge.Dst]; !ok {
edges.SrcToDsts[edge.Src][edge.Dst] = make([]*Edge, 0)
}
edges.SrcToDsts[edge.Src][edge.Dst] = append(edges.SrcToDsts[edge.Src][edge.Dst], edge)
if _, ok := edges.DstToSrcs[edge.Dst]; !ok {
edges.DstToSrcs[edge.Dst] = make(map[string][]*Edge)
}
if _, ok := edges.DstToSrcs[edge.Dst][edge.Src]; !ok {
edges.DstToSrcs[edge.Dst][edge.Src] = make([]*Edge, 0)
}
edges.DstToSrcs[edge.Dst][edge.Src] = append(edges.DstToSrcs[edge.Dst][edge.Src], edge)
edges.Edges = append(edges.Edges, edge)
}
// Sorted returns a sorted list of Edges.
func (edges Edges) Sorted() []*Edge {
es := make(edgeSorter, len(edges.Edges))
copy(es, edges.Edges)
sort.Sort(es)
return es
}
type edgeSorter []*Edge
func (es edgeSorter) Len() int { return len(es) }
func (es edgeSorter) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es edgeSorter) Less(i, j int) bool {
if es[i].Src < es[j].Src {
return true
} else if es[i].Src > es[j].Src {
return false
}
if es[i].Dst < es[j].Dst {
return true
} else if es[i].Dst > es[j].Dst {
return false
}
if es[i].SrcPort < es[j].SrcPort {
return true
} else if es[i].SrcPort > es[j].SrcPort {
return false
}
if es[i].DstPort < es[j].DstPort {
return true
} else if es[i].DstPort > es[j].DstPort {
return false
}
if es[i].Dir != es[j].Dir {
return es[i].Dir
}
attrs := es[i].Attrs.Copy()
for k, v := range es[j].Attrs {
attrs[k] = v
}
for _, k := range attrs.sortedNames() {
if es[i].Attrs[k] < es[j].Attrs[k] {
return true
} else if es[i].Attrs[k] > es[j].Attrs[k] {
return false
}
}
return false
}

195
vendor/github.com/awalterschulze/gographviz/escape.go generated vendored Normal file
View File

@@ -0,0 +1,195 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"fmt"
"strings"
"text/template"
"unicode"
)
// Escape is just a Graph that escapes some strings when required.
type Escape struct {
*Graph
}
// NewEscape returns a graph which will try to escape some strings when required
func NewEscape() *Escape {
return &Escape{NewGraph()}
}
func isHTML(s string) bool {
if len(s) == 0 {
return false
}
ss := strings.TrimSpace(s)
if ss[0] != '<' {
return false
}
count := 0
for _, c := range ss {
if c == '<' {
count++
}
if c == '>' {
count--
}
}
if count == 0 {
return true
}
return false
}
func isLetter(ch rune) bool {
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' ||
ch >= 0x80 && unicode.IsLetter(ch) && ch != 'ε'
}
func isID(s string) bool {
i := 0
pos := false
for _, c := range s {
if i == 0 {
if !isLetter(c) {
return false
}
pos = true
}
if unicode.IsSpace(c) {
return false
}
if c == '-' {
return false
}
if c == '/' {
return false
}
i++
}
return pos
}
func isDigit(ch rune) bool {
return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
}
func isNumber(s string) bool {
state := 0
for _, c := range s {
if state == 0 {
if isDigit(c) || c == '.' {
state = 2
} else if c == '-' {
state = 1
} else {
return false
}
} else if state == 1 {
if isDigit(c) || c == '.' {
state = 2
}
} else if c != '.' && !isDigit(c) {
return false
}
}
return (state == 2)
}
func isStringLit(s string) bool {
if !strings.HasPrefix(s, `"`) || !strings.HasSuffix(s, `"`) {
return false
}
var prev rune
for _, r := range s[1 : len(s)-1] {
if r == '"' && prev != '\\' {
return false
}
prev = r
}
return true
}
func esc(s string) string {
if len(s) == 0 {
return s
}
if isHTML(s) {
return s
}
ss := strings.TrimSpace(s)
if ss[0] == '<' {
return fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", -1))
}
if isID(s) {
return s
}
if isNumber(s) {
return s
}
if isStringLit(s) {
return s
}
return fmt.Sprintf("\"%s\"", template.HTMLEscapeString(s))
}
func escAttrs(attrs map[string]string) map[string]string {
newAttrs := make(map[string]string)
for k, v := range attrs {
newAttrs[esc(k)] = esc(v)
}
return newAttrs
}
// SetName sets the graph name and escapes it, if needed.
func (escape *Escape) SetName(name string) error {
return escape.Graph.SetName(esc(name))
}
// AddPortEdge adds an edge with ports and escapes the src, dst and attrs, if needed.
func (escape *Escape) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) error {
return escape.Graph.AddPortEdge(esc(src), srcPort, esc(dst), dstPort, directed, escAttrs(attrs))
}
// AddEdge adds an edge and escapes the src, dst and attrs, if needed.
func (escape *Escape) AddEdge(src, dst string, directed bool, attrs map[string]string) error {
return escape.AddPortEdge(src, "", dst, "", directed, attrs)
}
// AddNode adds a node and escapes the parentGraph, name and attrs, if needed.
func (escape *Escape) AddNode(parentGraph string, name string, attrs map[string]string) error {
return escape.Graph.AddNode(esc(parentGraph), esc(name), escAttrs(attrs))
}
// AddAttr adds an attribute and escapes the parentGraph, field and value, if needed.
func (escape *Escape) AddAttr(parentGraph string, field, value string) error {
return escape.Graph.AddAttr(esc(parentGraph), esc(field), esc(value))
}
// AddSubGraph adds a subgraph and escapes the parentGraph, name and attrs, if needed.
func (escape *Escape) AddSubGraph(parentGraph string, name string, attrs map[string]string) error {
return escape.Graph.AddSubGraph(esc(parentGraph), esc(name), escAttrs(attrs))
}
// IsNode returns whether the, escaped if needed, name is a node in the graph.
func (escape *Escape) IsNode(name string) bool {
return escape.Graph.IsNode(esc(name))
}
// IsSubGraph returns whether the, escaped if needed, name is a subgraph in the grahp.
func (escape *Escape) IsSubGraph(name string) bool {
return escape.Graph.IsSubGraph(esc(name))
}

View File

@@ -0,0 +1,58 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//Package gographviz provides parsing for the DOT grammar into
//an abstract syntax tree representing a graph,
//analysis of the abstract syntax tree into a more usable structure,
//and writing back of this structure into the DOT format.
package gographviz
import (
"github.com/awalterschulze/gographviz/ast"
"github.com/awalterschulze/gographviz/internal/parser"
)
var _ Interface = NewGraph()
//Interface allows you to parse the graph into your own structure.
type Interface interface {
SetStrict(strict bool) error
SetDir(directed bool) error
SetName(name string) error
AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) error
AddEdge(src, dst string, directed bool, attrs map[string]string) error
AddNode(parentGraph string, name string, attrs map[string]string) error
AddAttr(parentGraph string, field, value string) error
AddSubGraph(parentGraph string, name string, attrs map[string]string) error
String() string
}
//Parse parses the buffer into a abstract syntax tree representing the graph.
func Parse(buf []byte) (*ast.Graph, error) {
return parser.ParseBytes(buf)
}
//ParseString parses the buffer into a abstract syntax tree representing the graph.
func ParseString(buf string) (*ast.Graph, error) {
return parser.ParseBytes([]byte(buf))
}
//Read parses and creates a new Graph from the data.
func Read(buf []byte) (*Graph, error) {
st, err := Parse(buf)
if err != nil {
return nil, err
}
return NewAnalysedGraph(st)
}

197
vendor/github.com/awalterschulze/gographviz/graph.go generated vendored Normal file
View File

@@ -0,0 +1,197 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"fmt"
"strings"
)
// Graph is the analysed representation of the Graph parsed from the DOT format.
type Graph struct {
Attrs Attrs
Name string
Directed bool
Strict bool
Nodes *Nodes
Edges *Edges
SubGraphs *SubGraphs
Relations *Relations
}
// NewGraph creates a new empty graph, ready to be populated.
func NewGraph() *Graph {
return &Graph{
Attrs: make(Attrs),
Name: "",
Directed: false,
Strict: false,
Nodes: NewNodes(),
Edges: NewEdges(),
SubGraphs: NewSubGraphs(),
Relations: NewRelations(),
}
}
// SetStrict sets whether a graph is strict.
// If the graph is strict then multiple edges are not allowed between the same pairs of nodes,
// see dot man page.
func (g *Graph) SetStrict(strict bool) error {
g.Strict = strict
return nil
}
// SetDir sets whether the graph is directed (true) or undirected (false).
func (g *Graph) SetDir(dir bool) error {
g.Directed = dir
return nil
}
// SetName sets the graph name.
func (g *Graph) SetName(name string) error {
g.Name = name
return nil
}
// AddPortEdge adds an edge to the graph from node src to node dst.
// srcPort and dstPort are the port the node ports, leave as empty strings if it is not required.
// This does not imply the adding of missing nodes.
func (g *Graph) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) error {
as, err := NewAttrs(attrs)
if err != nil {
return err
}
g.Edges.Add(&Edge{src, srcPort, dst, dstPort, directed, as})
return nil
}
// AddEdge adds an edge to the graph from node src to node dst.
// This does not imply the adding of missing nodes.
// If directed is set to true then SetDir(true) must also be called or there will be a syntax error in the output.
func (g *Graph) AddEdge(src, dst string, directed bool, attrs map[string]string) error {
return g.AddPortEdge(src, "", dst, "", directed, attrs)
}
// AddNode adds a node to a graph/subgraph.
// If not subgraph exists use the name of the main graph.
// This does not imply the adding of a missing subgraph.
func (g *Graph) AddNode(parentGraph string, name string, attrs map[string]string) error {
as, err := NewAttrs(attrs)
if err != nil {
return err
}
g.Nodes.Add(&Node{name, as})
g.Relations.Add(parentGraph, name)
return nil
}
// RemoveNode removes a node from the graph
func (g *Graph) RemoveNode(parentGraph string, name string) error {
err := g.Nodes.Remove(name)
if err != nil {
return err
}
g.Relations.Remove(parentGraph, name)
edges := NewEdges()
for _, e := range g.Edges.Edges {
if e.Dst == name || e.Src == name {
continue
}
edges.Add(e)
}
g.Edges = edges
return nil
}
func (g *Graph) getAttrs(graphName string) (Attrs, error) {
if g.Name == graphName {
return g.Attrs, nil
}
sub, ok := g.SubGraphs.SubGraphs[graphName]
if !ok {
return nil, fmt.Errorf("graph or subgraph %s does not exist", graphName)
}
return sub.Attrs, nil
}
// AddAttr adds an attribute to a graph/subgraph.
func (g *Graph) AddAttr(parentGraph string, field string, value string) error {
a, err := g.getAttrs(parentGraph)
if err != nil {
return err
}
return a.Add(field, value)
}
// AddSubGraph adds a subgraph to a graph/subgraph.
func (g *Graph) AddSubGraph(parentGraph string, name string, attrs map[string]string) error {
g.Relations.Add(parentGraph, name)
g.SubGraphs.Add(name)
for key, value := range attrs {
if err := g.AddAttr(name, key, value); err != nil {
return err
}
}
return nil
}
// RemoveSubGraph removes the subgraph including nodes
func (g *Graph) RemoveSubGraph(parentGraph string, name string) error {
for child := range g.Relations.ParentToChildren[name] {
err := g.RemoveNode(parentGraph, child)
if err != nil {
return err
}
}
g.Relations.Remove(parentGraph, name)
g.SubGraphs.Remove(name)
edges := NewEdges()
for _, e := range g.Edges.Edges {
if e.Dst == name || e.DstPort == name || e.Src == name || e.SrcPort == name {
continue
}
edges.Add(e)
}
g.Edges = edges
return nil
}
// IsNode returns whether a given node name exists as a node in the graph.
func (g *Graph) IsNode(name string) bool {
_, ok := g.Nodes.Lookup[name]
return ok
}
// IsSubGraph returns whether a given subgraph name exists as a subgraph in the graph.
func (g *Graph) IsSubGraph(name string) bool {
_, ok := g.SubGraphs.SubGraphs[name]
return ok
}
func (g *Graph) isClusterSubGraph(name string) bool {
isSubGraph := g.IsSubGraph(name)
isCluster := strings.HasPrefix(name, "cluster")
return isSubGraph && isCluster
}

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -xe
mkdir -p $GOPATH/src/githbub.com/goccmack
git clone https://github.com/goccmack/gocc $GOPATH/src/github.com/goccmack/gocc
go get golang.org/x/tools/cmd/goimports
go get github.com/kisielk/errcheck
go get -u golang.org/x/lint/golint

View File

@@ -0,0 +1,56 @@
// Code generated by gocc; DO NOT EDIT.
package errors
import (
"bytes"
"fmt"
"github.com/awalterschulze/gographviz/internal/token"
)
type ErrorSymbol interface {
}
type Error struct {
Err error
ErrorToken *token.Token
ErrorSymbols []ErrorSymbol
ExpectedTokens []string
StackTop int
}
func (e *Error) String() string {
w := new(bytes.Buffer)
fmt.Fprintf(w, "Error")
if e.Err != nil {
fmt.Fprintf(w, " %s\n", e.Err)
} else {
fmt.Fprintf(w, "\n")
}
fmt.Fprintf(w, "Token: type=%d, lit=%s\n", e.ErrorToken.Type, e.ErrorToken.Lit)
fmt.Fprintf(w, "Pos: offset=%d, line=%d, column=%d\n", e.ErrorToken.Pos.Offset, e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
fmt.Fprintf(w, "Expected one of: ")
for _, sym := range e.ExpectedTokens {
fmt.Fprintf(w, "%s ", sym)
}
fmt.Fprintf(w, "ErrorSymbol:\n")
for _, sym := range e.ErrorSymbols {
fmt.Fprintf(w, "%v\n", sym)
}
return w.String()
}
func (e *Error) Error() string {
w := new(bytes.Buffer)
fmt.Fprintf(w, "Error in S%d: %s, %s", e.StackTop, token.TokMap.TokenString(e.ErrorToken), e.ErrorToken.Pos.String())
if e.Err != nil {
fmt.Fprintf(w, ": %+v", e.Err)
} else {
fmt.Fprintf(w, ", expected one of: ")
for _, expected := range e.ExpectedTokens {
fmt.Fprintf(w, "%s ", expected)
}
}
return w.String()
}

View File

@@ -0,0 +1,587 @@
// Code generated by gocc; DO NOT EDIT.
package lexer
import (
"fmt"
"github.com/awalterschulze/gographviz/internal/token"
)
type ActionTable [NumStates]ActionRow
type ActionRow struct {
Accept token.Type
Ignore string
}
func (a ActionRow) String() string {
return fmt.Sprintf("Accept=%d, Ignore=%s", a.Accept, a.Ignore)
}
var ActTab = ActionTable{
ActionRow{ // S0
Accept: 0,
Ignore: "",
},
ActionRow{ // S1
Accept: -1,
Ignore: "!whitespace",
},
ActionRow{ // S2
Accept: 0,
Ignore: "",
},
ActionRow{ // S3
Accept: 0,
Ignore: "",
},
ActionRow{ // S4
Accept: 13,
Ignore: "",
},
ActionRow{ // S5
Accept: 0,
Ignore: "",
},
ActionRow{ // S6
Accept: 0,
Ignore: "",
},
ActionRow{ // S7
Accept: 0,
Ignore: "",
},
ActionRow{ // S8
Accept: 18,
Ignore: "",
},
ActionRow{ // S9
Accept: 14,
Ignore: "",
},
ActionRow{ // S10
Accept: 7,
Ignore: "",
},
ActionRow{ // S11
Accept: 0,
Ignore: "",
},
ActionRow{ // S12
Accept: 8,
Ignore: "",
},
ActionRow{ // S13
Accept: 18,
Ignore: "",
},
ActionRow{ // S14
Accept: 18,
Ignore: "",
},
ActionRow{ // S15
Accept: 18,
Ignore: "",
},
ActionRow{ // S16
Accept: 18,
Ignore: "",
},
ActionRow{ // S17
Accept: 18,
Ignore: "",
},
ActionRow{ // S18
Accept: 18,
Ignore: "",
},
ActionRow{ // S19
Accept: 11,
Ignore: "",
},
ActionRow{ // S20
Accept: 12,
Ignore: "",
},
ActionRow{ // S21
Accept: 18,
Ignore: "",
},
ActionRow{ // S22
Accept: 18,
Ignore: "",
},
ActionRow{ // S23
Accept: 18,
Ignore: "",
},
ActionRow{ // S24
Accept: 18,
Ignore: "",
},
ActionRow{ // S25
Accept: 18,
Ignore: "",
},
ActionRow{ // S26
Accept: 18,
Ignore: "",
},
ActionRow{ // S27
Accept: 3,
Ignore: "",
},
ActionRow{ // S28
Accept: 4,
Ignore: "",
},
ActionRow{ // S29
Accept: 18,
Ignore: "",
},
ActionRow{ // S30
Accept: 0,
Ignore: "",
},
ActionRow{ // S31
Accept: 18,
Ignore: "",
},
ActionRow{ // S32
Accept: 0,
Ignore: "",
},
ActionRow{ // S33
Accept: 0,
Ignore: "",
},
ActionRow{ // S34
Accept: -1,
Ignore: "!comment",
},
ActionRow{ // S35
Accept: 17,
Ignore: "",
},
ActionRow{ // S36
Accept: 16,
Ignore: "",
},
ActionRow{ // S37
Accept: 18,
Ignore: "",
},
ActionRow{ // S38
Accept: 0,
Ignore: "",
},
ActionRow{ // S39
Accept: 0,
Ignore: "",
},
ActionRow{ // S40
Accept: 18,
Ignore: "",
},
ActionRow{ // S41
Accept: 0,
Ignore: "",
},
ActionRow{ // S42
Accept: 0,
Ignore: "",
},
ActionRow{ // S43
Accept: 18,
Ignore: "",
},
ActionRow{ // S44
Accept: 18,
Ignore: "",
},
ActionRow{ // S45
Accept: 18,
Ignore: "",
},
ActionRow{ // S46
Accept: 18,
Ignore: "",
},
ActionRow{ // S47
Accept: 18,
Ignore: "",
},
ActionRow{ // S48
Accept: 18,
Ignore: "",
},
ActionRow{ // S49
Accept: 18,
Ignore: "",
},
ActionRow{ // S50
Accept: 18,
Ignore: "",
},
ActionRow{ // S51
Accept: 18,
Ignore: "",
},
ActionRow{ // S52
Accept: 18,
Ignore: "",
},
ActionRow{ // S53
Accept: 18,
Ignore: "",
},
ActionRow{ // S54
Accept: 18,
Ignore: "",
},
ActionRow{ // S55
Accept: 18,
Ignore: "",
},
ActionRow{ // S56
Accept: 18,
Ignore: "",
},
ActionRow{ // S57
Accept: 18,
Ignore: "",
},
ActionRow{ // S58
Accept: 18,
Ignore: "",
},
ActionRow{ // S59
Accept: 18,
Ignore: "",
},
ActionRow{ // S60
Accept: 18,
Ignore: "",
},
ActionRow{ // S61
Accept: 18,
Ignore: "",
},
ActionRow{ // S62
Accept: 18,
Ignore: "",
},
ActionRow{ // S63
Accept: 0,
Ignore: "",
},
ActionRow{ // S64
Accept: 0,
Ignore: "",
},
ActionRow{ // S65
Accept: 0,
Ignore: "",
},
ActionRow{ // S66
Accept: 0,
Ignore: "",
},
ActionRow{ // S67
Accept: 18,
Ignore: "",
},
ActionRow{ // S68
Accept: 0,
Ignore: "",
},
ActionRow{ // S69
Accept: 18,
Ignore: "",
},
ActionRow{ // S70
Accept: 18,
Ignore: "",
},
ActionRow{ // S71
Accept: 18,
Ignore: "",
},
ActionRow{ // S72
Accept: 18,
Ignore: "",
},
ActionRow{ // S73
Accept: 18,
Ignore: "",
},
ActionRow{ // S74
Accept: 18,
Ignore: "",
},
ActionRow{ // S75
Accept: 18,
Ignore: "",
},
ActionRow{ // S76
Accept: 18,
Ignore: "",
},
ActionRow{ // S77
Accept: 18,
Ignore: "",
},
ActionRow{ // S78
Accept: 18,
Ignore: "",
},
ActionRow{ // S79
Accept: 18,
Ignore: "",
},
ActionRow{ // S80
Accept: 18,
Ignore: "",
},
ActionRow{ // S81
Accept: 18,
Ignore: "",
},
ActionRow{ // S82
Accept: 18,
Ignore: "",
},
ActionRow{ // S83
Accept: 18,
Ignore: "",
},
ActionRow{ // S84
Accept: 18,
Ignore: "",
},
ActionRow{ // S85
Accept: 18,
Ignore: "",
},
ActionRow{ // S86
Accept: 18,
Ignore: "",
},
ActionRow{ // S87
Accept: 18,
Ignore: "",
},
ActionRow{ // S88
Accept: 18,
Ignore: "",
},
ActionRow{ // S89
Accept: -1,
Ignore: "!comment",
},
ActionRow{ // S90
Accept: 0,
Ignore: "",
},
ActionRow{ // S91
Accept: 18,
Ignore: "",
},
ActionRow{ // S92
Accept: 18,
Ignore: "",
},
ActionRow{ // S93
Accept: 18,
Ignore: "",
},
ActionRow{ // S94
Accept: 10,
Ignore: "",
},
ActionRow{ // S95
Accept: 18,
Ignore: "",
},
ActionRow{ // S96
Accept: 18,
Ignore: "",
},
ActionRow{ // S97
Accept: 9,
Ignore: "",
},
ActionRow{ // S98
Accept: 18,
Ignore: "",
},
ActionRow{ // S99
Accept: 18,
Ignore: "",
},
ActionRow{ // S100
Accept: 18,
Ignore: "",
},
ActionRow{ // S101
Accept: 18,
Ignore: "",
},
ActionRow{ // S102
Accept: 18,
Ignore: "",
},
ActionRow{ // S103
Accept: 18,
Ignore: "",
},
ActionRow{ // S104
Accept: 18,
Ignore: "",
},
ActionRow{ // S105
Accept: 18,
Ignore: "",
},
ActionRow{ // S106
Accept: 18,
Ignore: "",
},
ActionRow{ // S107
Accept: 18,
Ignore: "",
},
ActionRow{ // S108
Accept: 18,
Ignore: "",
},
ActionRow{ // S109
Accept: 18,
Ignore: "",
},
ActionRow{ // S110
Accept: 18,
Ignore: "",
},
ActionRow{ // S111
Accept: 18,
Ignore: "",
},
ActionRow{ // S112
Accept: 2,
Ignore: "",
},
ActionRow{ // S113
Accept: 18,
Ignore: "",
},
ActionRow{ // S114
Accept: 18,
Ignore: "",
},
ActionRow{ // S115
Accept: 18,
Ignore: "",
},
ActionRow{ // S116
Accept: 18,
Ignore: "",
},
ActionRow{ // S117
Accept: 18,
Ignore: "",
},
ActionRow{ // S118
Accept: 18,
Ignore: "",
},
ActionRow{ // S119
Accept: 18,
Ignore: "",
},
ActionRow{ // S120
Accept: 18,
Ignore: "",
},
ActionRow{ // S121
Accept: 18,
Ignore: "",
},
ActionRow{ // S122
Accept: 18,
Ignore: "",
},
ActionRow{ // S123
Accept: 18,
Ignore: "",
},
ActionRow{ // S124
Accept: 18,
Ignore: "",
},
ActionRow{ // S125
Accept: 18,
Ignore: "",
},
ActionRow{ // S126
Accept: 5,
Ignore: "",
},
ActionRow{ // S127
Accept: 18,
Ignore: "",
},
ActionRow{ // S128
Accept: 18,
Ignore: "",
},
ActionRow{ // S129
Accept: 18,
Ignore: "",
},
ActionRow{ // S130
Accept: 18,
Ignore: "",
},
ActionRow{ // S131
Accept: 18,
Ignore: "",
},
ActionRow{ // S132
Accept: 18,
Ignore: "",
},
ActionRow{ // S133
Accept: 18,
Ignore: "",
},
ActionRow{ // S134
Accept: 6,
Ignore: "",
},
ActionRow{ // S135
Accept: 18,
Ignore: "",
},
ActionRow{ // S136
Accept: 18,
Ignore: "",
},
ActionRow{ // S137
Accept: 18,
Ignore: "",
},
ActionRow{ // S138
Accept: 18,
Ignore: "",
},
ActionRow{ // S139
Accept: 18,
Ignore: "",
},
ActionRow{ // S140
Accept: 15,
Ignore: "",
},
}

View File

@@ -0,0 +1,300 @@
// Code generated by gocc; DO NOT EDIT.
package lexer
import (
"io/ioutil"
"unicode/utf8"
"github.com/awalterschulze/gographviz/internal/token"
)
const (
NoState = -1
NumStates = 141
NumSymbols = 184
)
type Lexer struct {
src []byte
pos int
line int
column int
}
func NewLexer(src []byte) *Lexer {
lexer := &Lexer{
src: src,
pos: 0,
line: 1,
column: 1,
}
return lexer
}
func NewLexerFile(fpath string) (*Lexer, error) {
src, err := ioutil.ReadFile(fpath)
if err != nil {
return nil, err
}
return NewLexer(src), nil
}
func (l *Lexer) Scan() (tok *token.Token) {
tok = new(token.Token)
if l.pos >= len(l.src) {
tok.Type = token.EOF
tok.Pos.Offset, tok.Pos.Line, tok.Pos.Column = l.pos, l.line, l.column
return
}
start, startLine, startColumn, end := l.pos, l.line, l.column, 0
tok.Type = token.INVALID
state, rune1, size := 0, rune(-1), 0
for state != -1 {
if l.pos >= len(l.src) {
rune1 = -1
} else {
rune1, size = utf8.DecodeRune(l.src[l.pos:])
l.pos += size
}
nextState := -1
if rune1 != -1 {
nextState = TransTab[state](rune1)
}
state = nextState
if state != -1 {
switch rune1 {
case '\n':
l.line++
l.column = 1
case '\r':
l.column = 1
case '\t':
l.column += 4
default:
l.column++
}
switch {
case ActTab[state].Accept != -1:
tok.Type = ActTab[state].Accept
end = l.pos
case ActTab[state].Ignore != "":
start, startLine, startColumn = l.pos, l.line, l.column
state = 0
if start >= len(l.src) {
tok.Type = token.EOF
}
}
} else {
if tok.Type == token.INVALID {
end = l.pos
}
}
}
if end > start {
l.pos = end
tok.Lit = l.src[start:end]
} else {
tok.Lit = []byte{}
}
tok.Pos.Offset, tok.Pos.Line, tok.Pos.Column = start, startLine, startColumn
return
}
func (l *Lexer) Reset() {
l.pos = 0
}
/*
Lexer symbols:
0: 'n'
1: 'o'
2: 'd'
3: 'e'
4: 'N'
5: 'o'
6: 'd'
7: 'e'
8: 'N'
9: 'O'
10: 'D'
11: 'E'
12: 'e'
13: 'd'
14: 'g'
15: 'e'
16: 'E'
17: 'd'
18: 'g'
19: 'e'
20: 'E'
21: 'D'
22: 'G'
23: 'E'
24: 'g'
25: 'r'
26: 'a'
27: 'p'
28: 'h'
29: 'G'
30: 'r'
31: 'a'
32: 'p'
33: 'h'
34: 'G'
35: 'R'
36: 'A'
37: 'P'
38: 'H'
39: 'd'
40: 'i'
41: 'g'
42: 'r'
43: 'a'
44: 'p'
45: 'h'
46: 'D'
47: 'i'
48: 'g'
49: 'r'
50: 'a'
51: 'p'
52: 'h'
53: 'd'
54: 'i'
55: 'G'
56: 'r'
57: 'a'
58: 'p'
59: 'h'
60: 'D'
61: 'i'
62: 'G'
63: 'r'
64: 'a'
65: 'p'
66: 'h'
67: 'D'
68: 'I'
69: 'G'
70: 'R'
71: 'A'
72: 'P'
73: 'H'
74: 's'
75: 'u'
76: 'b'
77: 'g'
78: 'r'
79: 'a'
80: 'p'
81: 'h'
82: 'S'
83: 'u'
84: 'b'
85: 'g'
86: 'r'
87: 'a'
88: 'p'
89: 'h'
90: 's'
91: 'u'
92: 'b'
93: 'G'
94: 'r'
95: 'a'
96: 'p'
97: 'h'
98: 'S'
99: 'u'
100: 'b'
101: 'G'
102: 'r'
103: 'a'
104: 'p'
105: 'h'
106: 'S'
107: 'U'
108: 'B'
109: 'G'
110: 'R'
111: 'A'
112: 'P'
113: 'H'
114: 's'
115: 't'
116: 'r'
117: 'i'
118: 'c'
119: 't'
120: 'S'
121: 't'
122: 'r'
123: 'i'
124: 'c'
125: 't'
126: 'S'
127: 'T'
128: 'R'
129: 'I'
130: 'C'
131: 'T'
132: '{'
133: '}'
134: ';'
135: '='
136: '['
137: ']'
138: ','
139: ':'
140: '-'
141: '>'
142: '-'
143: '-'
144: '_'
145: '-'
146: '.'
147: '-'
148: '.'
149: '\'
150: '"'
151: '\'
152: '"'
153: '"'
154: '='
155: '<'
156: '>'
157: '<'
158: '>'
159: '/'
160: '/'
161: '\n'
162: '#'
163: '\n'
164: '/'
165: '*'
166: '*'
167: '*'
168: '/'
169: ' '
170: '\t'
171: '\r'
172: '\n'
173: \u0001-'!'
174: '#'-'['
175: ']'-\u007f
176: 'a'-'z'
177: 'A'-'Z'
178: '0'-'9'
179: \u0080-\ufffc
180: \ufffe-\U0010ffff
181: \u0001-';'
182: '?'-\u00ff
183: .
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
// Code generated by gocc; DO NOT EDIT.
package parser
import (
"fmt"
)
type action interface {
act()
String() string
}
type (
accept bool
shift int // value is next state index
reduce int // value is production index
)
func (this accept) act() {}
func (this shift) act() {}
func (this reduce) act() {}
func (this accept) Equal(that action) bool {
if _, ok := that.(accept); ok {
return true
}
return false
}
func (this reduce) Equal(that action) bool {
that1, ok := that.(reduce)
if !ok {
return false
}
return this == that1
}
func (this shift) Equal(that action) bool {
that1, ok := that.(shift)
if !ok {
return false
}
return this == that1
}
func (this accept) String() string { return "accept(0)" }
func (this shift) String() string { return fmt.Sprintf("shift:%d", this) }
func (this reduce) String() string {
return fmt.Sprintf("reduce:%d(%s)", this, productionsTable[this].String)
}

View File

@@ -0,0 +1,152 @@
// Code generated by gocc; DO NOT EDIT.
package parser
import (
"bytes"
"compress/gzip"
"encoding/gob"
)
type (
actionTable [numStates]actionRow
actionRow struct {
canRecover bool
actions [numSymbols]action
}
)
var actionTab = actionTable{}
func init() {
tab := []struct {
CanRecover bool
Actions []struct {
Index int
Action int
Amount int
}
}{}
data := []byte{
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9c, 0x97, 0x4f, 0x88, 0x5b, 0x55,
0x1b, 0xc6, 0xcf, 0x7b, 0xe7, 0x7e, 0xd3, 0xf9, 0x66, 0xa6, 0xa5, 0x0c, 0xf3, 0x85, 0x61, 0x18,
0x86, 0x10, 0xc2, 0x10, 0x42, 0x08, 0x21, 0x0c, 0x21, 0xe4, 0x8b, 0x21, 0x8e, 0x65, 0xd0, 0x21,
0x84, 0x10, 0x42, 0x08, 0x31, 0x86, 0x9a, 0xa6, 0x21, 0x0d, 0xf1, 0x36, 0x4c, 0xd3, 0xa1, 0xe0,
0x1f, 0x6a, 0xad, 0xda, 0x95, 0xb8, 0x70, 0xe1, 0xca, 0xa5, 0x0b, 0x17, 0x22, 0xe2, 0x42, 0x5c,
0x88, 0x0b, 0xe9, 0x42, 0x5c, 0xba, 0x10, 0x17, 0x22, 0x2e, 0x5c, 0x89, 0xb8, 0x10, 0x11, 0x17,
0xbd, 0x72, 0xcf, 0x2f, 0x3d, 0x99, 0xd4, 0xc9, 0xe4, 0x26, 0x74, 0x71, 0x6e, 0x4e, 0xef, 0xf3,
0x7b, 0x9e, 0x73, 0xce, 0x7b, 0xce, 0x3d, 0x73, 0xd1, 0x7d, 0xdb, 0x12, 0xcb, 0x7d, 0xa0, 0xc4,
0xbd, 0xa7, 0x54, 0xc4, 0x7d, 0x7d, 0x49, 0x2c, 0xf7, 0x9e, 0x12, 0x4b, 0x56, 0x9f, 0x79, 0xd1,
0x29, 0x5f, 0xbf, 0x76, 0xf3, 0xe4, 0xfa, 0xb1, 0x58, 0x4a, 0x2e, 0x3c, 0x7d, 0x6d, 0x78, 0xe3,
0xa6, 0x73, 0x4b, 0xdc, 0xb7, 0x94, 0x52, 0x4f, 0xb9, 0x6f, 0x5a, 0x22, 0xf1, 0xe7, 0x5f, 0xb8,
0x35, 0x3c, 0xbe, 0x7d, 0x6d, 0x18, 0x7c, 0x39, 0xf8, 0x9c, 0xd3, 0xbe, 0x7e, 0x27, 0x78, 0xc3,
0x19, 0xfe, 0x3f, 0xc8, 0x9b, 0xa3, 0xe7, 0x97, 0x6e, 0xde, 0x76, 0x86, 0xde, 0x73, 0xf0, 0x55,
0x4f, 0x2a, 0xee, 0x7d, 0xa5, 0x62, 0xee, 0x1b, 0x9e, 0xcd, 0x7d, 0x25, 0x4b, 0xf2, 0x1f, 0x2d,
0x14, 0x5b, 0xc9, 0x32, 0x3a, 0x1e, 0xb5, 0x4c, 0x6c, 0xa5, 0xd4, 0xa3, 0xff, 0x3d, 0x74, 0x1f,
0x28, 0xf7, 0xae, 0xb5, 0x24, 0xb6, 0xf7, 0x4f, 0xc9, 0xaa, 0xd8, 0xb2, 0xac, 0x64, 0x5d, 0x6c,
0x59, 0x51, 0xca, 0x12, 0xb1, 0x94, 0xb2, 0x2c, 0x59, 0x16, 0x5b, 0x56, 0x95, 0x84, 0xc5, 0x96,
0x4b, 0xba, 0xc3, 0x7b, 0xfd, 0x32, 0xef, 0x6d, 0x98, 0x37, 0x36, 0xc7, 0x6f, 0x5c, 0xd0, 0x6f,
0x6c, 0x29, 0xdd, 0xbf, 0xad, 0x64, 0x45, 0x6c, 0xd9, 0x51, 0xb2, 0x21, 0xb6, 0xc4, 0x95, 0x6c,
0x8a, 0x2d, 0x09, 0x25, 0xbb, 0x62, 0xcb, 0x3e, 0x9a, 0x94, 0x36, 0xf3, 0x5e, 0x4e, 0x8f, 0x9e,
0x2c, 0x39, 0x31, 0xe0, 0xcc, 0x69, 0x6b, 0xaf, 0x23, 0x77, 0xbe, 0xd3, 0x81, 0x2f, 0xa7, 0x43,
0xfd, 0x14, 0x10, 0x5b, 0x8e, 0x94, 0xb2, 0x96, 0x9f, 0xe0, 0xcc, 0x00, 0x58, 0xde, 0x3f, 0xa5,
0xac, 0x8b, 0x62, 0x8b, 0x25, 0x57, 0x95, 0x4e, 0x7c, 0xd5, 0xb3, 0xd7, 0xcd, 0x25, 0x9a, 0xcb,
0x62, 0x4b, 0xd1, 0x63, 0xe9, 0x5f, 0x9b, 0x34, 0x01, 0x9a, 0x1d, 0xb1, 0xa5, 0xec, 0x91, 0xf5,
0xaf, 0x20, 0x4d, 0x88, 0x26, 0xac, 0x9b, 0xb3, 0x07, 0x57, 0x99, 0x91, 0xed, 0x82, 0x4e, 0x14,
0x22, 0x51, 0x88, 0x44, 0x21, 0x32, 0x84, 0xc8, 0x10, 0xc2, 0x35, 0x84, 0x4f, 0x48, 0x29, 0x6b,
0x45, 0x6b, 0xf6, 0xd0, 0xec, 0xa1, 0xd9, 0xf3, 0x46, 0x61, 0x4b, 0x0d, 0xe9, 0x1e, 0xd2, 0x3d,
0xa4, 0x7b, 0x48, 0xf7, 0x8c, 0x34, 0x86, 0x34, 0x86, 0x34, 0xc6, 0x04, 0xc4, 0x90, 0xc6, 0x90,
0xc6, 0x90, 0xc6, 0x90, 0xc6, 0x8c, 0x34, 0x8e, 0x34, 0x8e, 0x34, 0x8e, 0x34, 0x8e, 0x34, 0x8e,
0x34, 0x8e, 0x34, 0x8e, 0x34, 0x6e, 0xa4, 0x09, 0xa4, 0x09, 0xa4, 0x09, 0xa4, 0x09, 0xa4, 0x09,
0xa4, 0x09, 0xa4, 0x09, 0xa4, 0x09, 0xa5, 0xac, 0x55, 0x2d, 0x4d, 0x22, 0x4d, 0x22, 0x4d, 0x22,
0x4d, 0x22, 0x4d, 0x22, 0x4d, 0x22, 0x4d, 0x7a, 0x8b, 0x63, 0x4b, 0xd3, 0x5b, 0x1c, 0xfb, 0xf1,
0xe2, 0x24, 0x27, 0x6a, 0x67, 0xfc, 0xb4, 0xa6, 0xe1, 0x0d, 0xe0, 0x0d, 0xe0, 0x0d, 0xe0, 0x0d,
0xe0, 0x0d, 0xe0, 0x0d, 0x35, 0xd2, 0x68, 0x8f, 0xc6, 0x59, 0x1e, 0x0d, 0x53, 0xee, 0xbd, 0x71,
0xb9, 0x53, 0x6f, 0x27, 0x6a, 0xb4, 0x43, 0xb4, 0xc1, 0x09, 0x06, 0x27, 0x5e, 0xbd, 0xe9, 0x66,
0x83, 0x66, 0x93, 0x26, 0x40, 0xb3, 0x43, 0xb3, 0x4b, 0x13, 0xa4, 0x09, 0xd1, 0x84, 0x47, 0xdb,
0xed, 0xac, 0x7a, 0x73, 0x7c, 0xd4, 0xdb, 0x93, 0x9a, 0x63, 0x5f, 0x1b, 0x70, 0x9a, 0xe3, 0x1d,
0x5f, 0xea, 0x57, 0xcc, 0x3e, 0xdc, 0x98, 0xc2, 0x79, 0x6d, 0x81, 0xe4, 0xee, 0xdd, 0x19, 0xa2,
0xff, 0xea, 0x05, 0xd8, 0x67, 0x01, 0xf6, 0x59, 0x80, 0x7d, 0x16, 0x60, 0x9f, 0x99, 0xdf, 0x67,
0xe6, 0xf7, 0x59, 0x61, 0xef, 0x28, 0xde, 0xe5, 0x67, 0x58, 0x37, 0xde, 0xa2, 0x6e, 0x79, 0xff,
0xf1, 0x00, 0xa8, 0xfb, 0xce, 0xb4, 0x28, 0xef, 0xce, 0x9c, 0x07, 0xad, 0x7f, 0xcf, 0xd4, 0x5d,
0x8b, 0x54, 0x2d, 0x52, 0xb5, 0x48, 0xd5, 0x22, 0x55, 0x8b, 0x54, 0x2d, 0xea, 0xa1, 0x45, 0xa8,
0x16, 0x85, 0xd0, 0xa2, 0x10, 0x5a, 0x44, 0x6c, 0x8d, 0xd1, 0xef, 0x9b, 0x39, 0x5e, 0x35, 0x27,
0x4b, 0x18, 0x93, 0x30, 0x26, 0x61, 0xe8, 0x61, 0xe8, 0x61, 0xb0, 0x61, 0x40, 0x61, 0xa3, 0x89,
0xa0, 0x89, 0xa0, 0x89, 0xa0, 0x89, 0xa0, 0x89, 0xa0, 0x89, 0xa0, 0x89, 0x98, 0xc1, 0x94, 0xd0,
0x94, 0xd0, 0x94, 0x18, 0x4c, 0x09, 0x69, 0x09, 0x69, 0x69, 0x62, 0x13, 0x95, 0xce, 0xda, 0x44,
0x25, 0xa5, 0xac, 0x25, 0x3d, 0xab, 0xee, 0x07, 0x4c, 0xa0, 0xfb, 0xa1, 0x1a, 0x0f, 0x6e, 0x49,
0x7b, 0x1c, 0x03, 0x38, 0x46, 0x72, 0x6c, 0xfa, 0x87, 0xf4, 0x0f, 0xe9, 0x1f, 0x9a, 0xd5, 0x4f,
0x11, 0x2d, 0x45, 0xb4, 0x14, 0xd1, 0x52, 0x44, 0x4b, 0x11, 0x2d, 0x35, 0xb9, 0xfa, 0x29, 0x10,
0xe3, 0x02, 0x4a, 0x83, 0x48, 0x83, 0x48, 0x83, 0x48, 0x83, 0x48, 0x83, 0x48, 0x4f, 0x22, 0xd2,
0x20, 0xd2, 0x06, 0xd1, 0x04, 0xd1, 0x04, 0xd1, 0x04, 0xd1, 0x04, 0xd1, 0x04, 0xd1, 0x9c, 0x44,
0x34, 0x41, 0x34, 0xcd, 0x1c, 0x17, 0x40, 0x14, 0x40, 0x14, 0x40, 0x14, 0x40, 0x14, 0x40, 0x14,
0x26, 0xe6, 0xb8, 0x70, 0xd6, 0x1c, 0x17, 0xa6, 0x15, 0xf0, 0x47, 0xbe, 0x36, 0xb2, 0xfb, 0xb1,
0xa9, 0xb2, 0xe5, 0x69, 0xa4, 0x4f, 0x7c, 0x7d, 0x90, 0xed, 0x69, 0xf2, 0x4f, 0x17, 0x39, 0x09,
0x3e, 0xf3, 0xe5, 0xb9, 0x39, 0x4d, 0xfe, 0xf9, 0x22, 0x9e, 0x5f, 0xf8, 0xf2, 0xdc, 0x36, 0x4f,
0x81, 0x69, 0xa0, 0x2f, 0x67, 0x80, 0x46, 0x67, 0xd0, 0x57, 0xa7, 0xce, 0x20, 0x5b, 0x5f, 0x57,
0xdc, 0xaf, 0x95, 0x6c, 0x89, 0x25, 0xcf, 0x2a, 0xd9, 0xa6, 0x09, 0xeb, 0xe6, 0x71, 0xd5, 0x65,
0x28, 0x99, 0x0c, 0x25, 0x93, 0xa1, 0x64, 0x32, 0x94, 0x4c, 0x86, 0x92, 0xc9, 0x70, 0xc6, 0x64,
0x28, 0x99, 0x0c, 0x84, 0x8c, 0xde, 0x55, 0xda, 0xf4, 0xa1, 0x87, 0xb6, 0xc5, 0xfd, 0xe6, 0x94,
0xf9, 0x92, 0x36, 0x3d, 0xc0, 0xf4, 0x00, 0xc9, 0xc1, 0x28, 0x94, 0xfe, 0x44, 0x6d, 0xd1, 0x6c,
0x4f, 0x7e, 0xb0, 0xf8, 0x98, 0x77, 0xc9, 0xd4, 0x25, 0x53, 0x97, 0x4c, 0x5d, 0x32, 0x75, 0xc9,
0xd4, 0x25, 0x4c, 0x97, 0x03, 0xaf, 0xcb, 0x81, 0xd7, 0x05, 0xd4, 0x35, 0x17, 0x8a, 0x28, 0xa0,
0x28, 0xa0, 0x28, 0xa0, 0x28, 0xa0, 0x28, 0xa0, 0x28, 0xa0, 0x28, 0xd2, 0xa8, 0x91, 0x4e, 0xfb,
0x24, 0x4f, 0x7e, 0x8b, 0x77, 0x27, 0xe3, 0xaf, 0x6b, 0x69, 0x1b, 0x69, 0x1b, 0x69, 0x1b, 0x69,
0x1b, 0x69, 0x1b, 0x69, 0x9b, 0x29, 0x6d, 0x73, 0x6d, 0x74, 0xbf, 0x85, 0xd4, 0x66, 0x34, 0x6d,
0x46, 0xd3, 0x86, 0xdb, 0x36, 0x5c, 0x7f, 0x91, 0xe6, 0xb8, 0x1e, 0x50, 0x01, 0x65, 0xb0, 0x65,
0xb0, 0x65, 0xb0, 0x65, 0xb0, 0x65, 0xb0, 0xe5, 0xc9, 0x73, 0xa7, 0x0c, 0xa2, 0x7c, 0xfe, 0x59,
0x3c, 0xd7, 0x0d, 0x7c, 0xfd, 0xdc, 0x7b, 0xf7, 0xc2, 0x17, 0x6e, 0x8e, 0xc5, 0x2a, 0xd8, 0x2a,
0xd8, 0x2a, 0xd8, 0x2a, 0xd8, 0x2a, 0xd8, 0x2a, 0xd8, 0x2a, 0xbc, 0x2a, 0xbc, 0x2a, 0xbc, 0x2a,
0xbc, 0xaa, 0xe1, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55,
0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xe0, 0x55, 0xcc, 0x7d, 0xd0, 0xfd, 0x6e, 0x7c, 0x21, 0x64,
0x4d, 0x8a, 0x38, 0x14, 0x71, 0x28, 0xe2, 0x30, 0xfa, 0xcb, 0xa3, 0x88, 0x43, 0x71, 0x72, 0x4d,
0x8a, 0x40, 0x8b, 0x66, 0x13, 0x39, 0x20, 0x1c, 0x10, 0x0e, 0x08, 0x07, 0x84, 0x03, 0xc2, 0x41,
0xea, 0x90, 0xce, 0x21, 0x9d, 0x03, 0xc8, 0x99, 0x76, 0x12, 0x7d, 0xbf, 0xc8, 0x39, 0xf8, 0x83,
0xaf, 0x73, 0x70, 0xdd, 0x3c, 0x5d, 0x32, 0x4f, 0x2b, 0xd3, 0x90, 0x3f, 0xfa, 0x42, 0xee, 0x9a,
0xa7, 0xad, 0x69, 0xa0, 0x9f, 0x7c, 0x81, 0x76, 0xcc, 0xda, 0xe4, 0x98, 0xd8, 0x1c, 0x13, 0x9b,
0x63, 0x62, 0x73, 0x4c, 0x6c, 0x8e, 0x89, 0xcd, 0xb1, 0xfa, 0x39, 0xe6, 0x37, 0xc7, 0x8c, 0xe6,
0xc6, 0x27, 0xe6, 0xcf, 0x67, 0x9c, 0x98, 0xa3, 0x2b, 0xda, 0x2f, 0xc6, 0x27, 0x8b, 0x4f, 0x16,
0x9f, 0x2c, 0x3e, 0x59, 0x7c, 0xb2, 0xf8, 0x64, 0xf1, 0xc9, 0xe2, 0x93, 0xc5, 0x27, 0x6b, 0x8e,
0xdf, 0x2b, 0x9c, 0xaf, 0x57, 0xe8, 0xbf, 0x32, 0x36, 0x39, 0xe5, 0xf7, 0xab, 0xa9, 0xea, 0x3a,
0x7e, 0x75, 0xfc, 0xea, 0xf8, 0xd5, 0xf1, 0xab, 0xe3, 0x57, 0xc7, 0xaf, 0x8e, 0x5f, 0x9d, 0xba,
0xa9, 0x53, 0x37, 0x75, 0x5c, 0xea, 0x86, 0x57, 0x83, 0x57, 0x83, 0x57, 0x83, 0x37, 0xfa, 0xf3,
0xb3, 0x06, 0xaf, 0x06, 0xaf, 0x06, 0xaf, 0x06, 0xaf, 0x06, 0xaf, 0x06, 0xaf, 0x36, 0x6d, 0xd9,
0x7e, 0x5b, 0xa4, 0x0e, 0x7f, 0xf7, 0x77, 0x83, 0xf9, 0xc3, 0xec, 0xa2, 0x1e, 0x83, 0xe8, 0x31,
0x88, 0x1e, 0x83, 0xe8, 0x31, 0x88, 0x1e, 0x83, 0xe8, 0x91, 0xbe, 0x47, 0xfa, 0x1e, 0xe9, 0x7b,
0xa4, 0xef, 0x19, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x60, 0xda, 0x88, 0xfe, 0xf4, 0x55, 0xbd, 0x97, 0xcd, 0x53,
0xd0, 0xd4, 0x57, 0x9e, 0x44, 0x79, 0x12, 0xe5, 0x49, 0x94, 0x27, 0x51, 0x9e, 0x44, 0x79, 0xd6,
0x27, 0x4f, 0xb0, 0x3c, 0x51, 0xf2, 0xa6, 0xbe, 0x8e, 0xa8, 0xaf, 0x23, 0xfa, 0x8f, 0x4c, 0xff,
0xbf, 0xbf, 0xeb, 0xf4, 0x1f, 0xd2, 0x7f, 0x48, 0xff, 0xa1, 0xa9, 0x94, 0x0e, 0x49, 0x3a, 0x24,
0xe9, 0x90, 0xa4, 0x43, 0x92, 0x0e, 0x49, 0x3a, 0x24, 0xe9, 0x90, 0xa4, 0xc3, 0x14, 0x75, 0x98,
0xa2, 0x0e, 0xbc, 0x8e, 0xe1, 0xcd, 0xf5, 0xa1, 0x3c, 0xf7, 0x0b, 0xb9, 0x36, 0xc7, 0x7d, 0x24,
0xe0, 0xe3, 0x5a, 0xb2, 0x36, 0xc7, 0xd1, 0x1c, 0x58, 0xf4, 0x84, 0xfe, 0x6b, 0x91, 0x9d, 0xf1,
0xf7, 0x0c, 0x11, 0x55, 0xdc, 0x27, 0x79, 0x9f, 0xe4, 0x7d, 0x92, 0xf7, 0x49, 0xde, 0x27, 0x79,
0x9f, 0xc8, 0x7d, 0x22, 0xf7, 0x89, 0xdc, 0x27, 0x72, 0xdf, 0x4c, 0x81, 0xbf, 0x7d, 0x15, 0xf0,
0xb1, 0xbd, 0xd6, 0xe6, 0xd8, 0x5e, 0x81, 0x45, 0x77, 0xd9, 0xa3, 0x19, 0xb3, 0xb3, 0x36, 0xc7,
0xec, 0x04, 0x66, 0x4f, 0xd2, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x47, 0x5c, 0x26, 0x6b,
0x16, 0x00, 0x00,
}
buf, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
panic(err)
}
dec := gob.NewDecoder(buf)
if err := dec.Decode(&tab); err != nil {
panic(err)
}
for i, row := range tab {
actionTab[i].canRecover = row.CanRecover
for _, a := range row.Actions {
switch a.Action {
case 0:
actionTab[i].actions[a.Index] = accept(true)
case 1:
actionTab[i].actions[a.Index] = reduce(a.Amount)
case 2:
actionTab[i].actions[a.Index] = shift(a.Amount)
}
}
}
}

View File

@@ -0,0 +1,56 @@
// Code generated by gocc; DO NOT EDIT.
package parser
import (
"bytes"
"compress/gzip"
"encoding/gob"
)
const numNTSymbols = 17
type (
gotoTable [numStates]gotoRow
gotoRow [numNTSymbols]int
)
var gotoTab = gotoTable{}
func init() {
tab := [][]int{}
data := []byte{
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe2, 0xfd, 0xdf, 0xcd, 0xc4, 0xc8,
0xf4, 0xbf, 0x87, 0x81, 0xf1, 0x7f, 0x17, 0x03, 0x03, 0xcf, 0xff, 0x4e, 0x10, 0xaf, 0x8b, 0x81,
0x91, 0x85, 0x81, 0xe1, 0x1f, 0xa7, 0xc6, 0xff, 0x1e, 0x86, 0xff, 0x0d, 0x82, 0x8c, 0x4c, 0x8c,
0xa8, 0x40, 0x90, 0x11, 0x1d, 0x60, 0x88, 0xf0, 0x10, 0xa1, 0x46, 0x4c, 0x90, 0x91, 0x51, 0x41,
0x49, 0x45, 0x8b, 0x91, 0x91, 0x51, 0x83, 0x51, 0xcd, 0x88, 0x51, 0x87, 0x51, 0x8e, 0x08, 0x5d,
0x98, 0x22, 0x36, 0x18, 0x22, 0x0e, 0x82, 0x8c, 0x8c, 0x2e, 0x44, 0x9a, 0xec, 0x81, 0x22, 0xe2,
0x43, 0x9a, 0x7b, 0x02, 0xa0, 0x22, 0x61, 0x94, 0xfb, 0x82, 0x54, 0x91, 0x28, 0x10, 0x11, 0x03,
0x13, 0x49, 0xc2, 0x50, 0x93, 0x82, 0x21, 0x92, 0xc6, 0xc8, 0xc8, 0x98, 0x81, 0xa2, 0x0b, 0x01,
0x72, 0xb0, 0xda, 0x55, 0x80, 0x11, 0x1a, 0x25, 0x44, 0x84, 0x4f, 0x15, 0x79, 0x71, 0x8a, 0x11,
0x86, 0xff, 0x9b, 0x88, 0x35, 0xe8, 0x7f, 0xd7, 0xff, 0x1e, 0x18, 0xb3, 0x8d, 0x88, 0xf8, 0xf8,
0x3f, 0x89, 0x08, 0x47, 0xfd, 0x9f, 0x46, 0x51, 0x1c, 0xfd, 0x9f, 0x05, 0x37, 0x68, 0x0e, 0xaa,
0xaa, 0xff, 0x4b, 0x18, 0xff, 0x2f, 0x62, 0xfc, 0xbf, 0x80, 0xe6, 0xc9, 0xe4, 0xff, 0x0a, 0x54,
0x27, 0xfc, 0x5f, 0x43, 0xa5, 0x98, 0x21, 0x46, 0xcd, 0xff, 0x6d, 0xc4, 0x58, 0x86, 0xa9, 0x6d,
0x0f, 0x35, 0xdd, 0xf8, 0xff, 0x10, 0x5a, 0xc2, 0x20, 0x32, 0xe4, 0x18, 0x19, 0xff, 0x9f, 0x20,
0x4f, 0x1f, 0xbd, 0x45, 0xfe, 0x5f, 0x60, 0xfc, 0x7f, 0x0e, 0x92, 0x98, 0xfe, 0x5f, 0xc2, 0x17,
0x74, 0x01, 0xe4, 0xda, 0xf7, 0xff, 0x1a, 0xf9, 0x39, 0xf8, 0x0e, 0x15, 0x8a, 0x77, 0x0a, 0x0a,
0x58, 0x0a, 0x8a, 0x65, 0x7c, 0xf1, 0xff, 0xff, 0x09, 0x69, 0x46, 0xbd, 0xc0, 0x63, 0xd4, 0x2b,
0xf2, 0x03, 0xf7, 0xd3, 0xc0, 0x06, 0xee, 0x60, 0x13, 0xc1, 0x0c, 0xa0, 0x3f, 0xf4, 0x0a, 0x20,
0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xfa, 0xd1, 0x1a, 0x46, 0x09, 0x00, 0x00,
}
buf, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
panic(err)
}
dec := gob.NewDecoder(buf)
if err := dec.Decode(&tab); err != nil {
panic(err)
}
for i := 0; i < numStates; i++ {
for j := 0; j < numNTSymbols; j++ {
gotoTab[i][j] = tab[i][j]
}
}
}

View File

@@ -0,0 +1,72 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//A parser for the DOT grammar.
package parser
import (
"fmt"
"io"
"io/ioutil"
"os"
"github.com/awalterschulze/gographviz/ast"
"github.com/awalterschulze/gographviz/internal/lexer"
)
//Parses a DOT string and outputs the
//abstract syntax tree representing the graph.
func ParseString(dotString string) (*ast.Graph, error) {
return ParseBytes([]byte(dotString))
}
//Parses the bytes representing a DOT string
//and outputs the abstract syntax tree representing the graph.
func ParseBytes(dotBytes []byte) (*ast.Graph, error) {
lex := lexer.NewLexer(dotBytes)
parser := NewParser()
st, err := parser.Parse(lex)
if err != nil {
return nil, err
}
g, ok := st.(*ast.Graph)
if !ok {
panic(fmt.Sprintf("Parser did not return an *ast.Graph, but rather a %T", st))
}
return g, nil
}
//Parses a reader which contains a DOT string
//and outputs the abstract syntax tree representing the graph.
func Parse(r io.Reader) (*ast.Graph, error) {
bytes, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return ParseBytes(bytes)
}
//Parses a file which contains a DOT string
//and outputs the abstract syntax tree representing the graph.
func ParseFile(filename string) (*ast.Graph, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
g, err := Parse(f)
if err := f.Close(); err != nil {
return nil, err
}
return g, err
}

View File

@@ -0,0 +1,216 @@
// Code generated by gocc; DO NOT EDIT.
package parser
import (
"bytes"
"fmt"
parseError "github.com/awalterschulze/gographviz/internal/errors"
"github.com/awalterschulze/gographviz/internal/token"
)
const (
numProductions = 60
numStates = 128
numSymbols = 36
)
// Stack
type stack struct {
state []int
attrib []Attrib
}
const iNITIAL_STACK_SIZE = 100
func newStack() *stack {
return &stack{
state: make([]int, 0, iNITIAL_STACK_SIZE),
attrib: make([]Attrib, 0, iNITIAL_STACK_SIZE),
}
}
func (s *stack) reset() {
s.state = s.state[:0]
s.attrib = s.attrib[:0]
}
func (s *stack) push(state int, a Attrib) {
s.state = append(s.state, state)
s.attrib = append(s.attrib, a)
}
func (s *stack) top() int {
return s.state[len(s.state)-1]
}
func (s *stack) peek(pos int) int {
return s.state[pos]
}
func (s *stack) topIndex() int {
return len(s.state) - 1
}
func (s *stack) popN(items int) []Attrib {
lo, hi := len(s.state)-items, len(s.state)
attrib := s.attrib[lo:hi]
s.state = s.state[:lo]
s.attrib = s.attrib[:lo]
return attrib
}
func (s *stack) String() string {
w := new(bytes.Buffer)
fmt.Fprintf(w, "stack:\n")
for i, st := range s.state {
fmt.Fprintf(w, "\t%d: %d , ", i, st)
if s.attrib[i] == nil {
fmt.Fprintf(w, "nil")
} else {
switch attr := s.attrib[i].(type) {
case *token.Token:
fmt.Fprintf(w, "%s", attr.Lit)
default:
fmt.Fprintf(w, "%v", attr)
}
}
fmt.Fprintf(w, "\n")
}
return w.String()
}
// Parser
type Parser struct {
stack *stack
nextToken *token.Token
pos int
}
type Scanner interface {
Scan() (tok *token.Token)
}
func NewParser() *Parser {
p := &Parser{stack: newStack()}
p.Reset()
return p
}
func (p *Parser) Reset() {
p.stack.reset()
p.stack.push(0, nil)
}
func (p *Parser) Error(err error, scanner Scanner) (recovered bool, errorAttrib *parseError.Error) {
errorAttrib = &parseError.Error{
Err: err,
ErrorToken: p.nextToken,
ErrorSymbols: p.popNonRecoveryStates(),
ExpectedTokens: make([]string, 0, 8),
}
for t, action := range actionTab[p.stack.top()].actions {
if action != nil {
errorAttrib.ExpectedTokens = append(errorAttrib.ExpectedTokens, token.TokMap.Id(token.Type(t)))
}
}
if action := actionTab[p.stack.top()].actions[token.TokMap.Type("error")]; action != nil {
p.stack.push(int(action.(shift)), errorAttrib) // action can only be shift
} else {
return
}
if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil {
recovered = true
}
for !recovered && p.nextToken.Type != token.EOF {
p.nextToken = scanner.Scan()
if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil {
recovered = true
}
}
return
}
func (p *Parser) popNonRecoveryStates() (removedAttribs []parseError.ErrorSymbol) {
if rs, ok := p.firstRecoveryState(); ok {
errorSymbols := p.stack.popN(p.stack.topIndex() - rs)
removedAttribs = make([]parseError.ErrorSymbol, len(errorSymbols))
for i, e := range errorSymbols {
removedAttribs[i] = e
}
} else {
removedAttribs = []parseError.ErrorSymbol{}
}
return
}
// recoveryState points to the highest state on the stack, which can recover
func (p *Parser) firstRecoveryState() (recoveryState int, canRecover bool) {
recoveryState, canRecover = p.stack.topIndex(), actionTab[p.stack.top()].canRecover
for recoveryState > 0 && !canRecover {
recoveryState--
canRecover = actionTab[p.stack.peek(recoveryState)].canRecover
}
return
}
func (p *Parser) newError(err error) error {
e := &parseError.Error{
Err: err,
StackTop: p.stack.top(),
ErrorToken: p.nextToken,
}
actRow := actionTab[p.stack.top()]
for i, t := range actRow.actions {
if t != nil {
e.ExpectedTokens = append(e.ExpectedTokens, token.TokMap.Id(token.Type(i)))
}
}
return e
}
func (p *Parser) Parse(scanner Scanner) (res interface{}, err error) {
p.Reset()
p.nextToken = scanner.Scan()
for acc := false; !acc; {
action := actionTab[p.stack.top()].actions[p.nextToken.Type]
if action == nil {
if recovered, errAttrib := p.Error(nil, scanner); !recovered {
p.nextToken = errAttrib.ErrorToken
return nil, p.newError(nil)
}
if action = actionTab[p.stack.top()].actions[p.nextToken.Type]; action == nil {
panic("Error recovery led to invalid action")
}
}
switch act := action.(type) {
case accept:
res = p.stack.popN(1)[0]
acc = true
case shift:
p.stack.push(int(act), p.nextToken)
p.nextToken = scanner.Scan()
case reduce:
prod := productionsTable[int(act)]
attrib, err := prod.ReduceFunc(p.stack.popN(prod.NumSymbols))
if err != nil {
return nil, p.newError(err)
} else {
p.stack.push(gotoTab[p.stack.top()][prod.NTType], attrib)
}
default:
panic("unknown action: " + action.String())
}
}
return res, nil
}

View File

@@ -0,0 +1,623 @@
// Code generated by gocc; DO NOT EDIT.
package parser
import "github.com/awalterschulze/gographviz/ast"
type (
//TODO: change type and variable names to be consistent with other tables
ProdTab [numProductions]ProdTabEntry
ProdTabEntry struct {
String string
Id string
NTType int
Index int
NumSymbols int
ReduceFunc func([]Attrib) (Attrib, error)
}
Attrib interface {
}
)
var productionsTable = ProdTab{
ProdTabEntry{
String: `S' : DotGraph << >>`,
Id: "S'",
NTType: 0,
Index: 0,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `DotGraph : graphx "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 1,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.FALSE, nil, nil)
},
},
ProdTabEntry{
String: `DotGraph : strict graphx "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 2,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.TRUE, nil, nil)
},
},
ProdTabEntry{
String: `DotGraph : graphx Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, X[1], nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 3,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.FALSE, X[1], nil)
},
},
ProdTabEntry{
String: `DotGraph : strict graphx Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, X[2], nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 4,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.TRUE, X[2], nil)
},
},
ProdTabEntry{
String: `DotGraph : graphx "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, X[2]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 5,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.FALSE, nil, X[2])
},
},
ProdTabEntry{
String: `DotGraph : graphx Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, X[1], X[3]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 6,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.FALSE, X[1], X[3])
},
},
ProdTabEntry{
String: `DotGraph : strict graphx "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, X[3]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 7,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.TRUE, nil, X[3])
},
},
ProdTabEntry{
String: `DotGraph : strict graphx Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, X[2], X[4]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 8,
NumSymbols: 6,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.GRAPH, ast.TRUE, X[2], X[4])
},
},
ProdTabEntry{
String: `DotGraph : digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 9,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, nil)
},
},
ProdTabEntry{
String: `DotGraph : strict digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 10,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, nil)
},
},
ProdTabEntry{
String: `DotGraph : digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, X[1], nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 11,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.FALSE, X[1], nil)
},
},
ProdTabEntry{
String: `DotGraph : strict digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, X[2], nil) >>`,
Id: "DotGraph",
NTType: 1,
Index: 12,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.TRUE, X[2], nil)
},
},
ProdTabEntry{
String: `DotGraph : digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, X[2]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 13,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, X[2])
},
},
ProdTabEntry{
String: `DotGraph : digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, X[1], X[3]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 14,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.FALSE, X[1], X[3])
},
},
ProdTabEntry{
String: `DotGraph : strict digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, X[3]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 15,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, X[3])
},
},
ProdTabEntry{
String: `DotGraph : strict digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, X[2], X[4]) >>`,
Id: "DotGraph",
NTType: 1,
Index: 16,
NumSymbols: 6,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraph(ast.DIGRAPH, ast.TRUE, X[2], X[4])
},
},
ProdTabEntry{
String: `StmtList : Stmt1 << ast.NewStmtList(X[0]) >>`,
Id: "StmtList",
NTType: 2,
Index: 17,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewStmtList(X[0])
},
},
ProdTabEntry{
String: `StmtList : StmtList Stmt1 << ast.AppendStmtList(X[0], X[1]) >>`,
Id: "StmtList",
NTType: 2,
Index: 18,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendStmtList(X[0], X[1])
},
},
ProdTabEntry{
String: `Stmt1 : Stmt << X[0], nil >>`,
Id: "Stmt1",
NTType: 3,
Index: 19,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `Stmt1 : Stmt ";" << X[0], nil >>`,
Id: "Stmt1",
NTType: 3,
Index: 20,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `Stmt : Id "=" Id << ast.NewAttr(X[0], X[2]) >>`,
Id: "Stmt",
NTType: 4,
Index: 21,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAttr(X[0], X[2])
},
},
ProdTabEntry{
String: `Stmt : NodeStmt << X[0], nil >>`,
Id: "Stmt",
NTType: 4,
Index: 22,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `Stmt : EdgeStmt << X[0], nil >>`,
Id: "Stmt",
NTType: 4,
Index: 23,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `Stmt : AttrStmt << X[0], nil >>`,
Id: "Stmt",
NTType: 4,
Index: 24,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `Stmt : SubGraphStmt << X[0], nil >>`,
Id: "Stmt",
NTType: 4,
Index: 25,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return X[0], nil
},
},
ProdTabEntry{
String: `AttrStmt : graphx AttrList << ast.NewGraphAttrs(X[1]) >>`,
Id: "AttrStmt",
NTType: 5,
Index: 26,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewGraphAttrs(X[1])
},
},
ProdTabEntry{
String: `AttrStmt : node AttrList << ast.NewNodeAttrs(X[1]) >>`,
Id: "AttrStmt",
NTType: 5,
Index: 27,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewNodeAttrs(X[1])
},
},
ProdTabEntry{
String: `AttrStmt : edge AttrList << ast.NewEdgeAttrs(X[1]) >>`,
Id: "AttrStmt",
NTType: 5,
Index: 28,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeAttrs(X[1])
},
},
ProdTabEntry{
String: `AttrList : "[" "]" << ast.NewAttrList(nil) >>`,
Id: "AttrList",
NTType: 6,
Index: 29,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAttrList(nil)
},
},
ProdTabEntry{
String: `AttrList : "[" AList "]" << ast.NewAttrList(X[1]) >>`,
Id: "AttrList",
NTType: 6,
Index: 30,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAttrList(X[1])
},
},
ProdTabEntry{
String: `AttrList : AttrList "[" "]" << ast.AppendAttrList(X[0], nil) >>`,
Id: "AttrList",
NTType: 6,
Index: 31,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendAttrList(X[0], nil)
},
},
ProdTabEntry{
String: `AttrList : AttrList "[" AList "]" << ast.AppendAttrList(X[0], X[2]) >>`,
Id: "AttrList",
NTType: 6,
Index: 32,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendAttrList(X[0], X[2])
},
},
ProdTabEntry{
String: `AList : Attr << ast.NewAList(X[0]) >>`,
Id: "AList",
NTType: 7,
Index: 33,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAList(X[0])
},
},
ProdTabEntry{
String: `AList : AList Attr << ast.AppendAList(X[0], X[1]) >>`,
Id: "AList",
NTType: 7,
Index: 34,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendAList(X[0], X[1])
},
},
ProdTabEntry{
String: `AList : AList "," Attr << ast.AppendAList(X[0], X[2]) >>`,
Id: "AList",
NTType: 7,
Index: 35,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendAList(X[0], X[2])
},
},
ProdTabEntry{
String: `Attr : Id << ast.NewAttr(X[0], nil) >>`,
Id: "Attr",
NTType: 8,
Index: 36,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAttr(X[0], nil)
},
},
ProdTabEntry{
String: `Attr : Id "=" Id << ast.NewAttr(X[0], X[2]) >>`,
Id: "Attr",
NTType: 8,
Index: 37,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewAttr(X[0], X[2])
},
},
ProdTabEntry{
String: `EdgeStmt : NodeId EdgeRHS << ast.NewEdgeStmt(X[0], X[1], nil) >>`,
Id: "EdgeStmt",
NTType: 9,
Index: 38,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeStmt(X[0], X[1], nil)
},
},
ProdTabEntry{
String: `EdgeStmt : NodeId EdgeRHS AttrList << ast.NewEdgeStmt(X[0], X[1], X[2]) >>`,
Id: "EdgeStmt",
NTType: 9,
Index: 39,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeStmt(X[0], X[1], X[2])
},
},
ProdTabEntry{
String: `EdgeStmt : SubGraphStmt EdgeRHS << ast.NewEdgeStmt(X[0], X[1], nil) >>`,
Id: "EdgeStmt",
NTType: 9,
Index: 40,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeStmt(X[0], X[1], nil)
},
},
ProdTabEntry{
String: `EdgeStmt : SubGraphStmt EdgeRHS AttrList << ast.NewEdgeStmt(X[0], X[1], X[2]) >>`,
Id: "EdgeStmt",
NTType: 9,
Index: 41,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeStmt(X[0], X[1], X[2])
},
},
ProdTabEntry{
String: `EdgeRHS : EdgeOp NodeId << ast.NewEdgeRHS(X[0], X[1]) >>`,
Id: "EdgeRHS",
NTType: 10,
Index: 42,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeRHS(X[0], X[1])
},
},
ProdTabEntry{
String: `EdgeRHS : EdgeOp SubGraphStmt << ast.NewEdgeRHS(X[0], X[1]) >>`,
Id: "EdgeRHS",
NTType: 10,
Index: 43,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewEdgeRHS(X[0], X[1])
},
},
ProdTabEntry{
String: `EdgeRHS : EdgeRHS EdgeOp NodeId << ast.AppendEdgeRHS(X[0], X[1], X[2]) >>`,
Id: "EdgeRHS",
NTType: 10,
Index: 44,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendEdgeRHS(X[0], X[1], X[2])
},
},
ProdTabEntry{
String: `EdgeRHS : EdgeRHS EdgeOp SubGraphStmt << ast.AppendEdgeRHS(X[0], X[1], X[2]) >>`,
Id: "EdgeRHS",
NTType: 10,
Index: 45,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.AppendEdgeRHS(X[0], X[1], X[2])
},
},
ProdTabEntry{
String: `NodeStmt : NodeId << ast.NewNodeStmt(X[0], nil) >>`,
Id: "NodeStmt",
NTType: 11,
Index: 46,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewNodeStmt(X[0], nil)
},
},
ProdTabEntry{
String: `NodeStmt : NodeId AttrList << ast.NewNodeStmt(X[0], X[1]) >>`,
Id: "NodeStmt",
NTType: 11,
Index: 47,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewNodeStmt(X[0], X[1])
},
},
ProdTabEntry{
String: `NodeId : Id << ast.NewNodeID(X[0], nil) >>`,
Id: "NodeId",
NTType: 12,
Index: 48,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewNodeID(X[0], nil)
},
},
ProdTabEntry{
String: `NodeId : Id Port << ast.NewNodeID(X[0], X[1]) >>`,
Id: "NodeId",
NTType: 12,
Index: 49,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewNodeID(X[0], X[1])
},
},
ProdTabEntry{
String: `Port : ":" Id << ast.NewPort(X[1], nil), nil >>`,
Id: "Port",
NTType: 13,
Index: 50,
NumSymbols: 2,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewPort(X[1], nil), nil
},
},
ProdTabEntry{
String: `Port : ":" Id ":" Id << ast.NewPort(X[1], X[3]), nil >>`,
Id: "Port",
NTType: 13,
Index: 51,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewPort(X[1], X[3]), nil
},
},
ProdTabEntry{
String: `SubGraphStmt : "{" StmtList "}" << ast.NewSubGraph(nil, X[1]) >>`,
Id: "SubGraphStmt",
NTType: 14,
Index: 52,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewSubGraph(nil, X[1])
},
},
ProdTabEntry{
String: `SubGraphStmt : subgraph "{" StmtList "}" << ast.NewSubGraph(nil, X[2]) >>`,
Id: "SubGraphStmt",
NTType: 14,
Index: 53,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewSubGraph(nil, X[2])
},
},
ProdTabEntry{
String: `SubGraphStmt : subgraph Id "{" StmtList "}" << ast.NewSubGraph(X[1], X[3]) >>`,
Id: "SubGraphStmt",
NTType: 14,
Index: 54,
NumSymbols: 5,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewSubGraph(X[1], X[3])
},
},
ProdTabEntry{
String: `SubGraphStmt : subgraph "{" "}" << ast.NewSubGraph(nil, nil) >>`,
Id: "SubGraphStmt",
NTType: 14,
Index: 55,
NumSymbols: 3,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewSubGraph(nil, nil)
},
},
ProdTabEntry{
String: `SubGraphStmt : subgraph Id "{" "}" << ast.NewSubGraph(X[1], nil) >>`,
Id: "SubGraphStmt",
NTType: 14,
Index: 56,
NumSymbols: 4,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewSubGraph(X[1], nil)
},
},
ProdTabEntry{
String: `EdgeOp : "->" << ast.DIRECTED, nil >>`,
Id: "EdgeOp",
NTType: 15,
Index: 57,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.DIRECTED, nil
},
},
ProdTabEntry{
String: `EdgeOp : "--" << ast.UNDIRECTED, nil >>`,
Id: "EdgeOp",
NTType: 15,
Index: 58,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.UNDIRECTED, nil
},
},
ProdTabEntry{
String: `Id : id << ast.NewID(X[0]) >>`,
Id: "Id",
NTType: 16,
Index: 59,
NumSymbols: 1,
ReduceFunc: func(X []Attrib) (Attrib, error) {
return ast.NewID(X[0])
},
},
}

View File

@@ -0,0 +1,104 @@
// Code generated by gocc; DO NOT EDIT.
package token
import (
"fmt"
)
type Token struct {
Type
Lit []byte
Pos
}
type Type int
const (
INVALID Type = iota
EOF
)
type Pos struct {
Offset int
Line int
Column int
}
func (p Pos) String() string {
return fmt.Sprintf("Pos(offset=%d, line=%d, column=%d)", p.Offset, p.Line, p.Column)
}
type TokenMap struct {
typeMap []string
idMap map[string]Type
}
func (m TokenMap) Id(tok Type) string {
if int(tok) < len(m.typeMap) {
return m.typeMap[tok]
}
return "unknown"
}
func (m TokenMap) Type(tok string) Type {
if typ, exist := m.idMap[tok]; exist {
return typ
}
return INVALID
}
func (m TokenMap) TokenString(tok *Token) string {
//TODO: refactor to print pos & token string properly
return fmt.Sprintf("%s(%d,%s)", m.Id(tok.Type), tok.Type, tok.Lit)
}
func (m TokenMap) StringType(typ Type) string {
return fmt.Sprintf("%s(%d)", m.Id(typ), typ)
}
var TokMap = TokenMap{
typeMap: []string{
"INVALID",
"$",
"graphx",
"{",
"}",
"strict",
"digraph",
";",
"=",
"node",
"edge",
"[",
"]",
",",
":",
"subgraph",
"->",
"--",
"id",
},
idMap: map[string]Type{
"INVALID": 0,
"$": 1,
"graphx": 2,
"{": 3,
"}": 4,
"strict": 5,
"digraph": 6,
";": 7,
"=": 8,
"node": 9,
"edge": 10,
"[": 11,
"]": 12,
",": 13,
":": 14,
"subgraph": 15,
"->": 16,
"--": 17,
"id": 18,
},
}

78
vendor/github.com/awalterschulze/gographviz/nodes.go generated vendored Normal file
View File

@@ -0,0 +1,78 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"fmt"
"sort"
)
// Node represents a Node.
type Node struct {
Name string
Attrs Attrs
}
// Nodes represents a set of Nodes.
type Nodes struct {
Lookup map[string]*Node
Nodes []*Node
}
// NewNodes creates a new set of Nodes.
func NewNodes() *Nodes {
return &Nodes{make(map[string]*Node), make([]*Node, 0)}
}
// Remove removes a node
func (nodes *Nodes) Remove(name string) error {
for i := 0; i < len(nodes.Nodes); i++ {
if nodes.Nodes[i].Name != name {
continue
}
nodes.Nodes = append(nodes.Nodes[:i], nodes.Nodes[i+1:]...)
delete(nodes.Lookup, name)
return nil
}
return fmt.Errorf("node %s not found", name)
}
// Add adds a Node to the set of Nodes, extending the attributes of an already existing node.
func (nodes *Nodes) Add(node *Node) {
n, ok := nodes.Lookup[node.Name]
if ok {
n.Attrs.Extend(node.Attrs)
return
}
nodes.Lookup[node.Name] = node
nodes.Nodes = append(nodes.Nodes, node)
}
// Sorted returns a sorted list of nodes.
func (nodes Nodes) Sorted() []*Node {
keys := make([]string, 0, len(nodes.Lookup))
for key := range nodes.Lookup {
keys = append(keys, key)
}
sort.Strings(keys)
nodeList := make([]*Node, len(keys))
for i := range keys {
nodeList[i] = nodes.Lookup[keys[i]]
}
return nodeList
}

View File

@@ -0,0 +1,64 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"sort"
)
// Relations represents the relations between graphs and nodes.
// Each node belongs the main graph or a subgraph.
type Relations struct {
ParentToChildren map[string]map[string]bool
ChildToParents map[string]map[string]bool
}
// NewRelations creates an empty set of relations.
func NewRelations() *Relations {
return &Relations{make(map[string]map[string]bool), make(map[string]map[string]bool)}
}
// Add adds a node to a parent graph.
func (relations *Relations) Add(parent string, child string) {
if _, ok := relations.ParentToChildren[parent]; !ok {
relations.ParentToChildren[parent] = make(map[string]bool)
}
relations.ParentToChildren[parent][child] = true
if _, ok := relations.ChildToParents[child]; !ok {
relations.ChildToParents[child] = make(map[string]bool)
}
relations.ChildToParents[child][parent] = true
}
// Remove removes relation
func (relations *Relations) Remove(parent string, child string) {
if _, ok := relations.ParentToChildren[parent]; ok {
delete(relations.ParentToChildren[parent], child)
}
if _, ok := relations.ChildToParents[child]; ok {
delete(relations.ChildToParents[child], parent)
}
}
// SortedChildren returns a list of sorted children of the given parent graph.
func (relations *Relations) SortedChildren(parent string) []string {
keys := make([]string, 0)
for key := range relations.ParentToChildren[parent] {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}

View File

@@ -0,0 +1,69 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"sort"
)
// SubGraph represents a Subgraph.
type SubGraph struct {
Attrs Attrs
Name string
}
// NewSubGraph creates a new Subgraph.
func NewSubGraph(name string) *SubGraph {
return &SubGraph{
Attrs: make(Attrs),
Name: name,
}
}
// SubGraphs represents a set of SubGraphs.
type SubGraphs struct {
SubGraphs map[string]*SubGraph
}
// NewSubGraphs creates a new blank set of SubGraphs.
func NewSubGraphs() *SubGraphs {
return &SubGraphs{make(map[string]*SubGraph)}
}
// Add adds and creates a new Subgraph to the set of SubGraphs.
func (subgraphs *SubGraphs) Add(name string) {
if _, ok := subgraphs.SubGraphs[name]; !ok {
subgraphs.SubGraphs[name] = NewSubGraph(name)
}
}
// Remove removes a subgraph
func (subgraphs *SubGraphs) Remove(name string) {
delete(subgraphs.SubGraphs, name)
}
// Sorted returns a sorted list of SubGraphs.
func (subgraphs *SubGraphs) Sorted() []*SubGraph {
keys := make([]string, 0)
for key := range subgraphs.SubGraphs {
keys = append(keys, key)
}
sort.Strings(keys)
s := make([]*SubGraph, len(keys))
for i, key := range keys {
s[i] = subgraphs.SubGraphs[key]
}
return s
}

172
vendor/github.com/awalterschulze/gographviz/write.go generated vendored Normal file
View File

@@ -0,0 +1,172 @@
//Copyright 2013 GoGraphviz Authors
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package gographviz
import (
"fmt"
"github.com/awalterschulze/gographviz/ast"
)
type writer struct {
*Graph
writtenLocations map[string]bool
}
func newWriter(g *Graph) *writer {
return &writer{g, make(map[string]bool)}
}
func appendAttrs(list ast.StmtList, attrs Attrs) ast.StmtList {
for _, name := range attrs.sortedNames() {
stmt := &ast.Attr{
Field: ast.ID(name),
Value: ast.ID(attrs[name]),
}
list = append(list, stmt)
}
return list
}
func (w *writer) newSubGraph(name string) (*ast.SubGraph, error) {
sub := w.SubGraphs.SubGraphs[name]
w.writtenLocations[sub.Name] = true
s := &ast.SubGraph{}
s.ID = ast.ID(sub.Name)
s.StmtList = appendAttrs(s.StmtList, sub.Attrs)
children := w.Relations.SortedChildren(name)
for _, child := range children {
if w.IsNode(child) {
s.StmtList = append(s.StmtList, w.newNodeStmt(child))
} else if w.IsSubGraph(child) {
subgraph, err := w.newSubGraph(child)
if err != nil {
return nil, err
}
s.StmtList = append(s.StmtList, subgraph)
} else {
return nil, fmt.Errorf("%v is not a node or a subgraph", child)
}
}
return s, nil
}
func (w *writer) newNodeID(name string, port string) *ast.NodeID {
node := w.Nodes.Lookup[name]
return ast.MakeNodeID(node.Name, port)
}
func (w *writer) newNodeStmt(name string) *ast.NodeStmt {
node := w.Nodes.Lookup[name]
id := ast.MakeNodeID(node.Name, "")
w.writtenLocations[node.Name] = true
return &ast.NodeStmt{
NodeID: id,
Attrs: ast.PutMap(node.Attrs.toMap()),
}
}
func (w *writer) newLocation(name string, port string) (ast.Location, error) {
if w.IsNode(name) {
return w.newNodeID(name, port), nil
} else if w.isClusterSubGraph(name) {
if len(port) != 0 {
return nil, fmt.Errorf("subgraph cannot have a port: %v", port)
}
return ast.MakeNodeID(name, port), nil
} else if w.IsSubGraph(name) {
if len(port) != 0 {
return nil, fmt.Errorf("subgraph cannot have a port: %v", port)
}
return w.newSubGraph(name)
}
return nil, fmt.Errorf("%v is not a node or a subgraph", name)
}
func (w *writer) newEdgeStmt(edge *Edge) (*ast.EdgeStmt, error) {
src, err := w.newLocation(edge.Src, edge.SrcPort)
if err != nil {
return nil, err
}
dst, err := w.newLocation(edge.Dst, edge.DstPort)
if err != nil {
return nil, err
}
stmt := &ast.EdgeStmt{
Source: src,
EdgeRHS: ast.EdgeRHS{
&ast.EdgeRH{
Op: ast.EdgeOp(edge.Dir),
Destination: dst,
},
},
Attrs: ast.PutMap(edge.Attrs.toMap()),
}
return stmt, nil
}
func (w *writer) Write() (*ast.Graph, error) {
t := &ast.Graph{}
t.Strict = w.Strict
t.Type = ast.GraphType(w.Directed)
t.ID = ast.ID(w.Name)
t.StmtList = appendAttrs(t.StmtList, w.Attrs)
for _, edge := range w.Edges.Edges {
e, err := w.newEdgeStmt(edge)
if err != nil {
return nil, err
}
t.StmtList = append(t.StmtList, e)
}
subGraphs := w.SubGraphs.Sorted()
for _, s := range subGraphs {
if _, ok := w.writtenLocations[s.Name]; !ok {
if _, ok := w.Relations.ParentToChildren[w.Name][s.Name]; ok {
s, err := w.newSubGraph(s.Name)
if err != nil {
return nil, err
}
t.StmtList = append(t.StmtList, s)
}
}
}
nodes := w.Nodes.Sorted()
for _, n := range nodes {
if _, ok := w.writtenLocations[n.Name]; !ok {
t.StmtList = append(t.StmtList, w.newNodeStmt(n.Name))
}
}
return t, nil
}
// WriteAst creates an Abstract Syntrax Tree from the Graph.
func (g *Graph) WriteAst() (*ast.Graph, error) {
w := newWriter(g)
return w.Write()
}
// String returns a DOT string representing the Graph.
func (g *Graph) String() string {
w, err := g.WriteAst()
if err != nil {
return fmt.Sprintf("error: %v", err)
}
return w.String()
}