<s> """<STR_LIT>""" <EOL> __author__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> __license__ = '<STR_LIT>' <EOL> import sys <EOL> import glob <EOL> import pydot <EOL> import re <EOL> import codecs <EOL> from pyparsing import __version__ as pyparsing_version <EOL> from pyparsing import ( nestedExpr , Literal , CaselessLiteral , Word , Upcase , OneOrMore , ZeroOrMore , <EOL> Forward , NotAny , delimitedList , oneOf , Group , Optional , Combine , alphas , nums , <EOL> restOfLine , cStyleComment , nums , alphanums , printables , empty , quotedString , <EOL> ParseException , ParseResults , CharsNotIn , _noncomma , dblQuotedString , QuotedString , ParserElement ) <EOL> class P_AttrList : <EOL> def __init__ ( self , toks ) : <EOL> self . attrs = { } <EOL> i = <NUM_LIT:0> <EOL> while i < len ( toks ) : <EOL> attrname = toks [ i ] <EOL> if i + <NUM_LIT:2> < len ( toks ) and toks [ i + <NUM_LIT:1> ] == '<STR_LIT:=>' : <EOL> attrvalue = toks [ i + <NUM_LIT:2> ] <EOL> i += <NUM_LIT:3> <EOL> else : <EOL> attrvalue = None <EOL> i += <NUM_LIT:1> <EOL> self . attrs [ attrname ] = attrvalue <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , self . attrs ) <EOL> class DefaultStatement ( P_AttrList ) : <EOL> def __init__ ( self , default_type , attrs ) : <EOL> self . default_type = default_type <EOL> self . attrs = attrs <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % ( self . __class__ . __name__ , <EOL> self . default_type , self . attrs ) <EOL> top_graphs = list ( ) <EOL> def push_top_graph_stmt ( str , loc , toks ) : <EOL> attrs = { } <EOL> g = None <EOL> for element in toks : <EOL> if ( isinstance ( element , ( ParseResults , tuple , list ) ) and <EOL> len ( element ) == <NUM_LIT:1> and isinstance ( element [ <NUM_LIT:0> ] , basestring ) ) : <EOL> element = element [ <NUM_LIT:0> ] <EOL> if element == '<STR_LIT:strict>' : <EOL> attrs [ '<STR_LIT:strict>' ] = True <EOL> elif element in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> attrs = { } <EOL> g = pydot . Dot ( graph_type = element , ** attrs ) <EOL> attrs [ '<STR_LIT:type>' ] = element <EOL> top_graphs . append ( g ) <EOL> elif isinstance ( element , basestring ) : <EOL> g . set_name ( element ) <EOL> elif isinstance ( element , pydot . Subgraph ) : <EOL> g . obj_dict [ '<STR_LIT>' ] . update ( element . obj_dict [ '<STR_LIT>' ] ) <EOL> g . obj_dict [ '<STR_LIT>' ] . update ( element . obj_dict [ '<STR_LIT>' ] ) <EOL> g . obj_dict [ '<STR_LIT>' ] . update ( element . obj_dict [ '<STR_LIT>' ] ) <EOL> g . obj_dict [ '<STR_LIT>' ] . update ( element . obj_dict [ '<STR_LIT>' ] ) <EOL> g . set_parent_graph ( g ) <EOL> elif isinstance ( element , P_AttrList ) : <EOL> attrs . update ( element . attrs ) <EOL> elif isinstance ( element , ( ParseResults , list ) ) : <EOL> add_elements ( g , element ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" % element <EOL> for g in top_graphs : <EOL> update_parent_graph_hierarchy ( g ) <EOL> if len ( top_graphs ) == <NUM_LIT:1> : <EOL> return top_graphs [ <NUM_LIT:0> ] <EOL> return top_graphs <EOL> def update_parent_graph_hierarchy ( g , parent_graph = None , level = <NUM_LIT:0> ) : <EOL> if parent_graph is None : <EOL> parent_graph = g <EOL> for key_name in ( '<STR_LIT>' , ) : <EOL> if isinstance ( g , pydot . frozendict ) : <EOL> item_dict = g <EOL> else : <EOL> item_dict = g . obj_dict <EOL> if not item_dict . has_key ( key_name ) : <EOL> continue <EOL> for key , objs in item_dict [ key_name ] . items ( ) : <EOL> for obj in objs : <EOL> if '<STR_LIT>' in obj and obj [ '<STR_LIT>' ] . get_parent_graph ( ) == g : <EOL> if obj [ '<STR_LIT>' ] is g : <EOL> pass <EOL> else : <EOL> obj [ '<STR_LIT>' ] . set_parent_graph ( parent_graph ) <EOL> if key_name == '<STR_LIT>' and len ( key ) == <NUM_LIT:2> : <EOL> for idx , vertex in enumerate ( obj [ '<STR_LIT>' ] ) : <EOL> if isinstance ( vertex , ( pydot . Graph , pydot . Subgraph , pydot . Cluster ) ) : <EOL> vertex . set_parent_graph ( parent_graph ) <EOL> if isinstance ( vertex , pydot . frozendict ) : <EOL> if vertex [ '<STR_LIT>' ] is g : <EOL> pass <EOL> else : <EOL> vertex [ '<STR_LIT>' ] . set_parent_graph ( parent_graph ) <EOL> def add_defaults ( element , defaults ) : <EOL> d = element . __dict__ <EOL> for key , value in defaults . items ( ) : <EOL> if not d . get ( key ) : <EOL> d [ key ] = value <EOL> def add_elements ( g , toks , defaults_graph = None , defaults_node = None , defaults_edge = None ) : <EOL> if defaults_graph is None : <EOL> defaults_graph = { } <EOL> if defaults_node is None : <EOL> defaults_node = { } <EOL> if defaults_edge is None : <EOL> defaults_edge = { } <EOL> for elm_idx , element in enumerate ( toks ) : <EOL> if isinstance ( element , ( pydot . Subgraph , pydot . Cluster ) ) : <EOL> add_defaults ( element , defaults_graph ) <EOL> g . add_subgraph ( element ) <EOL> elif isinstance ( element , pydot . Node ) : <EOL> add_defaults ( element , defaults_node ) <EOL> g . add_node ( element ) <EOL> elif isinstance ( element , pydot . Edge ) : <EOL> add_defaults ( element , defaults_edge ) <EOL> g . add_edge ( element ) <EOL> elif isinstance ( element , ParseResults ) : <EOL> for e in element : <EOL> add_elements ( g , [ e ] , defaults_graph , defaults_node , defaults_edge ) <EOL> elif isinstance ( element , DefaultStatement ) : <EOL> if element . default_type == '<STR_LIT>' : <EOL> default_graph_attrs = pydot . Node ( '<STR_LIT>' , ** element . attrs ) <EOL> g . add_node ( default_graph_attrs ) <EOL> elif element . default_type == '<STR_LIT>' : <EOL> default_node_attrs = pydot . Node ( '<STR_LIT>' , ** element . attrs ) <EOL> g . add_node ( default_node_attrs ) <EOL> elif element . default_type == '<STR_LIT>' : <EOL> default_edge_attrs = pydot . Node ( '<STR_LIT>' , ** element . attrs ) <EOL> g . add_node ( default_edge_attrs ) <EOL> defaults_edge . update ( element . attrs ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" % element . default_type <EOL> elif isinstance ( element , P_AttrList ) : <EOL> g . obj_dict [ '<STR_LIT>' ] . update ( element . attrs ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" % element <EOL> def push_graph_stmt ( str , loc , toks ) : <EOL> g = pydot . Subgraph ( '<STR_LIT>' ) <EOL> add_elements ( g , toks ) <EOL> return g <EOL> def push_subgraph_stmt ( str , loc , toks ) : <EOL> g = pydot . Subgraph ( '<STR_LIT>' ) <EOL> for e in toks : <EOL> if len ( e ) == <NUM_LIT:3> : <EOL> e [ <NUM_LIT:2> ] . set_name ( e [ <NUM_LIT:1> ] ) <EOL> if e [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> e [ <NUM_LIT:2> ] . obj_dict [ '<STR_LIT>' ] = True <EOL> return e [ <NUM_LIT:2> ] <EOL> else : <EOL> if e [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> e [ <NUM_LIT:1> ] . obj_dict [ '<STR_LIT>' ] = True <EOL> return e [ <NUM_LIT:1> ] <EOL> return g <EOL> def push_default_stmt ( str , loc , toks ) : <EOL> default_type = toks [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> if len ( toks ) > <NUM_LIT:1> : <EOL> attrs = toks [ <NUM_LIT:1> ] . attrs <EOL> else : <EOL> attrs = { } <EOL> if default_type in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> return DefaultStatement ( default_type , attrs ) <EOL> else : <EOL> raise ValueError , "<STR_LIT>" % toks <EOL> def push_attr_list ( str , loc , toks ) : <EOL> p = P_AttrList ( toks ) <EOL> return p <EOL> def get_port ( node ) : <EOL> if len ( node ) > <NUM_LIT:1> : <EOL> if isinstance ( node [ <NUM_LIT:1> ] , ParseResults ) : <EOL> if len ( node [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] ) == <NUM_LIT:2> : <EOL> if node [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] == '<STR_LIT::>' : <EOL> return node [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> return None <EOL> def do_node_ports ( node ) : <EOL> node_port = '<STR_LIT>' <EOL> if len ( node ) > <NUM_LIT:1> : <EOL> node_port = '<STR_LIT>' . join ( [ str ( a ) + str ( b ) for a , b in node [ <NUM_LIT:1> ] ] ) <EOL> return node_port <EOL> def push_edge_stmt ( str , loc , toks ) : <EOL> tok_attrs = [ a for a in toks if isinstance ( a , P_AttrList ) ] <EOL> attrs = { } <EOL> for a in tok_attrs : <EOL> attrs . update ( a . attrs ) <EOL> e = [ ] <EOL> if isinstance ( toks [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] , pydot . Graph ) : <EOL> n_prev = pydot . frozendict ( toks [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] . obj_dict ) <EOL> else : <EOL> n_prev = toks [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] + do_node_ports ( toks [ <NUM_LIT:0> ] ) <EOL> if isinstance ( toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , ParseResults ) : <EOL> n_next_list = [ [ n . get_name ( ) , ] for n in toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] ] <EOL> for n_next in [ n for n in n_next_list ] : <EOL> n_next_port = do_node_ports ( n_next ) <EOL> e . append ( pydot . Edge ( n_prev , n_next [ <NUM_LIT:0> ] + n_next_port , ** attrs ) ) <EOL> elif isinstance ( toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , pydot . Graph ) : <EOL> e . append ( pydot . Edge ( n_prev , pydot . frozendict ( toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] . obj_dict ) , ** attrs ) ) <EOL> elif isinstance ( toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , pydot . Node ) : <EOL> node = toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] <EOL> if node . get_port ( ) is not None : <EOL> name_port = node . get_name ( ) + "<STR_LIT::>" + node . get_port ( ) <EOL> else : <EOL> name_port = node . get_name ( ) <EOL> e . append ( pydot . Edge ( n_prev , name_port , ** attrs ) ) <EOL> elif isinstance ( toks [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , type ( '<STR_LIT>' ) ) : <EOL> for n_next in [ n for n in tuple ( toks ) [ <NUM_LIT:2> : : <NUM_LIT:2> ] ] : <EOL> if isinstance ( n_next , P_AttrList ) or not isinstance ( n_next [ <NUM_LIT:0> ] , type ( '<STR_LIT>' ) ) : <EOL> continue <EOL> n_next_port = do_node_ports ( n_next ) <EOL> e . append ( pydot . Edge ( n_prev , n_next [ <NUM_LIT:0> ] + n_next_port , ** attrs ) ) <EOL> n_prev = n_next [ <NUM_LIT:0> ] + n_next_port <EOL> else : <EOL> pass <EOL> return e <EOL> def push_node_stmt ( s , loc , toks ) : <EOL> if len ( toks ) == <NUM_LIT:2> : <EOL> attrs = toks [ <NUM_LIT:1> ] . attrs <EOL> else : <EOL> attrs = { } <EOL> node_name = toks [ <NUM_LIT:0> ] <EOL> if isinstance ( node_name , list ) or isinstance ( node_name , tuple ) : <EOL> if len ( node_name ) > <NUM_LIT:0> : <EOL> node_name = node_name [ <NUM_LIT:0> ] <EOL> n = pydot . Node ( str ( node_name ) , ** attrs ) <EOL> return n <EOL> graphparser = None <EOL> def graph_definition ( ) : <EOL> global graphparser <EOL> if not graphparser : <EOL> colon = Literal ( "<STR_LIT::>" ) <EOL> lbrace = Literal ( "<STR_LIT:{>" ) <EOL> rbrace = Literal ( "<STR_LIT:}>" ) <EOL> lbrack = Literal ( "<STR_LIT:[>" ) <EOL> rbrack = Literal ( "<STR_LIT:]>" ) <EOL> lparen = Literal ( "<STR_LIT:(>" ) <EOL> rparen = Literal ( "<STR_LIT:)>" ) <EOL> equals = Literal ( "<STR_LIT:=>" ) <EOL> comma = Literal ( "<STR_LIT:U+002C>" ) <EOL> dot = Literal ( "<STR_LIT:.>" ) <EOL> slash = Literal ( "<STR_LIT:/>" ) <EOL> bslash = Literal ( "<STR_LIT:\\>" ) <EOL> star = Literal ( "<STR_LIT:*>" ) <EOL> semi = Literal ( "<STR_LIT:;>" ) <EOL> at = Literal ( "<STR_LIT:@>" ) <EOL> minus = Literal ( "<STR_LIT:->" ) <EOL> strict_ = CaselessLiteral ( "<STR_LIT:strict>" ) <EOL> graph_ = CaselessLiteral ( "<STR_LIT>" ) <EOL> digraph_ = CaselessLiteral ( "<STR_LIT>" ) <EOL> subgraph_ = CaselessLiteral ( "<STR_LIT>" ) <EOL> node_ = CaselessLiteral ( "<STR_LIT>" ) <EOL> edge_ = CaselessLiteral ( "<STR_LIT>" ) <EOL> identifier = Word ( alphanums + "<STR_LIT>" ) . setName ( "<STR_LIT>" ) <EOL> double_quoted_string = QuotedString ( '<STR_LIT:">' , multiline = True , unquoteResults = False ) <EOL> alphastring_ = OneOrMore ( CharsNotIn ( _noncomma + '<STR_LIT:U+0020>' ) ) <EOL> def parse_html ( s , loc , toks ) : <EOL> return '<STR_LIT>' % '<STR_LIT>' . join ( toks [ <NUM_LIT:0> ] ) <EOL> opener = '<STR_LIT:<>' <EOL> closer = '<STR_LIT:>>' <EOL> html_text = nestedExpr ( opener , closer , <EOL> ( CharsNotIn ( opener + closer ) ) <EOL> ) . setParseAction ( parse_html ) . leaveWhitespace ( ) <EOL> ID = ( identifier | html_text | <EOL> double_quoted_string | <EOL> alphastring_ ) . setName ( "<STR_LIT>" ) <EOL> float_number = Combine ( Optional ( minus ) + <EOL> OneOrMore ( Word ( nums + "<STR_LIT:.>" ) ) ) . setName ( "<STR_LIT>" ) <EOL> righthand_id = ( float_number | ID ) . setName ( "<STR_LIT>" ) <EOL> port_angle = ( at + ID ) . setName ( "<STR_LIT>" ) <EOL> port_location = ( OneOrMore ( Group ( colon + ID ) ) | <EOL> Group ( colon + lparen + ID + comma + ID + rparen ) ) . setName ( "<STR_LIT>" ) <EOL> port = ( Group ( port_location + Optional ( port_angle ) ) | <EOL> Group ( port_angle + Optional ( port_location ) ) ) . setName ( "<STR_LIT:port>" ) <EOL> node_id = ( ID + Optional ( port ) ) <EOL> a_list = OneOrMore ( ID + Optional ( equals + righthand_id ) + <EOL> Optional ( comma . suppress ( ) ) ) . setName ( "<STR_LIT>" ) <EOL> attr_list = OneOrMore ( lbrack . suppress ( ) + Optional ( a_list ) + <EOL> rbrack . suppress ( ) ) . setName ( "<STR_LIT>" ) <EOL> attr_stmt = ( Group ( graph_ | node_ | edge_ ) + attr_list ) . setName ( "<STR_LIT>" ) <EOL> edgeop = ( Literal ( "<STR_LIT>" ) | Literal ( "<STR_LIT>" ) ) . setName ( "<STR_LIT>" ) <EOL> stmt_list = Forward ( ) <EOL> graph_stmt = Group ( lbrace . suppress ( ) + Optional ( stmt_list ) + <EOL> rbrace . suppress ( ) + Optional ( semi . suppress ( ) ) ) . setName ( "<STR_LIT>" ) <EOL> edge_point = Forward ( ) <EOL> edgeRHS = OneOrMore ( edgeop + edge_point ) <EOL> edge_stmt = edge_point + edgeRHS + Optional ( attr_list ) <EOL> subgraph = Group ( subgraph_ + Optional ( ID ) + graph_stmt ) . setName ( "<STR_LIT>" ) <EOL> edge_point << Group ( subgraph | graph_stmt | node_id ) . setName ( '<STR_LIT>' ) <EOL> node_stmt = ( node_id + Optional ( attr_list ) + Optional ( semi . suppress ( ) ) ) . setName ( "<STR_LIT>" ) <EOL> assignment = ( ID + equals + righthand_id ) . setName ( "<STR_LIT>" ) <EOL> stmt = ( assignment | edge_stmt | attr_stmt | subgraph | graph_stmt | node_stmt ) . setName ( "<STR_LIT>" ) <EOL> stmt_list << OneOrMore ( stmt + Optional ( semi . suppress ( ) ) ) <EOL> graphparser = OneOrMore ( ( Optional ( strict_ ) + Group ( ( graph_ | digraph_ ) ) + <EOL> Optional ( ID ) + graph_stmt ) . setResultsName ( "<STR_LIT>" ) ) <EOL> singleLineComment = Group ( "<STR_LIT>" + restOfLine ) | Group ( "<STR_LIT:#>" + restOfLine ) <EOL> graphparser . ignore ( singleLineComment ) <EOL> graphparser . ignore ( cStyleComment ) <EOL> assignment . setParseAction ( push_attr_list ) <EOL> a_list . setParseAction ( push_attr_list ) <EOL> edge_stmt . setParseAction ( push_edge_stmt ) <EOL> node_stmt . setParseAction ( push_node_stmt ) <EOL> attr_stmt . setParseAction ( push_default_stmt ) <EOL> subgraph . setParseAction ( push_subgraph_stmt ) <EOL> graph_stmt . setParseAction ( push_graph_stmt ) <EOL> graphparser . setParseAction ( push_top_graph_stmt ) <EOL> return graphparser <EOL> def parse_dot_data ( data ) : <EOL> global top_graphs <EOL> top_graphs = list ( ) <EOL> if data . startswith ( codecs . BOM_UTF8 ) : <EOL> data = data . decode ( '<STR_LIT:utf-8>' ) <EOL> try : <EOL> graphparser = graph_definition ( ) <EOL> if pyparsing_version >= '<STR_LIT>' : <EOL> graphparser . parseWithTabs ( ) <EOL> tokens = graphparser . parseString ( data ) <EOL> if len ( tokens ) == <NUM_LIT:1> : <EOL> return tokens [ <NUM_LIT:0> ] <EOL> else : <EOL> return [ g for g in tokens ] <EOL> except ParseException , err : <EOL> print err . line <EOL> print "<STR_LIT:U+0020>" * ( err . column - <NUM_LIT:1> ) + "<STR_LIT>" <EOL> print err <EOL> return None </s>
