예제 #1
0
 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()
예제 #2
0
 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
예제 #3
0
 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)
예제 #4
0
 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]
예제 #5
0
    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()