Esempio n. 1
0
def compile(graph, target):
    '''
    Compilation is a two-step process that supports (1) pre-computation of
    values and (2) rapid access to other nodes.

    A compiled node is a function that takes no arguments and returns the
    next compiled node for evaluation (the end of the process is signalled
    to the engine via the `.match()` and `.no_match()` callbacks above).

    It's non-trivial (I think?) to make an efficient closure that includes
    loops, so the compilation avoids this.  Instead, indices into an array
    of nodes are used.  So the compilation process works as follows:
      1. - The `.compile()` method is passed the engine (`BaseMatchTarget` above)
           and numbered.  It returns a "compiler" function.
      2. - The compiler function is called with the map from nodes to indices
           and the (future) table of compiled nodes by index.  This converts
           any node references to indices and returns the "compiled" node,
           which is stored in the table.
    At run-time, when the compiled node is called it must:
      3. - Call the target interface as necessary.
      4. - Return the next node.  To obtain the next node it will use the
           indices generated above to lookup the node from the table.
    Note that the state (position in the input text, matched groups, etc) is
    managed by the engine itself.  The nodes simply trigger the correct
    processing.
    '''
    compilers = [(node, node.compile(target)) for node in node_iterator(graph)]
    node_index = dict(
        (node, index) for (index, (node, _compiler)) in enumerate(compilers))
    table = []
    for (node, compiler) in compilers:
        table.append(compiler(node_index, table))
    return table
Esempio n. 2
0
def compile(graph, target):
    '''
    Compilation is a two-step process that supports (1) pre-computation of
    values and (2) rapid access to other nodes.

    A compiled node is a function that takes no arguments and returns the
    next compiled node for evaluation (the end of the process is signalled
    to the engine via the `.match()` and `.no_match()` callbacks above).

    It's non-trivial (I think?) to make an efficient closure that includes
    loops, so the compilation avoids this.  Instead, indices into an array
    of nodes are used.  So the compilation process works as follows:
      1. - The `.compile()` method is passed the engine (`BaseMatchTarget` above)
           and numbered.  It returns a "compiler" function.
      2. - The compiler function is called with the map from nodes to indices
           and the (future) table of compiled nodes by index.  This converts
           any node references to indices and returns the "compiled" node,
           which is stored in the table.
    At run-time, when the compiled node is called it must:
      3. - Call the target interface as necessary.
      4. - Return the next node.  To obtain the next node it will use the
           indices generated above to lookup the node from the table.
    Note that the state (position in the input text, matched groups, etc) is
    managed by the engine itself.  The nodes simply trigger the correct
    processing.
    '''
    compilers = [(node, node.compile(target)) for node in node_iterator(graph)]
    node_index = dict((node, index)
                      for (index, (node, _compiler)) in enumerate(compilers))
    table = []
    for (node, compiler) in compilers:
        table.append(compiler(node_index, table))
    return table
Esempio n. 3
0
def post_process(graph, actions):
    map = {}
    for (type_, function) in actions:
        if type_ not in map:
            map[type_] = function
        else:
            raise RxpyError('Conflicting actions for ' + str(type_))
    for node in node_iterator(graph):
        map.get(type(node), lambda x: None)(node)
    return graph
Esempio n. 4
0
def post_process(graph, actions):
    map = {}
    for (type_, function) in actions:
        if type_ not in map:
            map[type_] = function
        else:
            raise RxpyError('Conflicting actions for ' + str(type_))
    for node in node_iterator(graph):
        map.get(type(node), lambda x: None)(node)
    return graph