def __init__(self, token = Token(), child1 = None, child2 = None): self.node = token self.children = [] if (child1): self.children.append(child1) if (child2): self.children.append(child2)
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 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 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 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 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 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 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 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 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 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 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 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 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
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