예제 #1
0
def parsesingle(s, strictmode=True, expansionlimit=None, convertpos=False):
    '''like parse, but only consumes a single top level node, e.g. parsing
    'a\nb' will only return a node for 'a', leaving b unparsed'''
    p = _parser(s, strictmode=strictmode, expansionlimit=expansionlimit)
    tree = p.parse()
    if convertpos:
        bast.posconverter(s).visit(tree)
    return tree
예제 #2
0
def parse(s, strictmode=True, expansionlimit=None, convertpos=False):
    '''parse the input string, returning a list of nodes

    top level node kinds are:

    - command - a simple command
    - pipeline - a series of simple commands
    - list - a series of one or more pipelines
    - compound - contains constructs for { list; }, (list), if, for..

    leafs are word nodes (which in turn can also contain any of the
    aforementioned nodes due to command substitutions).

    when strictmode is set to False, we will:
    - skip reading a heredoc if we're at the end of the input

    expansionlimit is used to limit the amount of recursive parsing done due to
    command substitutions found during word expansion.
    '''
    p = _parser(s, strictmode=strictmode, expansionlimit=expansionlimit)
    parts = [p.parse()]

    class endfinder(bast.nodevisitor):
        def __init__(self):
            self.end = -1
        def visitheredoc(self, node, value):
            self.end = node.pos[1]

    # find the 'real' end incase we have a heredoc in there
    ef = _endfinder()
    ef.visit(parts[-1])
    index = max(parts[-1].pos[1], ef.end) + 1
    while index < len(s):
        part = _parser(s[index:], strictmode=strictmode).parse()

        if not isinstance(part, bast.node):
            break

        bast.posshifter(index).visit(part)
        parts.append(part)
        ef = _endfinder()
        ef.visit(parts[-1])
        index = max(parts[-1].pos[1], ef.end) + 1

    if convertpos:
        for tree in parts:
            bast.posconverter(s).visit(tree)

    return parts