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)
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
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)
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
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
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
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
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