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  ;