Ejemplo n.º 1
0
def matrix(self, node, cur):
    """
Verbatim matrices

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of matrix

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[[1 2] [3 4]]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[[1 2] [3 4]]'
       0     Expression  expression.create    '[[1 2] [3 4]]'
       0     Matrix      misc.matrix          '[[1 2] [3 4]]'
       1     Vector      misc.matrix          '[1 2] [3 4]'
       1     Expression  expression.create    '[1 2]'
       1     Matrix      misc.matrix          '[1 2]'
       2     Vector      misc.matrix          '1 2'
       2     Expression  expression.create    '1'
       2     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
       7     Expression  expression.create    '[3 4]'
       7     Matrix      misc.matrix          '[3 4]'
       8     Vector      misc.matrix          '3 4'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
      10     Expression  expression.create    '4'
      10     Int         misc.number          '4'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1   1Block      code_block   TYPE
     1   1| Statement  code_block   TYPE
     1   1| | Matrix     matrix       irowvec
     1   2| | | Vector     matrix       irowvec
     1   2| | | | Matrix     matrix       irowvec
     1   3| | | | | Vector     matrix       irowvec
     1   3| | | | | | Int        int          int
     1   5| | | | | | Int        int          int
     1   8| | | | Matrix     matrix       irowvec
     1   9| | | | | Vector     matrix       irowvec
     1   9| | | | | | Int        int          int
     1  11| | | | | | Int        int          int
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "bracket start")

    end = findend.matrix(self, cur)
    if self.disp:
        print "%4d     Matrix     " % cur,
        print "%-20s" % "misc.matrix",
        print repr(self.code[cur : end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    matrix = mc.collection.Matrix(node, cur=cur, code=self.code[cur : end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        vector = mc.collection.Vector(matrix, cur=start, code=self.code[start : end + 1])

        if self.disp:
            print "%4d     Vector     " % (start),
            print "%-20s" % "misc.matrix",
            print repr(self.code[start : end + 1])

        for start, end in array:

            self.create_expression(vector, start, end)

    if not L:

        if self.disp:
            print "%4d     Vector     " % cur,
            print "%-20s" % "misc.matrix",
            print repr("")
        vector = mc.collection.Vector(matrix, cur=cur, code="")

    return findend.matrix(self, cur)
Ejemplo n.º 2
0
def create(self, node, start, end=None, start_opr=None):
    """
Create expression in three steps:

    1) In order, split into sub-expressions for each dividing operator
    2) Address prefixes, postfixes, parenthesises, etc.
    3) Identify the remaining singleton

Args:
    self (Builder): Code constructor.
    node (Node): Reference to the parent node
    start (int): current possition in code
    end (int, optional): end of expression. Required for space-delimited expression.
    start_opr (str, optional): At which operator the recursive process is. (For internal use)

Returns:
	int : index to end of the expression

Examples::

    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "a*b+c/d")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  'a*b+c/d'
       0     Expression  expression.create    'a*b+c/d'
       0     Expression  expression.create    'a*b'
       0     Expression  expression.create    'a'
       0     Var         variables.variable   'a'
       2     Expression  expression.create    'b'
       2     Var         variables.variable   'b'
       4     Expression  expression.create    'c/d'
       4     Expression  expression.create    'c'
       4     Var         variables.variable   'c'
       6     Expression  expression.create    'd'
       6     Var         variables.variable   'd'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1 1Block      code_block   TYPE
    1 1| Statement  code_block   TYPE
    1 1| | Plus       expression   TYPE
    1 1| | | Mul        expression   TYPE
    1 1| | | | Var        unknown      TYPE    a
    1 3| | | | Var        unknown      TYPE    b
    1 5| | | Matrixdivisionexpression   TYPE
    1 5| | | | Var        unknown      TYPE    c
    1 7| | | | Var        unknown      TYPE    d
    """

    if self.code[start:start + 3] == "...":
        start = findend.dots(self, start)
        start += 1
        while self.code[start] in " \t":
            start += 1

    if self.code[start] == ":":

        if self.disp:

            print "%4d     Expression " % (start),
            print "%-20s" % "expression.create",
            print repr(self.code[start:start + 1])

            print "%4d     All        " % (start),
            print "%-20s" % "expression.create",
            print repr(self.code[start:start + 1])

        mc.collection.All(node, cur=start, code=self.code[start])
        return start

    if end is None:
        end = findend.expression(self, start)

    if self.disp:
        print "%4d     Expression " % (start),
        print "%-20s" % "expression.create",
        print repr(self.code[start:end + 1])

    if self.code[start] not in c.e_start:
        self.syntaxerror(start, "expression start")

    operators = [
        "||", "&&", "|", "&", "~=", "==", ">=", ">", "<=", "<", ":", "+", "-",
        ".*", "*", "./", "/", ".\\", "\\", ".^", "^"
    ]

    if not (start_opr is None):
        operators = operators[operators.index(start_opr) + 1:]

    for opr in operators:
        # Pre-screen
        if opr not in self.code[start:end + 1]:
            continue

        starts = [start]
        last = start
        ends = []

        k = start
        while True:

            if self.code[k] == "(":
                k = last = findend.paren(self, k)

            elif self.code[k] == "[":
                k = last = findend.matrix(self, k)

            elif self.code[k] == "{":
                k = last = findend.cell(self, k)

            elif self.code[k] == "'":
                if identify.string(self, k):
                    k = last = findend.string(self, k)
                else:
                    last = k

            elif opr == self.code[k:k + len(opr)]:

                if opr in "+-":
                    # no prefixes and no (scientific) numbers
                    if self.code[last] not in c.letters+c.digits+")]}" or\
                            self.code[k-1] in "dDeE" and self.code[k-2] in\
                            c.digits+"." and self.code[k+1] in c.digits:
                        k += 1
                        continue

                k += len(opr) - 1
                while self.code[k + 1] in " \t":
                    k += 1

                # no all-operator
                if opr == ":" and self.code[k + 1] in ",;\n)]}":
                    k += 1
                    continue

                starts.append(k + 1)
                ends.append(last)

            elif self.code[k] in c.letters + c.digits + "_":
                last = k

            k += 1
            if k >= end:
                ends.append(end)
                break

        if len(ends) > 1:

            node = retrieve_operator(self, opr)(node)
            node.cur = start
            node.code = self.code[starts[0]:ends[-1] + 1]

            for s, e in zip(starts, ends):
                create(self, node, s, e, opr)

            return end

    # All operators removed at this point!

    END = end

    # Prefixes
    while self.code[start] in "-~":

        if self.code[start] == "-":

            node = mc.collection.Neg(node,
                                     cur=start,
                                     code=self.code[start:end + 1])
            start += 1

        if self.code[start] == "~":

            node = mc.collection.Not(node,
                                     cur=start,
                                     code=self.code[start:end + 1])
            start += 1

        while self.code[start] in " \t":
            start += 1

    # Postfixes
    if self.code[end] == "'" and not self.code[start] == "'":
        if self.code[end - 1] == ".":
            node = mc.collection.Transpose(node,
                                           cur=start,
                                           code=self.code[start:end + 1])
            end -= 2
        else:
            node = mc.collection.Ctranspose(node,
                                            cur=start,
                                            code=self.code[start:end + 1])
            node.cur = start
            node.code = self.code[start:end + 1]
            end -= 1

        while self.code[end] in " \t":
            end -= 1

    # Parenthesis
    if self.code[start] == "(":
        if self.code[end] != ")":
            self.syntaxerror(end, "parenthesis end")

        node = mc.collection.Paren(node,
                                   cur=start,
                                   code=self.code[start:end + 1])

        start += 1
        while self.code[start] in " \t":
            start += 1

        end -= 1
        while self.code[end] in " \t":
            end -= 1

        return create(self, node, start, end)

    # Reserved keywords
    elif self.code[start:start +
                   3] == "end" and self.code[start + 3] in " +-:\t" + c.e_end:
        node = mc.collection.End(node,
                                 cur=start,
                                 code=self.code[start:start + 3])

    elif self.code[start:start + 6] == "return" and self.code[start +
                                                              6] in " ,;\n":
        node = mc.collection.Return(node,
                                    cur=start,
                                    code=self.code[start:start + 6])

    elif self.code[start:start + 5] == "break" and self.code[start +
                                                             5] in " ,;\n":
        node = mc.collection.Break(node,
                                   cur=start,
                                   code=self.code[start:start + 5])

    # Rest
    elif self.code[start] == "'":
        if self.code[end] != "'":
            self.syntaxerror(end, "string end")

        if "\n" in self.code[start:end]:
            self.syntaxerror(end, "non line-feed characters in string")

        mc.collection.String(node,
                             self.code[start + 1:end],
                             cur=start,
                             code=self.code[start:end + 1])

    elif self.code[start] in c.digits or\
            self.code[start] == "." and self.code[start+1] in c.digits:
        cur = self.create_number(node, start)

    elif self.code[start] == "[":
        cur = self.create_matrix(node, start)

    elif self.code[start] == "{":
        cur = self.create_cell(node, start)

    else:
        if self.code[start] not in c.letters + "@":
            self.syntaxerror(start, "variable name")

        cur = self.create_variable(node, start)

    return END
Ejemplo n.º 3
0
def matrix(self, node, cur):
    """
Verbatim matrices

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of matrix

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[[1 2] [3 4]]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[[1 2] [3 4]]'
       0     Expression  expression.create    '[[1 2] [3 4]]'
       0     Matrix      misc.matrix          '[[1 2] [3 4]]'
       1     Vector      misc.matrix          '[1 2] [3 4]'
       1     Expression  expression.create    '[1 2]'
       1     Matrix      misc.matrix          '[1 2]'
       2     Vector      misc.matrix          '1 2'
       2     Expression  expression.create    '1'
       2     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
       7     Expression  expression.create    '[3 4]'
       7     Matrix      misc.matrix          '[3 4]'
       8     Vector      misc.matrix          '3 4'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
      10     Expression  expression.create    '4'
      10     Int         misc.number          '4'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1   1Block      code_block   TYPE
     1   1| Statement  code_block   TYPE
     1   1| | Matrix     matrix       irowvec
     1   2| | | Vector     matrix       irowvec
     1   2| | | | Matrix     matrix       irowvec
     1   3| | | | | Vector     matrix       irowvec
     1   3| | | | | | Int        int          int
     1   5| | | | | | Int        int          int
     1   8| | | | Matrix     matrix       irowvec
     1   9| | | | | Vector     matrix       irowvec
     1   9| | | | | | Int        int          int
     1  11| | | | | | Int        int          int
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "bracket start")

    end = findend.matrix(self, cur)
    if self.disp:
        print "%4d     Matrix     " % cur,
        print "%-20s" % "misc.matrix",
        print repr(self.code[cur:end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    matrix = mc.collection.Matrix(node, cur=cur, code=self.code[cur:end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        vector = mc.collection.Vector(matrix,
                                      cur=start,
                                      code=self.code[start:end + 1])

        if self.disp:
            print "%4d     Vector     " % (start),
            print "%-20s" % "misc.matrix",
            print repr(self.code[start:end + 1])

        for start, end in array:

            self.create_expression(vector, start, end)

    if not L:

        if self.disp:
            print "%4d     Vector     " % cur,
            print "%-20s" % "misc.matrix",
            print repr("")
        vector = mc.collection.Vector(matrix, cur=cur, code="")

    return findend.matrix(self, cur)
Ejemplo n.º 4
0
def codeblock(self, parent, start):
    '''
If-ifelse-else branch

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int: Index to end of codeblock

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "a; 'b'; 3")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  'a'
       0     Expression  expression.create    'a'
       0     Var         variables.variable   'a'
       3   Statement     codeblock.codeblock  "'b'"
       3     String  misc.string          "'b'"
       8   Statement     codeblock.codeblock  '3'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
    >>> builder.configure()
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1  1Block      code_block   TYPE
    1  1| Statement  code_block   TYPE
    1  1| | Var        unknown      TYPE    a
    1  4| Statement  code_block   TYPE
    1  4| | String     string       string
    1  9| Statement  code_block   TYPE
    1  9| | Int        int          int
    '''

    cur = start
    block = mc.collection.Block(parent, cur=cur)

    if self.disp:
        print "%4d Codeblock  " % cur,
        print "%-20s" % "codeblock.codeblock"

    while True:

        if self.code[cur] in " \t;":
            pass

        elif self.code[cur] == "\n":
            if len(self.code)-cur < 3:
                break

        #%%PARFOR token
        elif self.code[cur:cur+8] == "%%PARFOR":
            cur = self.create_pragma_parfor(block, cur)
            
        elif self.code[cur] == "%":
            cur = self.create_comment(block, cur)

        elif self.code[cur:cur+3] == "___":
            cur = self.create_verbatim(block, cur)

        elif self.code[cur] == "[":

            # Divide between statement and assignment
            eq_loc = findend.matrix(self, cur)+1

            while self.code[eq_loc] in " \t":
                eq_loc += 1

            if self.code[eq_loc] == "=" and self.code[eq_loc+1] != "=":

                cur = self.create_assigns(block, cur, eq_loc)

            else:

                statement = mc.collection.Statement(block, cur=cur)

                end = findend.expression(self, cur)
                if self.disp:
                    print "%4d   Statement    " % cur,
                    print "%-20s" % "codeblock.codeblock",
                    print repr(self.code[cur:end+1])

                statement.code = self.code[cur:end+1]

                cur = self.create_expression(
                        statement, cur, end=end)


        elif self.code[cur] == "'":

            end = findend.string(self, cur)
            if self.disp:
                print "%4d   Statement    " % cur,
                print "%-20s" % "codeblock.codeblock",
                print repr(self.code[cur:end+1])

            statement = mc.collection.Statement(block, cur=cur,
                    code=self.code[cur:end+1])

            cur = self.create_string(statement, cur)

        elif self.code[cur:cur+4] == "case" and self.code[cur+4] in c.k_end:
            break

        elif self.code[cur:cur+5] == "catch" and self.code[cur+5] in c.k_end:
            break

        elif self.code[cur:cur+3] == "end" and self.code[cur+3] in c.k_end:
            cur += 3
            break

        elif self.code[cur:cur+4] == "else" and self.code[cur+4] in c.k_end:
            break

        elif self.code[cur:cur+6] == "elseif" and self.code[cur+6] in c.k_end:
            break

        elif self.code[cur:cur+6] == "parfor" and self.code[cur+6] in c.k_end:
            cur = self.create_parfor(block, cur)

        elif self.code[cur:cur+3] == "for" and self.code[cur+3] in c.k_end:
            cur = self.create_for(block, cur)

        elif self.code[cur:cur+8] == "function" and\
                self.code[cur+8] in c.k_end + "[":
            cur -= 1
            break

        elif self.code[cur:cur+2] == "if" and self.code[cur+2] in c.k_end:
            cur = self.create_if(block, cur)

        elif self.code[cur:cur+9] == "otherwise" and self.code[cur+9] in c.k_end:
            break

        elif self.code[cur:cur+6] == "switch" and self.code[cur+6] in c.k_end:
            cur = self.create_switch(block, cur)

        elif self.code[cur:cur+3] == "try" and self.code[cur+3] in c.k_end:
            cur = self.create_try(block, cur)

        elif self.code[cur:cur+5] == "while" and self.code[cur+5] in c.k_end:
            cur = self.create_while(block, cur)

        elif self.code[cur:cur+4] == "hold" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur:cur+4] == "grid" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur] in c.e_start:
            j = findend.expression(self, cur)

            j += 1
            while self.code[j] in " \t":
                j += 1
            eq_loc = j

            if self.code[eq_loc] == "=": # and self.code[eq_loc+1] != "=":

                j = eq_loc +1
                while self.code[j] in " \t":
                    j += 1
                if self.code[j] == "@":
                    cur = self.create_lambda_assign(block, cur, eq_loc)
                else:
                    cur = self.create_assign(block, cur, eq_loc)

            else:
                end = findend.expression(self, cur)
                if self.disp:
                    print "%4d   Statement    " % cur,
                    print "%-20s" % "codeblock.codeblock",
                    print repr(self.code[cur:end+1])

                statement = mc.collection.Statement(block, cur=cur,
                        code=self.code[cur:end+1])

                cur = self.create_expression(statement,
                        cur, end=end)

        cur += 1

        if len(self.code)-cur<3:
            break

    block.code = self.code[start:cur+1]
    return cur
Ejemplo n.º 5
0
def codeblock(self, parent, start):
    '''
If-ifelse-else branch

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int: Index to end of codeblock

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "a; 'b'; 3")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  'a'
       0     Expression  expression.create    'a'
       0     Var         variables.variable   'a'
       3   Statement     codeblock.codeblock  "'b'"
       3     String  misc.string          "'b'"
       8   Statement     codeblock.codeblock  '3'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
    >>> builder.configure()
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1  1Block      code_block   TYPE
    1  1| Statement  code_block   TYPE
    1  1| | Var        unknown      TYPE    a
    1  4| Statement  code_block   TYPE
    1  4| | String     string       string
    1  9| Statement  code_block   TYPE
    1  9| | Int        int          int
    '''
    cur = start
    block = mc.collection.Block(parent, cur=cur)

    if self.disp:
        print "%4d Codeblock  " % cur,
        print "%-20s" % "codeblock.codeblock"

    is_end_terminated = False

    while True:
        #print self.code[cur:cur+5]
        if self.code[cur] in " \t;":
            pass

        elif self.code[cur] == "\n":
            if len(self.code) - cur < 3:
                break

        #%#PARFOR token
        elif self.code[cur:cur + 8] == "%#PARFOR":
            cur = self.create_pragma_parfor(block, cur)

        elif self.code[cur] == "%":
            cur = self.create_comment(block, cur)

        elif self.code[cur:cur + 3] == "___":
            cur = self.create_verbatim(block, cur)

        elif self.code[cur] == "[":
            # Divide between statement and assignment
            eq_loc = findend.matrix(self, cur) + 1

            while self.code[eq_loc] in " \t":
                eq_loc += 1

            if self.code[eq_loc] == "=" and self.code[eq_loc + 1] != "=":
                cur = self.create_assigns(block, cur, eq_loc)

            else:
                statement = mc.collection.Statement(block, cur=cur)

                end = findend.expression(self, cur)
                if self.disp:
                    print "%4d   Statement    " % cur,
                    print "%-20s" % "codeblock.codeblock",
                    print repr(self.code[cur:end + 1])

                statement.code = self.code[cur:end + 1]

                cur = self.create_expression(statement, cur, end=end)

        elif self.code[cur] == "'":
            end = findend.string(self, cur)
            if self.disp:
                print "%4d   Statement    " % cur,
                print "%-20s" % "codeblock.codeblock",
                print repr(self.code[cur:end + 1])

            statement = mc.collection.Statement(block,
                                                cur=cur,
                                                code=self.code[cur:end + 1])

            cur = self.create_string(statement, cur)

        elif self.code[cur:cur + 4] == "case" and self.code[cur +
                                                            4] in c.k_end:
            break

        elif self.code[cur:cur + 5] == "catch" and self.code[cur +
                                                             5] in c.k_end:
            break

        elif self.code[cur:cur + 3] == "end" and self.code[cur + 3] in c.k_end:
            cur += 3
            is_end_terminated = True
            break

        elif self.code[cur:cur + 4] == "else" and self.code[cur +
                                                            4] in c.k_end:
            break

        elif self.code[cur:cur + 6] == "elseif" and self.code[cur +
                                                              6] in c.k_end:
            break

        elif self.code[cur:cur + 6] == "parfor" and self.code[cur +
                                                              6] in c.k_end:
            cur = self.create_parfor(block, cur)

        elif self.code[cur:cur + 3] == "for" and self.code[cur + 3] in c.k_end:
            cur = self.create_for(block, cur)

        elif self.code[cur:cur+8] == "function" and\
                self.code[cur+8] in c.k_end + "[":
            cur -= 1
            break

        elif self.code[cur:cur + 2] == "if" and self.code[cur + 2] in c.k_end:
            cur = self.create_if(block, cur)

        elif self.code[cur:cur + 9] == "otherwise" and self.code[cur +
                                                                 9] in c.k_end:
            break

        elif self.code[cur:cur + 6] == "switch" and self.code[cur +
                                                              6] in c.k_end:
            cur = self.create_switch(block, cur)

        elif self.code[cur:cur + 3] == "try" and self.code[cur + 3] in c.k_end:
            cur = self.create_try(block, cur)

        elif self.code[cur:cur + 5] == "while" and self.code[cur +
                                                             5] in c.k_end:
            cur = self.create_while(block, cur)

        elif self.code[cur:cur+4] == "hold" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur:cur+4] == "load" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur:cur+4] == "disp" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur:cur+4] == "grid" and \
            self.code[cur+4] not in c.letters+c.digits+"_":
            cur = self.create_reserved(block, cur)

        elif self.code[cur] in c.e_start:
            j = findend.expression(self, cur)

            j += 1
            while self.code[j] in " \t":
                j += 1
            eq_loc = j

            if self.code[eq_loc] == "=":  # and self.code[eq_loc+1] != "=":

                j = eq_loc + 1
                while self.code[j] in " \t":
                    j += 1
                if self.code[j] == "@":
                    cur = self.create_lambda_assign(block, cur, eq_loc)
                else:
                    cur = self.create_assign(block, cur, eq_loc)

            else:
                end = findend.expression(self, cur)
                if self.disp:
                    print "%4d   Statement    " % cur,
                    print "%-20s" % "codeblock.codeblock",
                    print repr(self.code[cur:end + 1])

                statement = mc.collection.Statement(block,
                                                    cur=cur,
                                                    code=self.code[cur:end +
                                                                   1])

                cur = self.create_expression(statement, cur, end=end)

        cur += 1

        if len(self.code) - cur < 3:
            break
    block.is_end_terminated = is_end_terminated
    block.code = self.code[start:cur + 1]
    return cur
Ejemplo n.º 6
0
def space_delimited(self, start):
    """
Check if list is space-delimited

Args:
    self (Builder): Code constructor
    start (int): Current position in code

Returns:
	bool: True if list consists of whitespace delimiters
    """

    if self.code[start] not in c.l_start:
        self.syntaxerror(start, "list start")

    k = start + 1
    while self.code[k] in " \t":
        k += 1

    if self.code[k] in c.l_end:
        return False

    if self.code[k] not in c.e_start:
        self.syntaxerror(k, "expression start")

    if self.code[k] == "'":
        k = findend.string(self, k) + 1

        while self.code[k] in " \t":
            k += 1

    while True:

        if self.code[k] == "(":
            k = findend.paren(self, k)

        elif self.code[k] == "[":
            k = findend.matrix(self, k)

        elif self.code[k] == "{":
            k = findend.cell(self, k)

        elif self.code[k] == "'":
            # if self.code[k-1] in c.s_start:
            return True

        elif self.code[k : k + 3] == "...":
            k = findend.dots(self, k)

        elif self.code[k] in " \t":
            if space_delimiter(self, k):
                return True
            while self.code[k + 1] in " \t":
                k += 1

        elif self.code[k] in c.e_end:
            if self.code[k] == ",":
                return False
            elif self.code[k] in c.l_end:
                return False
            elif self.code[k] != ";":
                return True

            while self.code[k + 1] in " \t":
                k += 1

        elif self.code[k + 1] in c.letters + c.digits + "_@":
            while self.code[k + 1] in c.letters + c.digits + "_@":
                k += 1
        k += 1
Ejemplo n.º 7
0
def create(self, node, start, end=None, start_opr=None):
    """
Create expression in three steps:

    1) In order, split into sub-expressions for each dividing operator
    2) Address prefixes, postfixes, parenthesises, etc.
    3) Identify the remaining singleton

Args:
    self (Builder): Code constructor.
    node (Node): Reference to the parent node
    start (int): current possition in code
    end (int, optional): end of expression. Required for space-delimited expression.
    start_opr (str, optional): At which operator the recursive process is. (For internal use)

Returns:
	int : index to end of the expression

Examples::

    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "a*b+c/d")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  'a*b+c/d'
       0     Expression  expression.create    'a*b+c/d'
       0     Expression  expression.create    'a*b'
       0     Expression  expression.create    'a'
       0     Var         variables.variable   'a'
       2     Expression  expression.create    'b'
       2     Var         variables.variable   'b'
       4     Expression  expression.create    'c/d'
       4     Expression  expression.create    'c'
       4     Var         variables.variable   'c'
       6     Expression  expression.create    'd'
       6     Var         variables.variable   'd'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1 1Block      code_block   TYPE
    1 1| Statement  code_block   TYPE
    1 1| | Plus       expression   TYPE
    1 1| | | Mul        expression   TYPE
    1 1| | | | Var        unknown      TYPE    a
    1 3| | | | Var        unknown      TYPE    b
    1 5| | | Matrixdivisionexpression   TYPE
    1 5| | | | Var        unknown      TYPE    c
    1 7| | | | Var        unknown      TYPE    d
    """

    if self.code[start:start+3] == "...":
        start = findend.dots(self, start)
        start += 1
        while self.code[start] in " \t":
            start += 1

    if self.code[start] == ":":

        if self.disp:

            print "%4d     Expression " % (start),
            print "%-20s" % "expression.create",
            print repr(self.code[start:start+1])

            print "%4d     All        " % (start),
            print "%-20s" % "expression.create",
            print repr(self.code[start:start+1])

        mc.collection.All(node, cur=start, code=self.code[start])
        return start

    if end is None:
        end = findend.expression(self, start)

    if self.disp:
        print "%4d     Expression " % (start),
        print "%-20s" % "expression.create",
        print repr(self.code[start:end+1])

    if  self.code[start] not in c.e_start:
        self.syntaxerror(start, "expression start")


    operators = [
        "||", "&&", "|", "&",
        "~=", "==", ">=", ">", "<=", "<",
        ":", "+", "-",
        ".*", "*", "./", "/", ".\\", "\\",
        ".^", "^"]

    if not (start_opr is None):
        operators = operators[operators.index(start_opr)+1:]

    for opr in operators:
        # Pre-screen
        if opr not in self.code[start:end+1]:
            continue

        starts = [start]
        last = start
        ends = []

        k = start
        while True:

            if self.code[k] == "(":
                k = last = findend.paren(self, k)

            elif self.code[k] == "[":
                k = last = findend.matrix(self, k)

            elif self.code[k] == "{":
                k = last = findend.cell(self, k)

            elif self.code[k] == "'":
                if identify.string(self, k):
                    k = last = findend.string(self, k)
                else:
                    last = k

            elif opr == self.code[k:k+len(opr)]:

                if opr in "+-":
                    # no prefixes and no (scientific) numbers
                    if self.code[last] not in c.letters+c.digits+")]}" or\
                            self.code[k-1] in "dDeE" and self.code[k-2] in\
                            c.digits+"." and self.code[k+1] in c.digits:
                        k += 1
                        continue


                k += len(opr)-1
                while self.code[k+1] in " \t":
                    k += 1

                # no all-operator
                if opr == ":" and self.code[k+1] in ",;\n)]}":
                    k += 1
                    continue

                starts.append(k+1)
                ends.append(last)

            elif self.code[k] in c.letters+c.digits+"_":
                last = k

            k += 1
            if k >= end:
                ends.append(end)
                break

        if len(ends)>1:

            node = retrieve_operator(self, opr)(node)
            node.cur = start
            node.code = self.code[starts[0]:ends[-1]+1]

            for s,e in zip(starts, ends):
                create(self, node, s, e, opr)

            return end


    # All operators removed at this point!

    END = end

    # Prefixes
    while self.code[start] in "-~":

        if self.code[start] == "-":

            node = mc.collection.Neg(node, cur=start, code=self.code[start:end+1])
            start += 1

        if self.code[start] == "~":

            node = mc.collection.Not(node, cur=start, code=self.code[start:end+1])
            start += 1

        while self.code[start] in " \t":
            start += 1

    # Postfixes
    if self.code[end] == "'" and not self.code[start] == "'":
        if self.code[end-1] == ".":
            node = mc.collection.Transpose(node, cur=start,
                    code=self.code[start:end+1])
            end -= 2
        else:
            node = mc.collection.Ctranspose(node, cur=start,
                    code=self.code[start:end+1])
            node.cur = start
            node.code = self.code[start:end+1]
            end -= 1

        while self.code[end] in " \t":
            end -= 1

    # Parenthesis
    if self.code[start] == "(":
        if self.code[end] != ")":
            self.syntaxerror(end, "parenthesis end")

        node = mc.collection.Paren(node, cur=start, code=self.code[start:end+1])

        start += 1
        while self.code[start] in " \t":
            start += 1

        end -= 1
        while self.code[end] in " \t":
            end -= 1

        return create(self, node, start, end)

    # Reserved keywords
    elif self.code[start:start+3] == "end": # and self.code[start+3] in " \t" + c.e_end:
        node = mc.collection.End(node, cur=start, code=self.code[start:start+3])

    elif self.code[start:start+6] == "return" and self.code[start+6] in " ,;\n":
        node = mc.collection.Return(node, cur=start, code=self.code[start:start+6])

    elif self.code[start:start+5] == "break" and self.code[start+5] in " ,;\n":
        node = mc.collection.Break(node, cur=start, code=self.code[start:start+5])


    # Rest
    elif self.code[start] == "'":
        if self.code[end] != "'":
            self.syntaxerror(end, "string end")

        if "\n" in self.code[start:end]:
            self.syntaxerror(end, "non line-feed characters in string")

        mc.collection.String(node, self.code[start+1:end], cur=start,
                code=self.code[start:end+1])

    elif self.code[start] in c.digits or\
            self.code[start] == "." and self.code[start+1] in c.digits:
        cur = self.create_number(node, start)

    elif self.code[start] == "[":
        cur = self.create_matrix(node, start)

    elif self.code[start] == "{":
        cur = self.create_cell(node, start)

    else:
        if self.code[start] not in c.letters+"@":
            self.syntaxerror(start, "variable name")

        cur = self.create_variable(node, start)

    return END
Ejemplo n.º 8
0
def space_delimited(self, start):
    """
Check if list is space-delimited

Args:
    self (Builder): Code constructor
    start (int): Current position in code

Returns:
	bool: True if list consists of whitespace delimiters
    """

    if self.code[start] not in c.l_start:
        self.syntaxerror(start, "list start")

    k = start + 1
    while self.code[k] in " \t":
        k += 1

    if self.code[k] in c.l_end:
        return False

    if self.code[k] not in c.e_start:
        self.syntaxerror(k, "expression start")

    if self.code[k] == "'":
        k = findend.string(self, k) + 1

        while self.code[k] in " \t":
            k += 1

    while True:

        if self.code[k] == "(":
            k = findend.paren(self, k)

        elif self.code[k] == "[":
            k = findend.matrix(self, k)

        elif self.code[k] == "{":
            k = findend.cell(self, k)

        elif self.code[k] == "'" and string(self, k):
            #k = findend.string(self, k)
            #if self.code[k-1] in c.s_start:
            return True

        elif self.code[k:k + 3] == "...":
            k = findend.dots(self, k)

        elif self.code[k] in " \t":
            if space_delimiter(self, k):
                return True
            while self.code[k + 1] in " \t":
                k += 1

        elif self.code[k] in c.e_end:
            if self.code[k] == ",":
                return False
            elif self.code[k] in c.l_end:
                return False
            elif self.code[k] != ";":
                return True

            while self.code[k + 1] in " \t":
                k += 1

        elif self.code[k + 1] in c.letters + c.digits + "_@":
            while self.code[k + 1] in c.letters + c.digits + "_@":
                k += 1
        k += 1