def parse(seq): """Sequence(Token) -> object""" tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in ['Name', 'Number', 'String']) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval separator = some(lambda t: t.type == 'Separator') >> tokval def make_separator(sep): return Separator(sep[0:3], sep[3:-3].strip()) # # parts of syntax # option_stmt = (_id + maybe(op_('=') + _id) >> create_mapper(Attr)) option_list = (maybe( op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[])) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = (_id + op_('=') + _id >> create_mapper(Attr)) # node statement:: # A; # B [attr = value, attr = value]; # node_stmt = (_id + option_list >> create_mapper(Node)) # separator statement:: # === message === # ... message ... # separator_stmt = (separator >> make_separator) # edge statement:: # A -> B; # C -> D { # D -> E; # } # edge_block = forward_decl() edge_relation = (op('<<--') | op('<--') | op('<<-') | op('<-') | op('->') | op('->>') | op('-->') | op('-->>') | op('=>')) edge_stmt = (_id + edge_relation + _id + many(edge_relation + _id) + option_list + maybe(edge_block) >> create_mapper(Edge)) edge_block_inline_stmt_list = (many(edge_stmt + skip(maybe(op(';'))) | separator_stmt)) edge_block.define( op_('{') + edge_block_inline_stmt_list + op_('}') >> Statements) # group statement:: # group { # A; # } # group_inline_stmt_list = (many((attribute_stmt | node_stmt) + skip(maybe(op(';'))))) group_stmt = (skip(keyword('group')) + skip(maybe(_id)) + op_('{') + group_inline_stmt_list + op_('}') >> Group) # combined fragment (alt, loop) statement:: # loop { # A -> B; # } # alt { # D -> E; # } # fragment_stmt = forward_decl() fragment_inline_stmt = (attribute_stmt | fragment_stmt | edge_stmt | node_stmt) fragment_inline_stmt_list = (many(fragment_inline_stmt + skip(maybe(op(';'))))) fragment_types = (keyword('alt') | keyword('loop')) fragment_stmt.define(fragment_types + maybe(_id) + op_('{') + fragment_inline_stmt_list + op_('}') >> create_mapper(Fragment)) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ((keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension)) # diagram statement:: # seqdiag { # A -> B; # } # diagram_id = ( (keyword('diagram') | keyword('seqdiag')) + maybe(_id) >> list) diagram_inline_stmt = (extension_stmt | attribute_stmt | fragment_stmt | group_stmt | edge_stmt | separator_stmt | node_stmt) diagram_inline_stmt_list = (many(diagram_inline_stmt + skip(maybe(op(';'))))) diagram = (maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram)) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" id_tokens = ['Name', 'IPAddr', 'Number', 'String'] tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in id_tokens) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval def make_peer(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Peer(edges) def make_route(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Route(edges) # # parts of syntax # node_list = ( _id + many(op_(',') + _id) >> create_mapper(oneplus_to_list) ) option_stmt = ( _id + maybe(op_('=') + _id) >> create_mapper(Attr) ) option_list = ( maybe(op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[]) ) # node statement:: # A; # B [attr = value, attr = value]; # node_stmt = ( _id + option_list >> create_mapper(Node) ) # peer network statement:: # A -- B; # edge_stmt = ( _id + op('--') + _id + many(op('--') + _id) + option_list >> create_mapper(make_peer) ) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = ( _id + op_('=') + _id >> create_mapper(Attr) ) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ( (keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension) ) # group statement:: # group { # A; # } # group_inline_stmt = ( attribute_stmt | node_stmt ) group_inline_stmt_list = ( many(group_inline_stmt + skip(maybe(op(';')))) ) group_stmt = ( skip(keyword('group')) + maybe(_id) + op_('{') + group_inline_stmt_list + op_('}') >> create_mapper(Group) ) # network statement:: # network { # A; # } # network_inline_stmt = ( attribute_stmt | group_stmt | node_stmt ) network_inline_stmt_list = ( many(network_inline_stmt + skip(maybe(op(';')))) ) network_stmt = ( skip(keyword('network')) + maybe(_id) + op_('{') + network_inline_stmt_list + op_('}') >> create_mapper(Network) ) # route statement:: # route { # A -> B -> C; # } # route_inline_stmt = ( _id + op_('->') + _id + many(op_('->') + _id) + option_list >> create_mapper(make_route) ) route_stmt = ( skip(keyword('route')) + maybe(_id) + op_('{') + network_inline_stmt_list + op_('}') >> create_mapper(Network) ) # # diagram statement:: # nwdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('nwdiag')) + maybe(_id) >> list ) diagram_inline_stmt = ( extension_stmt | network_stmt | group_stmt | attribute_stmt | route_stmt | edge_stmt | node_stmt ) diagram_inline_stmt_list = ( many(diagram_inline_stmt + skip(maybe(op(';')))) ) diagram = ( maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram) ) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" id_tokens = ['Name', 'Number', 'String', 'RackHeight', 'Units'] rackitem_tokens = ['QuotedRackItem', 'RackItem'] tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in id_tokens) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval rackheight = some(lambda t: t.type == 'RackHeight') >> tokval number = some(lambda t: t.type == 'Number').named('number') >> tokval rackitem = some(lambda t: t.type in rackitem_tokens) >> tokval def make_num_rackitem(num, text, attr): return RackItem(num, text.strip(), attr) def make_nonnum_rackitem(text, attr): return RackItem(None, text.strip(), attr) def make_nonvalued_attr(rackheight): return Attr(rackheight, None) # # parts of syntax # option_stmt = ( _id + maybe(op_('=') + _id) >> create_mapper(Attr) ) option_list = ( maybe(op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[]) ) # attributes statement:: # default_shape = box; # default_fontsize = 16; # 12U; # ascending; # attribute_stmt = ( _id + op_('=') + _id >> create_mapper(Attr) ) rackheight_stmt = ( rackheight >> make_nonvalued_attr ) ascending_stmt = ( keyword('ascending') >> make_nonvalued_attr ) # field statement:: # 1: A # 2: B [attr = value, attr = value]; # * C [attr = value, attr = value]; # * D [attr = value, attr = value]; # numbered_field_item_stmt = ( number + op_(':') + rackitem + option_list >> create_mapper(make_num_rackitem) ) nonnumbered_field_item_stmt = ( (op_('-') | op_('*')) + rackitem + option_list >> create_mapper(make_nonnum_rackitem) ) field_item_stmt = ( numbered_field_item_stmt | nonnumbered_field_item_stmt ) # rack statement:: # rack { # 1: A; # } # # rack definition rack_inline_stmt = ( attribute_stmt | rackheight_stmt | field_item_stmt ) rack_inline_stmt_list = ( many(rack_inline_stmt + skip(maybe(op(';')))) ) rack_stmt = ( skip(keyword('rack')) + maybe(_id) + op_('{') + rack_inline_stmt_list + op_('}') >> create_mapper(Rack) ) # extension statement (plugin):: # plugin attributes [name = Name]; # extension_stmt = ( keyword('plugin') + _id + option_list >> create_mapper(Extension) ) # # diagram statement:: # rackdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('rackdiag')) + maybe(_id) >> list ) diagram_inline_stmt = ( ascending_stmt | extension_stmt | rack_stmt | field_item_stmt | attribute_stmt | rackheight_stmt ) diagram_inline_stmt_list = ( many(diagram_inline_stmt + skip(maybe(op(';')))) ) diagram = ( maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram) ) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" id_tokens = ['Name', 'IPAddr', 'Number', 'String'] tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in id_tokens) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval def make_peer(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Peer(edges) def make_route(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Route(edges) # # parts of syntax # node_list = (_id + many(op_(',') + _id) >> create_mapper(oneplus_to_list)) option_stmt = (_id + maybe(op_('=') + _id) >> create_mapper(Attr)) option_list = (maybe( op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[])) # node statement:: # A; # B [attr = value, attr = value]; # node_stmt = (_id + option_list >> create_mapper(Node)) # peer network statement:: # A -- B; # edge_stmt = (_id + op('--') + _id + many(op('--') + _id) + option_list >> create_mapper(make_peer)) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = (_id + op_('=') + _id >> create_mapper(Attr)) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ((keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension)) # group statement:: # group { # A; # } # group_inline_stmt = (attribute_stmt | node_stmt) group_inline_stmt_list = (many(group_inline_stmt + skip(maybe(op(';'))))) group_stmt = (skip(keyword('group')) + maybe(_id) + op_('{') + group_inline_stmt_list + op_('}') >> create_mapper(Group)) # network statement:: # network { # A; # } # network_inline_stmt = (attribute_stmt | group_stmt | node_stmt) network_inline_stmt_list = (many(network_inline_stmt + skip(maybe(op(';'))))) network_stmt = ( skip(keyword('network')) + maybe(_id) + op_('{') + network_inline_stmt_list + op_('}') >> create_mapper(Network)) # route statement:: # route { # A -> B -> C; # } # route_inline_stmt = (_id + op_('->') + _id + many(op_('->') + _id) + option_list >> create_mapper(make_route)) route_stmt = ( skip(keyword('route')) + maybe(_id) + op_('{') + network_inline_stmt_list + op_('}') >> create_mapper(Network)) # # diagram statement:: # nwdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('nwdiag')) + maybe(_id) >> list) diagram_inline_stmt = (extension_stmt | network_stmt | group_stmt | attribute_stmt | route_stmt | edge_stmt | node_stmt) diagram_inline_stmt_list = (many(diagram_inline_stmt + skip(maybe(op(';'))))) diagram = (maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram)) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in ['Name', 'Number', 'String']) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval def make_node_list(node_list, attrs): return Statements([Node(node, attrs) for node in node_list]) def make_edge(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Statements(edges) # # parts of syntax # node_list = ( _id + many(op_(',') + _id) >> create_mapper(oneplus_to_list) ) option_stmt = ( _id + maybe(op_('=') + _id) >> create_mapper(Attr) ) option_list = ( maybe(op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[]) ) # node (node list) statement:: # A; # B [attr = value, attr = value]; # C, D [attr = value, attr = value]; # node_stmt = ( node_list + option_list >> create_mapper(make_node_list) ) # edge statement:: # A -> B; # A <- B; # edge_relation = ( op('->') | op('--') | op('<-') | op('<->') ) edge_stmt = ( node_list + edge_relation + node_list + many(edge_relation + node_list) + option_list >> create_mapper(make_edge) ) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = ( _id + op_('=') + _id >> create_mapper(Attr) ) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ( (keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension) ) # lane statement:: # lane A [color = red]; # lane { # A; # } # lane_declare_stmt = ( skip(keyword('lane')) + _id + option_list >> create_mapper(Lane) ) lane_inline_stmt = ( edge_stmt | attribute_stmt | node_stmt ) lane_inline_stmt_list = ( many(lane_inline_stmt + skip(maybe(op(';')))) ) lane_stmt = ( skip(keyword('lane')) + maybe(_id) + op_('{') + lane_inline_stmt_list + op_('}') >> create_mapper(Lane) ) # # diagram statement:: # actdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('actdiag')) + maybe(_id) >> list ) diagram_inline_stmt = ( extension_stmt | edge_stmt | lane_stmt | lane_declare_stmt | attribute_stmt | node_stmt ) diagram_inline_stmt_list = ( many(diagram_inline_stmt + skip(maybe(op(';')))) ) diagram = ( maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram) ) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" fielditem_tokens = ['QuotedFieldItem', 'FieldItem'] tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in ['Name', 'Number', 'String']) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval number = some(lambda t: t.type == 'Number').named('number') >> tokval field_item = some(lambda t: t.type in fielditem_tokens) >> tokval def make_num_field_item(_from, to, text, attr): return FieldItem(_from, to, text.strip(), attr) def make_nonnum_field_item(text, attr): return FieldItem(None, None, text.strip(), attr) # # parts of syntax # option_stmt = ( _id + maybe(op_('=') + _id) >> create_mapper(Attr) ) option_list = ( maybe(op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[]) ) # field statement:: # 1: A # 2-3: B [attr = value, attr = value]; # * C [attr = value, attr = value]; # * D [attr = value, attr = value]; # numbered_field_item_stmt = ( number + maybe(op_('-') + number) + op_(':') + field_item + option_list >> create_mapper(make_num_field_item) ) nonnumbered_field_item_stmt = ( (op_('-') | op_('*')) + field_item + option_list >> create_mapper(make_nonnum_field_item) ) field_item_stmt = ( numbered_field_item_stmt | nonnumbered_field_item_stmt ) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = ( _id + op_('=') + _id >> create_mapper(Attr) ) # extension statement (plugin):: # plugin attributes [name = Name]; # extension_stmt = ( keyword('plugin') + _id + option_list >> create_mapper(Extension) ) # # diagram statement:: # packetdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('packetdiag')) + maybe(_id) >> list ) diagram_inline_stmt = ( extension_stmt | field_item_stmt | attribute_stmt ) diagram_inline_stmt_list = ( many(diagram_inline_stmt + skip(maybe(op(';')))) ) diagram = ( maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram) ) dotfile = diagram + skip(finished) return dotfile.parse(seq)
def parse(seq): """Sequence(Token) -> object""" tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in ['Name', 'Number', 'String']) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval def make_node_list(node_list, attrs): return Statements([Node(node, attrs) for node in node_list]) def make_edge(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Statements(edges) # # parts of syntax # node_list = (_id + many(op_(',') + _id) >> create_mapper(oneplus_to_list)) option_stmt = (_id + maybe(op_('=') + _id) >> create_mapper(Attr)) option_list = (maybe( op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[])) # node (node list) statement:: # A; # B [attr = value, attr = value]; # C, D [attr = value, attr = value]; # node_stmt = (node_list + option_list >> create_mapper(make_node_list)) # edge statement:: # A -> B; # A <- B; # edge_relation = (op('->') | op('--') | op('<-') | op('<->')) edge_stmt = (node_list + edge_relation + node_list + many(edge_relation + node_list) + option_list >> create_mapper(make_edge)) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = (_id + op_('=') + _id >> create_mapper(Attr)) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ((keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension)) # lane statement:: # lane A [color = red]; # lane { # A; # } # lane_declare_stmt = ( skip(keyword('lane')) + _id + option_list >> create_mapper(Lane)) lane_inline_stmt = (edge_stmt | attribute_stmt | node_stmt) lane_inline_stmt_list = (many(lane_inline_stmt + skip(maybe(op(';'))))) lane_stmt = (skip(keyword('lane')) + maybe(_id) + op_('{') + lane_inline_stmt_list + op_('}') >> create_mapper(Lane)) # # diagram statement:: # actdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('actdiag')) + maybe(_id) >> list) diagram_inline_stmt = (extension_stmt | edge_stmt | lane_stmt | lane_declare_stmt | attribute_stmt | node_stmt) diagram_inline_stmt_list = (many(diagram_inline_stmt + skip(maybe(op(';'))))) diagram = (maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram)) dotfile = diagram + skip(finished) return dotfile.parse(seq)