def parseStmt(self): self.curlex = self.lexAnalizer.getLex() stmt = '' if self.curlex.lex == "begin": stmt = self.parseBlock() elif self.curlex.lex == "if": stmt = self.parseIf() elif self.curlex.lex == "while": stmt = self.parseWhile() elif self.curlex.lex == "repeat": stmt = self.parseRepeatUntil() elif self.curlex.lex == "var": varW = Symbols.KeyWordNode(self.curlex) self.lexAnalizer.nextLex() stmt = Symbols.ProgVarBlockNode(varW, self.parseVar()) elif self.curlex.lex == "for": stmt = self.parseFor() elif self.curlex.lex == "break": self.lexAnalizer.nextLex() stmt = Symbols.KeyWordNode(self.curlex) elif self.curlex.lex == "continue": self.lexAnalizer.nextLex() stmt = Symbols.KeyWordNode(self.curlex) elif self.curlex.type == "Identifier": stmt = self.parseAssigmOrFunc() elif self.curlex.lex == "readln": stmt = self.parseReadln() elif self.curlex.lex == "writeln": stmt = self.parseWriteln() elif self.curlex.lex == "end" or self.curlex.lex == ";": return Symbols.NullNode() if stmt: return stmt return Symbols.NullNode()
def parseVar(self): self.curlex = self.lexAnalizer.getLex() varnames = [] if self.curlex.type == 'Delimiter': return (Symbols.NullNode()) self.RequireType(["Identifier"]) if self.curlex.lex not in self.stackTable[-1]: self.stackTable[-1][self.curlex.lex] = '' else: self.errorshow( f'Переменная {str(self.curlex.lex)} объявлена повторно') oplex = self.lexAnalizer.nextLex() varnames.append(self.curlex) while oplex.lex == ",": self.curlex = self.lexAnalizer.nextLex() self.RequireType(["Identifier"]) if self.curlex.lex not in self.stackTable[-1]: self.stackTable[-1][self.curlex.lex] = '' else: self.errorshow( f'Переменная {str(self.curlex.lex)} объявлена повторно') varibl = self.parseFactor() varnames.append(self.curlex) oplex = self.lexAnalizer.getLex() oprtn = Symbols.VarAssignNode(self.lexAnalizer.getLex()) self.Require([":", ":="]) self.curlex = self.lexAnalizer.getLex() if self.curlex.lex == ";": self.errorshow( f'Встречено {str(self.curlex.lex)}, ожидалось выражение') if (self.curlex.type == "Identifier" or self.curlex.lex == "array") and oprtn.name == ':': vartype = self.perseInitType( ) # возращать надо SymType или SymArray oprtn = Symbols.NullNode() self.curlex = self.lexAnalizer.nextLex() exprnode = Symbols.NullNode() elif oprtn.name == ':=': exprnode = self.parseExpression() vartype = exprnode.lexref.typeref.name varnodeslist = [] for i in varnames: self.stackTable[-1][i.lex] = vartype varnodeslist.append( Symbols.ProgVarNode(i, self.stackTable[-1][i.lex], exprnode, oprtn)) return varnodeslist
def parseIf(self): self.Require(['if']) expression = self.parseExpression() if expression.lexref.typeref.name != "boolean": self.errorshow(f'Условие должно быть типа boolean') self.Require(['then']) body = self.parseStmt() if self.lexAnalizer.getLex() == 'else': self.lexAnalizer.nextLex() elsebody = self.parseStmt() else: elsebody = Symbols.NullNode() return Symbols.IfNode(expression, body, elsebody)
def formalParameter(self, name): funcname = self.lexAnalizer.getLex() self.RequireType(["Identifier"]) self.lexAnalizer.nextLex() self.curlex = self.lexAnalizer.getLex() args = [] if self.curlex.lex == "(": self.lexAnalizer.nextLex() while self.curlex.lex == ";" or self.curlex.lex == "(": self.curlex = self.lexAnalizer.getLex() if self.curlex.lex == 'var': varcallW = Symbols.KeyWordNode(self.curlex) self.curlex = self.lexAnalizer.nextLex() for i in self.parseVar(): args.append(Symbols.FuncProcRefArg(varcallW, i)) else: for i in self.parseVar(): args.append(Symbols.FuncProcValArg(i)) self.curlex = self.lexAnalizer.getLex() self.Require([")"]) else: args.append(Symbols.NullNode()) return [funcname, args]
def parseFactor(self): self.curlex = self.lexAnalizer.getLex() oplex = self.lexAnalizer.getLex() if oplex.lex.lower() in ['not', '+', '-', '^', '@']: operation = oplex self.lexAnalizer.nextLex() right = self.parseFactor() self.checkNodeType([Symbols.NullNode], right) symexpr = Symbols.SymExpr(operation, Symbols.NullNode(), right, right.lexref.typeref) return Symbols.UnarOpNode(symexpr) if self.curlex.type == "Identifier": ident = self.curlex symb_var = '' for i in reversed(self.stackTable): if ident.lex in i: self.lexAnalizer.nextLex() symb_var = Symbols.SymVar(ident, i[ident.lex]) tableElem = i[ident.lex] break if not symb_var: self.errorshow( f'Переменная {self.curlex.lex} не была объявлена') oplex = self.lexAnalizer.getLex() if oplex.type == "Delimiter" and oplex.lex == "[": mid = [] middle = [] while oplex.lex in [',', '[']: self.lexAnalizer.nextLex() mid.append(self.parseExpression()) oplex = self.lexAnalizer.getLex() if len(mid) != len(tableElem.diap): self.errorshow( f'Неверное количество индексов, ожидалось {len(tableElem.diap)}' ) for i in range(len(mid)): mint = '' try: mint = int(mid[i].lexref.name.lex) except: pass if mint: if mint <= tableElem.diap[i][ 0] or mint >= tableElem.diap[i][1]: self.errorshow(f'Индекс за пределами диапазона') else: if mid[i].lexref.typeref.name != 'integer': self.errorshow(f'Тип должен быть integer') middle.append(mid[i].lexref.name.lex) self.curlex = self.lexAnalizer.getLex() self.Require(["]"]) return Symbols.toMassNode(symb_var, middle) if oplex.type == "Delimiter" and oplex.lex == "(": main = self.curlex open = oplex self.curlex = self.lexAnalizer.nextLex() mid = [] if self.lexAnalizer.getLex().lex == ')': self.curlex = self.lexAnalizer.nextLex() else: while self.curlex.lex != ")": mid.append(self.parseExpression()) self.curlex = self.lexAnalizer.getLex() self.Require([")", ","]) if type(tableElem) != Symbols.SymVoid: if len(mid) != len(tableElem.args): self.errorshow( f'Указано неверное количество аргументов') for i in range(len(mid)): if mid[i].lexref.typeref.name != tableElem.args[ i].varNode.vartype.name: if not (mid[i].lexref.typeref.name == "integer" and tableElem.args[i].varNode.vartype.name == 'float'): self.errorshow( f'Указана переменная неверного типа') return Symbols.callNode(tableElem, mid) return Symbols.IdentNode(symb_var) elif self.curlex.type == "Integer": varSym = Symbols.SymInt(self.curlex, Symbols.SymType(self.curlex.type.lower())) self.lexAnalizer.nextLex() return Symbols.NumberNode(varSym) elif self.curlex.type == "Float": varSym = Symbols.SymFlaot( self.curlex, Symbols.SymType(self.curlex.type.lower())) self.lexAnalizer.nextLex() return Symbols.NumberNode(varSym) elif self.curlex.type == "String": varSym = Symbols.SymStr(self.curlex, Symbols.SymType(self.curlex.type.lower())) self.lexAnalizer.nextLex() return Symbols.StringConstNode(varSym) elif self.curlex.lex == "(": self.lexAnalizer.nextLex() self.curlex = self.lexAnalizer.getLex() curNode = self.parseExpression() self.checkNodeType([Symbols.NullNode], curNode) self.curlex = self.lexAnalizer.getLex() self.Require([")"]) return curNode return Symbols.NullNode()