github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/graph/formats/dot/internal/dot.bnf (about) 1 // The DOT Language 2 // 3 // http://www.graphviz.org/doc/info/lang.html 4 5 // ### [ Tokens ] ############################################################## 6 7 // The keywords node, edge, graph, digraph, subgraph, and strict are case- 8 // independent. 9 10 node 11 : 'n' 'o' 'd' 'e' 12 | 'N' 'o' 'd' 'e' 13 | 'N' 'O' 'D' 'E' 14 ; 15 16 edge 17 : 'e' 'd' 'g' 'e' 18 | 'E' 'd' 'g' 'e' 19 | 'E' 'D' 'G' 'E' 20 ; 21 22 // TODO: Rename graphx to graph once gocc#20 is fixed [1]. 23 // 24 // [1]: https://github.com/goccmack/gocc/issues/20 25 26 graphx 27 : 'g' 'r' 'a' 'p' 'h' 28 | 'G' 'r' 'a' 'p' 'h' 29 | 'G' 'R' 'A' 'P' 'H' 30 ; 31 32 digraph 33 : 'd' 'i' 'g' 'r' 'a' 'p' 'h' 34 | 'D' 'i' 'g' 'r' 'a' 'p' 'h' 35 | 'd' 'i' 'G' 'r' 'a' 'p' 'h' 36 | 'D' 'i' 'G' 'r' 'a' 'p' 'h' 37 | 'D' 'I' 'G' 'R' 'A' 'P' 'H' 38 ; 39 40 subgraph 41 : 's' 'u' 'b' 'g' 'r' 'a' 'p' 'h' 42 | 'S' 'u' 'b' 'g' 'r' 'a' 'p' 'h' 43 | 's' 'u' 'b' 'G' 'r' 'a' 'p' 'h' 44 | 'S' 'u' 'b' 'G' 'r' 'a' 'p' 'h' 45 | 'S' 'U' 'B' 'G' 'R' 'A' 'P' 'H' 46 ; 47 48 strict 49 : 's' 't' 'r' 'i' 'c' 't' 50 | 'S' 't' 'r' 'i' 'c' 't' 51 | 'S' 'T' 'R' 'I' 'C' 'T' 52 ; 53 54 // An arbitrary ASCII character except null (0x00), double quote (0x22) and 55 // backslash (0x5C). 56 _ascii_char 57 // skip null (0x00) 58 : '\x01' - '\x21' 59 // skip double quote (0x22) 60 | '\x23' - '\x5B' 61 // skip backslash (0x5C) 62 | '\x5D' - '\x7F' 63 ; 64 65 _ascii_letter 66 : 'a' - 'z' 67 | 'A' - 'Z' 68 ; 69 70 _ascii_digit : '0' - '9' ; 71 72 _unicode_char 73 : _ascii_char 74 | _unicode_byte 75 ; 76 77 _unicode_byte 78 : '\u0080' - '\uFFFC' 79 // skip invalid code point (\uFFFD) 80 | '\uFFFE' - '\U0010FFFF' 81 ; 82 83 _letter : _ascii_letter | _unicode_byte | '_' ; 84 _decimal_digit : _ascii_digit ; 85 _decimals : _decimal_digit { _decimal_digit } ; 86 87 // An ID is one of the following: 88 // 89 // 1) Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores 90 // ('_') or digits ([0-9]), not beginning with a digit; 91 // 92 // 2) a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? ); 93 // 94 // 3) any double-quoted string ("...") possibly containing escaped quotes 95 // (\"); 96 // 97 // 4) an HTML string (<...>). 98 99 id 100 : _letter { _letter | _decimal_digit } 101 | _int_lit 102 | _string_lit 103 | _html_lit 104 ; 105 106 _int_lit 107 : [ '-' ] '.' _decimals 108 | [ '-' ] _decimals [ '.' { _decimal_digit } ] 109 ; 110 111 // In quoted strings in DOT, the only escaped character is double-quote ("). 112 // That is, in quoted strings, the dyad \" is converted to "; all other 113 // characters are left unchanged. In particular, \\ remains \\. 114 115 // As another aid for readability, dot allows double-quoted strings to span 116 // multiple physical lines using the standard C convention of a backslash 117 // immediately preceding a newline character. 118 119 // In addition, double-quoted strings can be concatenated using a '+' operator. 120 121 _escaped_char : '\\' ( _unicode_char | '"' | '\\' ) ; 122 _char : _unicode_char | _escaped_char ; 123 _string_lit : '"' { _char } '"' ; 124 125 // An arbitrary HTML character except null (0x00), left angle bracket (0x3C) and 126 // right angle bracket (0x3E). 127 _html_char 128 // skip null (0x00) 129 : '\x01' - '\x3B' 130 // skip left angle bracket (0x3C) 131 | '\x3D' 132 // skip right angle bracket (0x3E) 133 | '\x3F' - '\xFF' 134 | _unicode_byte 135 ; 136 137 _html_chars : { _html_char } ; 138 _html_tag : '<' _html_chars '>' ; 139 _html_lit : '<' { _html_chars | _html_tag } '>' ; 140 141 // The language supports C++-style comments: /* */ and //. In addition, a line 142 // beginning with a '#' character is considered a line output from a C 143 // preprocessor (e.g., # 34 to indicate line 34 ) and discarded. 144 145 _line_comment 146 : '/' '/' { . } '\n' 147 | '#' { . } '\n' 148 ; 149 150 _block_comment : '/' '*' { . | '*' } '*' '/' ; 151 !comment : _line_comment | _block_comment ; 152 153 !whitespace : ' ' | '\t' | '\r' | '\n' ; 154 155 // ### [ Syntax ] ############################################################## 156 157 << import ( 158 "github.com/jingcheng-WU/gonum/graph/formats/dot/ast" 159 "github.com/jingcheng-WU/gonum/graph/formats/dot/internal/astx" 160 ) >> 161 162 // === [ Files ] =============================================================== 163 164 File 165 : Graph << astx.NewFile($0) >> 166 | File Graph << astx.AppendGraph($0, $1) >> 167 ; 168 169 // === [ Graphs ] ============================================================== 170 171 // Graph : [ "strict" ] ( "graph" | "digraph" ) [ ID ] "{" [ StmtList ] "}" 172 173 Graph 174 : OptStrict DirectedGraph OptID 175 "{" OptStmtList "}" << astx.NewGraph($0, $1, $2, $4) >> 176 ; 177 178 OptStrict 179 : empty << false, nil >> 180 | strict << true, nil >> 181 ; 182 183 DirectedGraph 184 : graphx << false, nil >> 185 | digraph << true, nil >> 186 ; 187 188 // === [ Statements ] ========================================================== 189 190 // StmtList 191 // : Stmt [ ";" ] 192 // | StmtList Stmt [ ";" ] 193 194 StmtList 195 : Stmt OptSemi << astx.NewStmtList($0) >> 196 | StmtList Stmt OptSemi << astx.AppendStmt($0, $1) >> 197 ; 198 199 OptStmtList 200 : empty 201 | StmtList 202 ; 203 204 Stmt 205 : NodeStmt 206 | EdgeStmt 207 | AttrStmt 208 | Attr 209 | Subgraph 210 ; 211 212 OptSemi 213 : empty 214 | ";" 215 ; 216 217 // --- [ Node statement ] ------------------------------------------------------ 218 219 // NodeStmt : Node [ AttrList ] 220 221 NodeStmt 222 : Node OptAttrList << astx.NewNodeStmt($0, $1) >> 223 ; 224 225 // --- [ Edge statement ] ------------------------------------------------------ 226 227 // EdgeStmt : ( Node | Subgraph ) Edge [ AttrList ] 228 229 EdgeStmt 230 : Vertex Edge OptAttrList << astx.NewEdgeStmt($0, $1, $2) >> 231 ; 232 233 // Edge : ( "--" | "-->" ) ( Node | Subgraph ) [ Edge ] 234 235 Edge 236 : DirectedEdge Vertex OptEdge << astx.NewEdge($0, $1, $2) >> 237 ; 238 239 DirectedEdge 240 : "--" << false, nil >> 241 | "->" << true, nil >> 242 ; 243 244 OptEdge 245 : empty 246 | Edge 247 ; 248 249 // --- [ Attribute statement ] ------------------------------------------------- 250 251 // AttrStmt : ( "graph" | "node" | "edge" ) AttrList 252 253 AttrStmt 254 : Component AttrList << astx.NewAttrStmt($0, $1) >> 255 ; 256 257 Component 258 : graphx << ast.GraphKind, nil >> 259 | node << ast.NodeKind, nil >> 260 | edge << ast.EdgeKind, nil >> 261 ; 262 263 // AttrList : "[" [ AList ] "]" [ AttrList ] 264 265 AttrList 266 : "[" OptAList "]" << $1, nil >> 267 | AttrList "[" OptAList "]" << astx.AppendAttrList($0, $2) >> 268 ; 269 270 OptAttrList 271 : empty 272 | AttrList 273 ; 274 275 // AList 276 // : Attr [ ( ";" | "," ) ] 277 // | AList Attr [ ( ";" | "," ) ] 278 279 AList 280 : Attr OptSep << astx.NewAttrList($0) >> 281 | AList Attr OptSep << astx.AppendAttr($0, $1) >> 282 ; 283 284 OptAList 285 : empty 286 | AList 287 ; 288 289 OptSep 290 : empty 291 | ";" 292 | "," 293 ; 294 295 // --- [ Attribute ] ----------------------------------------------------------- 296 297 Attr 298 : ID "=" ID << astx.NewAttr($0, $2) >> 299 ; 300 301 // --- [ Subgraph ] ------------------------------------------------------------ 302 303 // Subgraph : [ "subgraph" [ ID ] ] "{" [ StmtList ] "}" 304 305 Subgraph 306 : OptSubgraphID "{" OptStmtList "}" << astx.NewSubgraph($0, $2) >> 307 ; 308 309 OptSubgraphID 310 : empty 311 | subgraph OptID << $1, nil >> 312 ; 313 314 // === [ Vertices ] ============================================================ 315 316 Vertex 317 : Node 318 | Subgraph 319 ; 320 321 // --- [ Node identifier ] ----------------------------------------------------- 322 323 // Node : ID [ Port ] 324 325 Node 326 : ID OptPort << astx.NewNode($0, $1) >> 327 ; 328 329 // Port 330 // : ":" ID [ ":" CompassPoint ] 331 // | ":" CompassPoint 332 // 333 // CompassPoint 334 // : "n" | "ne" | "e" | "se" | "s" | "sw" | "w" | "nw" | "c" | "_" 335 336 // Note also that the allowed compass point values are not keywords, so these 337 // strings can be used elsewhere as ordinary identifiers and, conversely, the 338 // parser will actually accept any identifier. 339 340 Port 341 : ":" ID << astx.NewPort($1, nil) >> 342 | ":" ID ":" ID << astx.NewPort($1, $3) >> 343 ; 344 345 OptPort 346 : empty 347 | Port 348 ; 349 350 // === [ Identifiers ] ========================================================= 351 352 ID 353 : id << astx.NewID($0) >> 354 ; 355 356 OptID 357 : empty << "", nil >> 358 | ID 359 ;