Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)