-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
maintained dot syntax and dot pretty printer
- Loading branch information
1 parent
1679a10
commit fc35a33
Showing
2 changed files
with
102 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,112 +7,65 @@ | |
} | ||
@contributor{Bert Lisser - [email protected]} | ||
|
||
@synopsis{AST and pretty printer for the Dot language.} | ||
@description{ | ||
This model of the DOT language is for generative purposes. | ||
If you need to parse DOT files, have a look at ((lang::dot::syntax::Dot)) instead. | ||
} | ||
module lang::dot::Dot | ||
import String; | ||
import Set; | ||
import Map; | ||
|
||
public alias Id = str; | ||
|
||
@synopsis{Abstract Data Type of Dot language} | ||
|
||
public data DotGraph = graph(Id id, Stms stmts) | digraph(Id id, Stms stmts); | ||
|
||
public alias Stms = list[Stm]; | ||
|
||
public alias NodeId = tuple[Id, PortId]; | ||
|
||
public alias PortId = tuple[Id, CompassPt]; | ||
@synopsis{Abstract Syntax for the Dot language} | ||
data DotGraph = graph(str id, list[Stm] stmts) | digraph(str id, list[Stm] stmts); | ||
|
||
public data CompassPt = N()|NE()|E()|SE()|S()|SW()|W()|NW()|C()|_(); | ||
alias NodeId = tuple[str, PortId]; | ||
|
||
alias PortId = tuple[str, CompassPt]; | ||
|
||
data CompassPt = N() | NE() | E() | SE() | S() | SW() | W() | NW() | C() | \_(); | ||
|
||
public data Stm | ||
= N(Id id, Attrs attrs) | ||
| N(Id id) | ||
data Stm | ||
= N(str id, Attrs attrs) | ||
| N(str id) | ||
| N(NodeId nid, Attrs attrs) | ||
| N(NodeId nid) | ||
| E(Id from, Id to, Attrs attrs) | ||
| E(Id from, Id to) | ||
| E(str from, str to, Attrs attrs) | ||
| E(str from, str to) | ||
| E(NodeId nfrom, Id to, Attrs attrs) | ||
| E(NodeId nfrom, Id to) | ||
| E(Stm sfrom, Id to, Attrs attrs) | ||
| E(Stm sfrom, Id to) | ||
| E(Id from, NodeId nto, Attrs attrs) | ||
| E(NodeId nfrom, str to) | ||
| E(Stm sfrom, str to, Attrs attrs) | ||
| E(Stm sfrom, str to) | ||
| E(str from, NodeId nto, Attrs attrs) | ||
| E(Id from, NodeId nto) | ||
| E(NodeId nfrom, NodeId nto, Attrs attrs) | ||
| E(NodeId nfrom, NodeId nto) | ||
| E(Stm sfrom, NodeId nto, Attrs attrs) | ||
| E(Stm sfrom, NodeId nto) | ||
| E(Id from, Stm sto, Attrs attrs) | ||
| E(Id from, Stm sto) | ||
| E(str from, Stm sto, Attrs attrs) | ||
| E(str from, Stm sto) | ||
| E(NodeId nfrom, Stm sto, Attrs attrs) | ||
| E(NodeId nfrom, Stm sto) | ||
| E(Stm sfrom, Stm sto, Attrs attrs) | ||
| E(Stm sfrom, Stm sto) | ||
| S(Id id, Stms stms) | ||
| S(Stms stms) | ||
| A(Id prop, Id val) | ||
| S(str id, list[Stm] stms) | ||
| S(list[Stm] stms) | ||
| A(str prop, str val) | ||
| GRAPH(Attrs attrs) | ||
| NODE(Attrs attrs) | ||
| EDGE(Attrs attrs) | ||
; | ||
|
||
public alias Attr = tuple[str prop, Id val]; | ||
|
||
public alias Attrs = list[Attr]; | ||
|
||
public alias Outline = map[int key, list[str] args]; | ||
|
||
public alias Dotline = tuple[DotGraph graph, Outline outline]; | ||
|
||
|
||
@synopsis{Dummy function call needed to tag initialized global variables of type DotGraph. | ||
It is possible to select that variable on the outline menu of the Rascal Editor. | ||
An application is for example to display dotgraphs.} | ||
|
||
public DotGraph export(DotGraph g) {return g;} | ||
|
||
public Dotline export(Dotline g) {return g;} | ||
|
||
public bool hasOutline(Dotline _) {return true;} | ||
|
||
public bool hasOutline(DotGraph _) {return false;} | ||
|
||
public Outline currentOutline; | ||
|
||
public void setCurrentOutline(Dotline current) { | ||
currentOutline = current.outline; | ||
} | ||
alias Attrs = lrel[str prop, str val]; | ||
|
||
@synopsis{Translates DotGraph to String input for dot} | ||
str toString(digraph(Id id,Stms stms)) | ||
str toString(digraph(str id,list[Stm] stms)) | ||
= "digraph <id> {<for (x<-stms) {> | ||
'<oStm(x)>;<}> | ||
'} | ||
'"; | ||
|
||
str toString(Dotline g) = toString(g.graph); | ||
|
||
list[value] getChildren(value key) { | ||
if (int k:=key) { | ||
if (k==-1) | ||
return toList(domain(currentOutline)); | ||
return currentOutline[k]; | ||
} | ||
return []; | ||
} | ||
|
||
private str reLabel(str prop, str val) { | ||
if (prop=="label") { | ||
return "\"<replaceAll(val,"\"","\\\"")>\""; | ||
} | ||
|
||
return val; | ||
} | ||
|
||
private str oAttrs(Attrs attrs) = "[<for (y<-attrs) {> <y.prop>=<reLabel(y.prop, y.val)>,<}>]"; | ||
private str oAttrs(lrel[str prop, str val] attrs) = "[<for (<prop,val> <- attrs) {> <prop>=<reLabel(prop, val)>,<}>]"; | ||
|
||
private str oCompassPt(N()) = "n"; | ||
private str oCompassPt(NE()) = "ne"; | ||
|
@@ -131,41 +84,41 @@ str oPortId(PortId id) { | |
|
||
str oNodeId(NodeId id) = "<id[0]><oPortId(id[1])>"; | ||
|
||
str oStms(Stms stms, str sep) = "<for (y <- stms) {> <oStm(y)><sep><}>"; | ||
str oStms(list[Stm] stms, str sep) = "<for (y <- stms) {> <oStm(y)><sep><}>"; | ||
|
||
str oStm( N(Id id)) = "<id>"; | ||
str oStm( N(Id id, Attrs attrs)) = "<id><oAttrs(attrs)>"; | ||
str oStm( N(str id)) = "<id>"; | ||
str oStm( N(str id, Attrs attrs)) = "<id><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Id from, Id to)) = "<from>-\><to>"; | ||
str oStm( E(Id from, Id to, Attrs attrs)) = "<from>-\><to><oAttrs(attrs)>"; | ||
str oStm( E(str from, str to)) = "<from>-\><to>"; | ||
str oStm( E(str from, str to, Attrs attrs)) = "<from>-\><to><oAttrs(attrs)>"; | ||
|
||
str oStm( E(NodeId from, Id to)) = "<oNodeId(from)>-\><to>"; | ||
str oStm( E(Id from, Id to, Attrs attrs)) = "<from>-\><to><oAttrs(attrs)>"; | ||
str oStm( E(NodeId from, str to)) = "<oNodeId(from)>-\><to>"; | ||
str oStm( E(str from, str to, Attrs attrs)) = "<from>-\><to><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Stm from, Id to)) = "<oStm(from)>-\><to>"; | ||
str oStm( E(Stm from, Id to, Attrs attrs)) = "<oStm(from)>-\><to><oAttrs(attrs)>"; | ||
str oStm( E(Stm from, str to)) = "<oStm(from)>-\><to>"; | ||
str oStm( E(Stm from, str to, Attrs attrs)) = "<oStm(from)>-\><to><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Id from, NodeId to)) = "<from>-\><oNodeId(to)>"; | ||
str oStm( E(Id from, NodeId to, Attrs attrs)) = "<from>-\><oNodeId(to)><oAttrs(attrs)>"; | ||
str oStm( E(str from, NodeId to)) = "<from>-\><oNodeId(to)>"; | ||
str oStm( E(str from, NodeId to, Attrs attrs)) = "<from>-\><oNodeId(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( E(NodeId from, NodeId to)) = "<oNodeId(from)>-\><oNodeId(to)>"; | ||
str oStm( E(Id from, NodeId to, Attrs attrs)) = "<from>-\><oNodeId(to)><oAttrs(attrs)>"; | ||
str oStm( E(str from, NodeId to, Attrs attrs)) = "<from>-\><oNodeId(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Stm from, NodeId to)) = "<oStm(from)>-\><oNodeId(to)>"; | ||
str oStm( E(Stm from, NodeId to, Attrs attrs)) = "<oStm(from)>-\><oNodeId(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Id from, Stm to)) = "<from>-\><oStm(to)>"; | ||
str oStm( E(Id from, Stm to, Attrs attrs)) = "<from>-\><oStm(to)><oAttrs(attrs)>"; | ||
str oStm( E(str from, Stm to)) = "<from>-\><oStm(to)>"; | ||
str oStm( E(str from, Stm to, Attrs attrs)) = "<from>-\><oStm(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( E(NodeId from, Stm to)) = "<oNodeId(from)>-\><oStm(to)>"; | ||
str oStm( E(Id from, Stm to, Attrs attrs)) = "<from>-\><oStm(to)><oAttrs(attrs)>"; | ||
str oStm( E(str from, Stm to, Attrs attrs)) = "<from>-\><oStm(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( E(Stm from, Stm to)) = "<oStm(from)>-\><oStm(to)>"; | ||
str oStm( E(Stm from, Stm to, Attrs attrs)) = "<oStm(from)>-\><oStm(to)><oAttrs(attrs)>"; | ||
|
||
str oStm( S(Stms stms)) = "subgraph {<oStms(stms,";")>} "; | ||
str oStm( S(Id id, Stms stms)) = "subgraph <id> {<oStms(stms,";")>} "; | ||
str oStm( A(Id prop, Id val)) = "<prop> = <val>"; | ||
str oStm( S(list[Stm] stms)) = "subgraph {<oStms(stms,";")>} "; | ||
str oStm( S(str id, list[Stm] stms)) = "subgraph <id> {<oStms(stms,";")>} "; | ||
str oStm( A(str prop, str val)) = "<prop> = <val>"; | ||
str oStm( GRAPH(Attrs attrs)) = "graph <oAttrs(attrs)>"; | ||
str oStm( EDGE(Attrs attrs)) = "edge <oAttrs(attrs)>"; | ||
str oStm( NODE(Attrs attrs)) = "node <oAttrs(attrs)>"; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,35 +5,48 @@ | |
which accompanies this distribution, and is available at | ||
http://www.eclipse.org/legal/epl-v10.html | ||
} | ||
@synopsis{Grammar for AT&T's Graphviz DOT language.} | ||
@contributor{Bert Lisser - [email protected]} | ||
|
||
module lang::dot::\syntax::Dot | ||
|
||
start syntax DOT = LAYOUT* Graph Id "{" StatementList "}" "\n"?; | ||
|
||
keyword Reserved = "graph"|"digraph"|"node"|"edge"|"subgraph"; | ||
|
||
syntax Graph = "graph"|"digraph"|AttrTag; | ||
|
||
syntax AttrTag = "node"|"edge"|"graph"; | ||
|
||
syntax Nod = NodeId|Subgraph; | ||
|
||
lexical Id = ([A-Z a-z 0-9 _] !<< [A-Z a-z 0-9 _]+ !<< [a-z A-Z 0-9 _][a-z A-Z 0-9 _]* !>> [0-9 A-Z _ a-z]) \ Reserved | ||
| [\"] (![\"] | "\\\"")* [\"] | ||
| [\-]? "." [0-9]+ | ||
| [\-]? [0-9]+ "." [0-9]* | ||
; | ||
|
||
syntax StatementList = StatementOptional*; | ||
|
||
syntax Statement = NodeStatement | ||
|EdgeStatement | ||
|AttrStatement | ||
>Id "=" Id | ||
; | ||
|
||
syntax StatementOptional = Statement ";"?; | ||
start syntax DOT = Graph Id "{" {Statement ";"?}* statements ";"? "}"; | ||
|
||
keyword Reserved | ||
= "graph" | ||
| "digraph" | ||
| "node" | ||
| "edge" | ||
| "subgraph" | ||
; | ||
syntax Graph | ||
= "graph" | ||
| "digraph" | ||
; | ||
|
||
syntax AttrTag | ||
= "node" | ||
| "edge" | ||
| "graph" | ||
; | ||
|
||
syntax Nod | ||
= NodeId | ||
| Subgraph; | ||
|
||
lexical Id | ||
= ([A-Z a-z 0-9 _] !<< [a-z A-Z 0-9 _][a-z A-Z 0-9 _]* !>> [0-9 A-Z _ a-z]) \ Reserved | ||
| [\"] (![\"] | "\\\"")* [\"] | ||
| [\-]? "." [0-9]+ | ||
| [\-]? [0-9]+ "." [0-9]* | ||
; | ||
|
||
syntax Statement | ||
= NodeStatement | ||
| EdgeStatement | ||
| AttrStatement | ||
| Id "=" Id | ||
; | ||
|
||
syntax NodeStatement = Nod AttrList; | ||
|
||
|
@@ -45,61 +58,32 @@ syntax EdgeOp = "-\>" | "--"; | |
|
||
syntax EdgeRhs = Edg+; | ||
|
||
syntax NodeId = Id | ||
| Id Port | ||
; | ||
syntax NodeId | ||
= Id | ||
| Id Port | ||
; | ||
|
||
syntax Port = ":" Id Id? | ||
// | ":" Id | ||
// | ":" CompassPt | ||
; | ||
syntax Port = ":" Id Id?; | ||
|
||
// syntax CompassPt = "n" | "ne" | "e" | "se" | "s" | "sw" | "w"| "nw" | "c" |"_"; | ||
syntax CompassPt = "n" | "ne" | "e" | "se" | "s" | "sw" | "w"| "nw" | "c" | "_"; | ||
|
||
syntax AttrList = AttrList0*; | ||
syntax AttrList = AttrList0*; | ||
|
||
syntax AttrList0 = "[" DotAttr* "]"; | ||
|
||
syntax DotAttr = Id "=" Id | Id "=" Id "," ; | ||
|
||
syntax AttrStatement = AttrTag AttrList; | ||
|
||
syntax Subgraph = ("subgraph" Id? )? "{" StatementList "}"; | ||
|
||
lexical Comment = "/*" (![*] | [*] !>> "/")* "*/" | ||
| "//" ![\n]* $ | ||
; | ||
|
||
layout LAYOUTLIST = LAYOUT* !>> [\ \t\n\r] !>> "//" !>> "/*" | ||
; | ||
|
||
|
||
lexical LAYOUT = Whitespace: [\ \t\n\r] | ||
| @category="Comment" Comment | ||
; | ||
|
||
|
||
/* | ||
graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}' | ||
stmt_list : [ stmt [ ';' ] [ stmt_list ] ] | ||
stmt : node_stmt | ||
| edge_stmt | ||
| attr_stmt | ||
| ID '=' ID | ||
| subgraph | ||
attr_stmt : (graph | node | edge) attr_list | ||
attr_list : '[' [ a_list ] ']' [ attr_list ] | ||
a_list : ID [ '=' ID ] [ ',' ] [ a_list ] | ||
edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ] | ||
edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ] | ||
node_stmt : node_id [ attr_list ] | ||
node_id : ID [ port ] | ||
port : ':' ID [ ':' compass_pt ] | ||
| ':' compass_pt | ||
subgraph : [ subgraph [ ID ] ] '{' stmt_list '}' | ||
compass_pt : (n | ne | e | se | s | sw | w | nw | c | _) | ||
*/ | ||
syntax Subgraph = ("subgraph" Id? )? "{" {Statement ";"?}* statements ";"? "}"; | ||
|
||
lexical Comment | ||
= "/*" (![*] | [*] !>> "/")* "*/" | ||
| "//" ![\n]* $ | ||
; | ||
|
||
layout LAYOUTLIST = LAYOUT* !>> [\ \t\n\r] !>> "//" !>> "/*"; | ||
lexical LAYOUT | ||
= Whitespace: [\ \t\n\r] | ||
| @category="Comment" Comment | ||
; |