mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
210 lines
10 KiB
BNF
210 lines
10 KiB
BNF
//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 http://www.graphviz.org/content/dot-language
|
|
//The rules have been copied and are shown in the comments, with their derived bnf rules below.
|
|
|
|
//graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'
|
|
DotGraph
|
|
: Graph "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, nil) >>
|
|
| Strict Graph "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, nil) >>
|
|
| Graph Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, nil) >>
|
|
| Strict Graph Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, $2, nil) >>
|
|
| Graph "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, $2) >>
|
|
| Graph Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, $3) >>
|
|
| Strict Graph "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, $3) >>
|
|
| Strict Graph 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
|
|
: Graph 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) >>
|
|
| ":" Id ":" Id << ast.NewPort($1, $3) >>
|
|
;
|
|
|
|
//subgraph : [ subgraph [ ID ] ] '{' stmt_list '}'
|
|
SubGraphStmt
|
|
: "{" StmtList "}" << ast.NewSubGraph(nil, $1) >>
|
|
| Subgraph "{" StmtList "}" << ast.NewSubGraph(nil, $2) >>
|
|
| Subgraph Id "{" StmtList "}" << ast.NewSubGraph($1, $3) >>
|
|
;
|
|
|
|
//An edgeop is -> in directed graphs and -- in undirected graphs.
|
|
EdgeOp
|
|
: "->" << ast.DIRECTED, nil >>
|
|
| "--" << ast.UNDIRECTED, nil >>
|
|
;
|
|
|
|
//The keywords node, edge, graph, digraph, subgraph, and strict are case-independent.
|
|
Graph
|
|
: "graph" << $0, nil >>
|
|
| "Graph" << $0, nil >>
|
|
| "GRAPH" << $0, nil >>
|
|
;
|
|
|
|
Strict
|
|
: "strict" << $0, nil >>
|
|
| "Strict" << $0, nil >>
|
|
| "STRICT" << $0, nil >>
|
|
;
|
|
|
|
Digraph
|
|
: "digraph" << $0, nil >>
|
|
| "Digraph" << $0, nil >>
|
|
| "DiGraph" << $0, nil >>
|
|
| "DIGRAPH" << $0, nil >>
|
|
;
|
|
|
|
Node
|
|
: "node" << $0, nil >>
|
|
| "Node" << $0, nil >>
|
|
| "NODE" << $0, nil >>
|
|
;
|
|
|
|
Edge
|
|
: "edge" << $0, nil >>
|
|
| "Edge" << $0, nil >>
|
|
| "EDGE" << $0, nil >>
|
|
;
|
|
|
|
Subgraph
|
|
: "subgraph" << $0, nil >>
|
|
| "Subgraph" << $0, nil >>
|
|
| "SubGraph" << $0, nil >>
|
|
| "SUBGRAPH" << $0, nil >>
|
|
;
|
|
|
|
// An ID is one of the following:
|
|
// Any string of alphabetic ([a-zA-Z'200-'377]) characters, underscores ('_') or digits ([0-9]), not beginning with a digit; //CHECK 200-377
|
|
// a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
|
|
// any double-quoted string ("...") possibly containing escaped quotes ('")1; //TODO
|
|
// an HTML string (<...>).
|
|
// An ID is just a string; the lack of quote characters in the first two forms is just for simplicity.
|
|
// There is no semantic difference between abc_2 and "abc_2", or between 2.34 and "2.34".
|
|
// Obviously, to use a keyword as an ID, it must be quoted. Note that, in HTML strings, angle brackets must occur in matched pairs, and unescaped newlines are allowed.
|
|
// In addition, the content must be legal XML, so that the special XML escape sequences for ", &, <, and > may be necessary in order to embed these characters in attribute values or raw text.
|
|
// Both quoted strings and HTML strings are scanned as a unit, so any embedded comments will be treated as part of the strings.
|
|
Id
|
|
: id << ast.NewId($0) >>
|
|
| string_lit << ast.NewId($0) >>
|
|
| int_lit << ast.NewId($0) >>
|
|
| float_lit << ast.NewId($0) >>
|
|
| html_lit << ast.NewId($0) >>
|
|
;
|
|
|
|
//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.
|
|
|
|
//TODO (if dot file is not parsable, it might be because of these points)
|
|
|
|
//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.
|
|
|
|
//TODO
|
|
//As another aid for readability, dot allows single logical lines to span multiple physical lines using the standard C convention of a backslash immediately preceding a newline character.
|
|
//In addition, double-quoted strings can be concatenated using a '+' operator. As HTML strings can contain newline characters, they do not support the concatenation operator.
|
|
|
|
//TODO
|
|
//Note there are still 3 sections on the webpage which have not been included (Subgraphs and Clusters, Lexical and Semantic Notes, and Character Encodings)
|