Files
gonum/graph/formats/dot/ast/ast.go
Dan Kortschak 5f0141ca4c all: run gofmt and generate all packages
Changes made in dsp/fourier/internal/fftpack break the formatting used
there, so these are reverted. There will be complaints in CI.

[git-generate]
gofmt -w .
go generate gonum.org/v1/gonum/blas
go generate gonum.org/v1/gonum/blas/gonum
go generate gonum.org/v1/gonum/unit
go generate gonum.org/v1/gonum/unit/constant
go generate gonum.org/v1/gonum/graph/formats/dot
go generate gonum.org/v1/gonum/graph/formats/rdf
go generate gonum.org/v1/gonum/stat/card

git checkout -- dsp/fourier/internal/fftpack
2022-08-06 07:05:17 +09:30

410 lines
8.7 KiB
Go

// This file is dual licensed under CC0 and The Gonum License.
//
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Copyright ©2017 Robin Eklind.
// This file is made available under a Creative Commons CC0 1.0
// Universal Public Domain Dedication.
package ast
import (
"bytes"
"fmt"
)
// === [ File ] ================================================================
// A File represents a DOT file.
//
// Examples.
//
// digraph G {
// A -> B
// }
// graph H {
// C - D
// }
type File struct {
// Graphs.
Graphs []*Graph
}
// String returns the string representation of the file.
func (f *File) String() string {
buf := new(bytes.Buffer)
for i, graph := range f.Graphs {
if i != 0 {
buf.WriteString("\n")
}
buf.WriteString(graph.String())
}
return buf.String()
}
// === [ Graphs ] ==============================================================
// A Graph represents a directed or an undirected graph.
//
// Examples.
//
// digraph G {
// A -> {B C}
// B -> C
// }
type Graph struct {
// Strict graph; multi-edges forbidden.
Strict bool
// Directed graph.
Directed bool
// Graph ID; or empty if anonymous.
ID string
// Graph statements.
Stmts []Stmt
}
// String returns the string representation of the graph.
func (g *Graph) String() string {
buf := new(bytes.Buffer)
if g.Strict {
buf.WriteString("strict ")
}
if g.Directed {
buf.WriteString("digraph ")
} else {
buf.WriteString("graph ")
}
if len(g.ID) > 0 {
fmt.Fprintf(buf, "%s ", g.ID)
}
buf.WriteString("{\n")
for _, stmt := range g.Stmts {
fmt.Fprintf(buf, "\t%s\n", stmt)
}
buf.WriteString("}")
return buf.String()
}
// === [ Statements ] ==========================================================
// A Stmt represents a statement, and has one of the following underlying types.
//
// *NodeStmt
// *EdgeStmt
// *AttrStmt
// *Attr
// *Subgraph
type Stmt interface {
fmt.Stringer
// isStmt ensures that only statements can be assigned to the Stmt interface.
isStmt()
}
// --- [ Node statement ] ------------------------------------------------------
// A NodeStmt represents a node statement.
//
// Examples.
//
// A [color=blue]
type NodeStmt struct {
// Node.
Node *Node
// Node attributes.
Attrs []*Attr
}
// String returns the string representation of the node statement.
func (e *NodeStmt) String() string {
buf := new(bytes.Buffer)
buf.WriteString(e.Node.String())
if len(e.Attrs) > 0 {
buf.WriteString(" [")
for i, attr := range e.Attrs {
if i != 0 {
buf.WriteString(" ")
}
buf.WriteString(attr.String())
}
buf.WriteString("]")
}
return buf.String()
}
// --- [ Edge statement ] ------------------------------------------------------
// An EdgeStmt represents an edge statement.
//
// Examples.
//
// A -> B
// A -> {B C}
// A -> B -> C
type EdgeStmt struct {
// Source vertex.
From Vertex
// Outgoing edge.
To *Edge
// Edge attributes.
Attrs []*Attr
}
// String returns the string representation of the edge statement.
func (e *EdgeStmt) String() string {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%s %s", e.From, e.To)
if len(e.Attrs) > 0 {
buf.WriteString(" [")
for i, attr := range e.Attrs {
if i != 0 {
buf.WriteString(" ")
}
buf.WriteString(attr.String())
}
buf.WriteString("]")
}
return buf.String()
}
// An Edge represents an edge between two vertices.
type Edge struct {
// Directed edge.
Directed bool
// Destination vertex.
Vertex Vertex
// Outgoing edge; or nil if none.
To *Edge
}
// String returns the string representation of the edge.
func (e *Edge) String() string {
op := "--"
if e.Directed {
op = "->"
}
if e.To != nil {
return fmt.Sprintf("%s %s %s", op, e.Vertex, e.To)
}
return fmt.Sprintf("%s %s", op, e.Vertex)
}
// --- [ Attribute statement ] -------------------------------------------------
// An AttrStmt represents an attribute statement.
//
// Examples.
//
// graph [rankdir=LR]
// node [color=blue fillcolor=red]
// edge [minlen=1]
type AttrStmt struct {
// Graph component kind to which the attributes are assigned.
Kind Kind
// Attributes.
Attrs []*Attr
}
// String returns the string representation of the attribute statement.
func (a *AttrStmt) String() string {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%s [", a.Kind)
for i, attr := range a.Attrs {
if i != 0 {
buf.WriteString(" ")
}
buf.WriteString(attr.String())
}
buf.WriteString("]")
return buf.String()
}
// Kind specifies the set of graph components to which attribute statements may
// be assigned.
type Kind uint
// Graph component kinds.
const (
GraphKind Kind = iota // graph
NodeKind // node
EdgeKind // edge
)
// String returns the string representation of the graph component kind.
func (k Kind) String() string {
switch k {
case GraphKind:
return "graph"
case NodeKind:
return "node"
case EdgeKind:
return "edge"
}
panic(fmt.Sprintf("invalid graph component kind (%d)", k))
}
// --- [ Attribute ] -----------------------------------------------------------
// An Attr represents an attribute.
//
// Examples.
//
// rank=same
type Attr struct {
// Attribute key.
Key string
// Attribute value.
Val string
}
// String returns the string representation of the attribute.
func (a *Attr) String() string {
return fmt.Sprintf("%s=%s", a.Key, a.Val)
}
// --- [ Subgraph ] ------------------------------------------------------------
// A Subgraph represents a subgraph vertex.
//
// Examples.
//
// subgraph S {A B C}
type Subgraph struct {
// Subgraph ID; or empty if none.
ID string
// Subgraph statements.
Stmts []Stmt
}
// String returns the string representation of the subgraph.
func (s *Subgraph) String() string {
buf := new(bytes.Buffer)
if len(s.ID) > 0 {
fmt.Fprintf(buf, "subgraph %s ", s.ID)
}
buf.WriteString("{")
for i, stmt := range s.Stmts {
if i != 0 {
buf.WriteString(" ")
}
buf.WriteString(stmt.String())
}
buf.WriteString("}")
return buf.String()
}
// isStmt ensures that only statements can be assigned to the Stmt interface.
func (*NodeStmt) isStmt() {}
func (*EdgeStmt) isStmt() {}
func (*AttrStmt) isStmt() {}
func (*Attr) isStmt() {}
func (*Subgraph) isStmt() {}
// === [ Vertices ] ============================================================
// A Vertex represents a vertex, and has one of the following underlying types.
//
// *Node
// *Subgraph
type Vertex interface {
fmt.Stringer
// isVertex ensures that only vertices can be assigned to the Vertex
// interface.
isVertex()
}
// --- [ Node identifier ] -----------------------------------------------------
// A Node represents a node vertex.
//
// Examples.
//
// A
// A:nw
type Node struct {
// Node ID.
ID string
// Node port; or nil if none.
Port *Port
}
// String returns the string representation of the node.
func (n *Node) String() string {
if n.Port != nil {
return fmt.Sprintf("%s%s", n.ID, n.Port)
}
return n.ID
}
// A Port specifies where on a node an edge should be aimed.
type Port struct {
// Port ID; or empty if none.
ID string
// Compass point.
CompassPoint CompassPoint
}
// String returns the string representation of the port.
func (p *Port) String() string {
buf := new(bytes.Buffer)
if len(p.ID) > 0 {
fmt.Fprintf(buf, ":%s", p.ID)
}
if p.CompassPoint != CompassPointNone {
fmt.Fprintf(buf, ":%s", p.CompassPoint)
}
return buf.String()
}
// CompassPoint specifies the set of compass points.
type CompassPoint uint
// Compass points.
const (
CompassPointNone CompassPoint = iota //
CompassPointNorth // n
CompassPointNorthEast // ne
CompassPointEast // e
CompassPointSouthEast // se
CompassPointSouth // s
CompassPointSouthWest // sw
CompassPointWest // w
CompassPointNorthWest // nw
CompassPointCenter // c
CompassPointDefault // _
)
// String returns the string representation of the compass point.
func (c CompassPoint) String() string {
switch c {
case CompassPointNone:
return ""
case CompassPointNorth:
return "n"
case CompassPointNorthEast:
return "ne"
case CompassPointEast:
return "e"
case CompassPointSouthEast:
return "se"
case CompassPointSouth:
return "s"
case CompassPointSouthWest:
return "sw"
case CompassPointWest:
return "w"
case CompassPointNorthWest:
return "nw"
case CompassPointCenter:
return "c"
case CompassPointDefault:
return "_"
}
panic(fmt.Sprintf("invalid compass point (%d)", uint(c)))
}
// isVertex ensures that only vertices can be assigned to the Vertex interface.
func (*Node) isVertex() {}
func (*Subgraph) isVertex() {}