def dBStepOrTraceStatement(self): root = Tree(self.next()) self.consume() if (self.matchAny([',', ';', '\n'])): return root root.addChild(self.expression()) return root
def matDef(self, basetokenvalue, closebracketvalue): # Octave compatibility mode requires commas between matrix entries, so white # space is ignored inside matrix definitions. if (not self.octCompat): self.lex.pushWSFlag(False) matdef = Tree(Token(basetokenvalue)) self.consumeIfFound(Token.TOK_SPACE) while (not self.match(closebracketvalue)): rowdef = self.rowDef(closebracketvalue) matdef.addChild(rowdef) if (not self.octCompat): self.lex.popWSFlag() return matdef
def multiFunctionCall(self): root = self.expect('[') root.rename(Token.TOK_MULTI) lhs = Tree(Token(Token.TOK_BRACKETS, self.lex.contextNum())) while (not self.match(']')): lhs.addChild(self.variableDereference()) self.consumeIfFound(',') self.expect(']') root.addChild(lhs) self.expect('=') root.addChild(self.expression()) return root
def statementList(self): stlist = Tree(Token(Token.TOK_BLOCK, self.lex.contextNum())) self.flushSeperators() s = self.statement() while (s.valid()): sep = self.statementSeperator() if (not sep.valid()): return stlist sep.addChild(s) stlist.addChild(sep) self.flushSeperators() s = self.statement() return stlist
def rowDef(self, closebracketvalue): rowdef = Tree(Token(Token.TOK_ROWDEF, self.lex.contextNum())) while (not self.match(';') and not self.match('\n') and not self.match(closebracketvalue)): rowdef.addChild(self.expression()) if (self.match(',')): self.consume() while (self.match(Token.TOK_SPACE)): self.consume() elif self.match(Token.TOK_SPACE): self.consume() if (self.matchAny([';', '\n'])): self.consume() self.consumeIfFound(Token.TOK_SPACE) return rowdef
def tryStatement(self): root = self.expect(Token.TOK_TRY) self.statementSeperator() block = self.statementList() root.addChild(block) if (self.match(Token.TOK_CATCH)): catchblock = Tree(self.next()) self.consume() self.statementSeperator() block = self.statementList() catchblock.addChild(block) root.addChild(catchblock) self.expect(Token.TOK_END, "TRY block") return root
def forIndexExpression(self): if (self.match('(')): self.consume() ret = self.forIndexExpression() self.expect(')') return ret ident = self.identifier() if (self.match('=')): root = Tree(self.next()) self.consume() expr = self.expression() root.addChildren(ident, expr) return root else: return ident
def transposeFixup(self, base): while (self.next() in ['\'', Token.TOK_DOTTRANSPOSE]): base = Tree(self.next(), base) self.consume() if (self.match(Token.TOK_SPACE)): if (not ((self.lex.peek(0, '-') or self.lex.peek(0, '+')) and not self.lex.peek(1, ' '))): self.consume() if (self.octCompat): if (self.match(Token.TOK_INCR)): base = Tree(Token.TOK_INCR_POSTFIX, base) self.consume() elif (self.match(Token.TOK_DECR)): base = Tree(Token.TOK_DECR_POSTFIX, base) self.consume() return base
def statement(self): if (self.match(Token.TOK_EOF)): return Tree() if (self.match(Token.TOK_END)): return Tree() if (self.match(Token.TOK_FOR)): return self.forStatement() if (self.match(Token.TOK_BREAK)): return self.singletonStatement() if (self.match(Token.TOK_CONTINUE)): return self.singletonStatement() if (self.match(Token.TOK_DBUP) or self.match(Token.TOK_DBDOWN)): return self.singletonStatement() if (self.match(Token.TOK_WHILE)): return self.whileStatement() if (self.match(Token.TOK_DBSTEP) or self.match(Token.TOK_DBTRACE)): return self.dBStepOrTraceStatement() if (self.match(Token.TOK_IF)): return self.ifStatement() if (self.match(Token.TOK_SWITCH)): return self.switchStatement() if (self.match(Token.TOK_TRY)): return self.tryStatement() if (self.match(Token.TOK_KEYBOARD) or self.match(Token.TOK_RETURN) or self.match(Token.TOK_RETALL) or self.match(Token.TOK_QUIT)): return self.singletonStatement() if (self.match(Token.TOK_GLOBAL) or self.match(Token.TOK_PERSISTENT)): return self.declarationStatement() # Now come the tentative parses save = copy.deepcopy(self.lex) if (self.match(Token.TOK_IDENT)): try: retval = self.assignmentStatement() self.lastpos = 0 return retval except ParseError: self.lex = save if (self.match('[')): try: retval = self.multiFunctionCall() self.lastpos = 0 return retval except ParseError: self.lex = save if (self.match(Token.TOK_IDENT)): try: retval = self.specialFunctionCall() self.lastpos = 0 return retval except ParseError: self.lex = save if (self.match(Token.TOK_FUNCTION)): try: retval = self.functionDefinition() retval.rename(Token.TOK_NEST_FUNC) self.expect(Token.TOK_END, "FUNCTION definition") self.lastpos = 0 return retval except ParseError: self.lex = save try: retval = Tree(Token(Token.TOK_EXPR, self.lex.contextNum())) retval.addChild(self.expression()) self.lastpos = 0 return retval except ParseError: self.lex = save return Tree()
def minusEqStatement(self, ident): opr = self.next() self.consume() opr.value = '=' root = Tree(opr) expr = self.expression() opr.value = '-' adder = Tree(opr) adder.addChildren(ident, expr) root.addChildren(ident, adder) return root
def exp(self, priority): t = self.primaryExpression() if (self.octCompat and (self.matchAny(['(', '{', '.']))): sub = Tree(Token(Token.TOK_REINDEX, self.lex.contextNum())) sub.addChild(t) self.indexingExpressions(sub, True) t = sub while (self.next().isBinaryOperator() and (Parser.OP_PRECEDENCE[self.next().value] >= priority)): opr_save = self.next() self.consume() self.consumeIfFound(Token.TOK_SPACE) if (opr_save.isRightAssociative()): q = Parser.OP_PRECEDENCE[opr_save.value] else: q = 1 + Parser.OP_PRECEDENCE[opr_save.value] t1 = self.exp(q) t = Tree(opr_save, t, t1) return t
def statementSeperator(self): root = Tree() if (self.match(';')): root = Tree( Token(Token.TOK_QSTATEMENT, AdjustContextOne(self.lex.contextNum()))) self.consume() self.consumeIfFound('\n') elif (self.match('\n')): root = Tree( Token(Token.TOK_STATEMENT, AdjustContextOne(self.lex.contextNum()))) self.consume() elif (self.match(',')): root = Tree( Token(Token.TOK_STATEMENT, AdjustContextOne(self.lex.contextNum()))) self.consume() return root
def expect(self, tokenvalue, because=""): ret = self.next() if (self.lex.next() != tokenvalue): if (tokenvalue != Token.TOK_EOF): self.serror("Expecting " + str(Token(tokenvalue)) + " for " + because) else: self.serror("Unexpected input") else: self.consume() return Tree(ret)
def unaryExpression(self): opr = self.next() self.consume() self.consumeIfFound(Token.TOK_SPACE) if (opr == '+'): opr.value = Token.TOK_UNARY_PLUS if (opr == '-'): opr.value = Token.TOK_UNARY_MINUS if (opr == Token.TOK_INCR): opr.value = Token.TOK_INCR_PREFIX if (opr == Token.TOK_DECR): opr.value = Token.TOK_DECR_PREFIX q = Parser.OP_PRECEDENCE[opr.value] child = self.exp(q) return Tree(opr, child)
def indexingParens(self, root, blankRefOK): self.consume() if (self.octCompat): self.lex.pushWSFlag(True) sub = Tree(Token(Token.TOK_PARENS, self.lex.contextNum())) while (not self.match(')')): if (self.match(':')): sub.addChild(self.expect(':')) elif (self.match('/')): sub.addChild(self.keyword()) else: sub.addChild(self.expression()) if (not self.match(')')): self.expect(',') if ((sub.numChildren() == 0) and (not blankRefOK)): if (self.octCompat): self.lex.popWSFlag() self.serror("The expression A() is not allowed.") self.expect(')') if (self.octCompat): self.lex.popWSFlag() root.addChild(sub)
def functionArgs(self, root): # Process (optional) args if (self.match('(')): self.consume() args = Tree(Token(Token.TOK_PARENS, self.lex.contextNum())) while (not self.match(')')): ident = Tree() if (self.match('&')): ident = self.expect('&') ident.addChild(self.identifier()) else: ident = self.identifier() args.addChild(ident) if (not self.match(')')): self.expect(',') self.expect(')') root.addChild(args) else: root.addChild(Tree(Token(Token.TOK_PARENS, self.lex.contextNum())))
def anonymousFunctionExpression(self): root = Tree(self.next()) self.consume() if (self.match('(')): root.addChild(self.anonymousFunction()) else: root.addChild(self.identifier()) return self.transposeFixup(root)
def process(self): self.lastpos = 0 while (self.match('\n')): self.consume() try: if (self.match(Token.TOK_FUNCTION)): root = Tree( Token(Token.TOK_FUNCTION_DEFS, self.lex.contextNum())) while (self.match(Token.TOK_FUNCTION)): child = self.functionDefinition() root.addChild(child) while (self.match('\n')): self.consume() # print root if (HasNestedFunctions(root) or self.match(Token.TOK_END)): self.expect(Token.TOK_END) while (self.match('\n')): self.consume() while (self.match(Token.TOK_FUNCTION)): root.addChild(self.functionDefinition()) if (HasNestedFunctions(root) or self.match(Token.TOK_END)): self.expect(Token.TOK_END) while (self.match('\n')): self.consume() else: root = Tree(Token(Token.TOK_SCRIPT, self.lex.contextNum())) root.addChild(self.statementList()) except ParseError as e: raise NameError(self.lastErr + self.lex.context(self.lastpos)) try: self.expect(Token.TOK_EOF) except ParseError as e: # print root raise NameError("Unexpected input ") return root
def indexingBraces(self, root): self.consume() sub = Tree(Token(Token.TOK_BRACES, self.lex.contextNum())) while (not self.match('}')): if (self.match(':')): sub.addChild(self.expect(':')) else: sub.addChild(self.expression()) if (not self.match('}')): self.expect(',') if (sub.numChildren() == 0): self.serror("The expression A{} is not allowed.") self.expect('}') root.addChild(sub)
def functionReturnList(self, root): if (self.match('[')): self.consume() lhs = Tree(Token(Token.TOK_BRACKETS, self.lex.contextNum())) while (not self.match(']')): lhs.addChild(self.identifier()) self.consumeIfFound(',') self.expect(']') root.addChild(lhs) self.expect('=') root.addChild(self.identifier()) else: save = self.identifier() if (self.match('=')): lhs = Tree(Token(Token.TOK_BRACKETS, self.lex.contextNum())) lhs.addChild(save) root.addChild(lhs) self.expect('=') root.addChild(self.identifier()) else: root.addChild( Tree(Token(Token.TOK_BRACKETS, self.lex.contextNum()))) root.addChild(save)
def ifStatement(self): root = self.expect(Token.TOK_IF) test = self.expression() self.statementSeperator() trueblock = self.statementList() root.addChildren(test, trueblock) while (self.match(Token.TOK_ELSEIF)): elseif = Tree(self.next()) self.consume() test = self.expression() block = self.statementList() elseif.addChildren(test, block) root.addChild(elseif) if (self.match(Token.TOK_ELSE)): elseblk = Tree(self.next()) self.consume() block = self.statementList() elseblk.addChild(block) root.addChild(elseblk) self.expect(Token.TOK_END, " IF block") return root
def indexingExpressions(self, root, blankRefOK): deref = True while (deref): if self.match('('): self.indexingParens(root, blankRefOK) elif self.match('{'): self.indexingBraces(root) elif self.match('.'): dynroot = Tree(self.next()) self.consume() if (self.match('(')): self.consume() dynroot.rename(Token.TOK_DYN) dynroot.addChild(self.expression()) root.addChild(dynroot) self.expect(')') else: dynroot.addChild(self.identifier()) root.addChild(dynroot) else: deref = False
def switchStatement(self): root = self.expect(Token.TOK_SWITCH) swexpr = self.expression() root.addChild(swexpr) self.flushSeperators() while (self.match(Token.TOK_CASE)): caseblock = Tree(self.next()) self.consume() csexpr = self.expression() self.statementSeperator() block = self.statementList() caseblock.addChildren(csexpr, block) root.addChild(caseblock) if (self.match(Token.TOK_OTHERWISE)): otherwise = Tree(self.next()) self.consume() self.statementSeperator() block = self.statementList() otherwise.addChild(block) root.addChild(otherwise) self.expect(Token.TOK_END, " SWITCH block") return root
def specialFunctionCall(self): self.lex.pushWSFlag(False) root = Tree(Token(Token.TOK_SPECIAL, self.lex.contextNum())) root.addChild(self.identifier()) # Next must be a whitespace if (not self.match(Token.TOK_SPACE)): self.serror("Not special call") self.consume() t_lex = copy.deepcopy(self.lex) if (t_lex.next() in [';', '\n', '(', ',']): self.serror("Not special call") if (t_lex.next().isBinaryOperator() or t_lex.next().isUnaryOperator()): t_lex.self.consume() if (t_lex.next() == Token.TOK_SPACE): self.serror("Not special call") # If the next thing is a character or a number, we grab "blobs" self.lex.setBlobMode(True) while (not self.match(';') and not self.match('\n') and not (self.match(','))): root.addChild(Tree(self.next())) self.consume() self.consumeIfFound(Token.TOK_SPACE) self.lex.setBlobMode(False) self.lex.popWSFlag() return root
def singletonStatement(self): root = Tree(self.next()) self.consume() return root
def identifier(self): if (not self.match(Token.TOK_IDENT)): self.serror("self.expecting identifier") ret = Tree(self.next()) self.consume() return ret
def declarationStatement(self): root = Tree(self.next()) self.consume() while (self.match(Token.TOK_IDENT)): root.addChild(self.identifier()) return root
def literalExpression(self): t = Tree(self.next()) self.consume() return self.transposeFixup(t)
from fmtree import Tree from fmtoken import Token a = Tree(Token('a')) b = Tree(Token('b')) c = Tree(Token('+'), a, b) print c
def variableDereference(self, blankRefOK=True): ident = self.identifier() root = Tree(Token(Token.TOK_VARIABLE, self.lex.contextNum())) root.addChild(ident) self.indexingExpressions(root, blankRefOK) return root