def Module(): skip(Lex.MODULE) if lex() == Lex.NAME: modRef = table.new(cat.Module(scan.name())) nextLex() else: Expected("имя") skip(Lex.SEMI) L = lex() if lex() == Lex.IMPORT: Import() DeclSeq() if lex() == Lex.BEGIN: nextLex() StatSeq() skip(Lex.END) check(Lex.NAME) x = table.find(scan.name()) if x != modRef: Expected(f"имя модуля {modRef.name}") nextLex() skip(Lex.DOT) Gen(cm.STOP) AllocVars()
def Function(x: cat.Func): if x.name == "ABS": intExpr() Gen(cm.DUP) gen.Const(0) Gen(gen.PC + 3) Gen(cm.IFGE) Gen(cm.NEG) elif x.name == "MIN": check(Lex.NAME) x = table.find(scan.name()) if type(x) != cat.Type: Expected("имя типа") nextLex() Gen(scan.MAXINT) Gen(cm.NEG) Gen(1) Gen(cm.SUB) elif x.name == "MAX": check(Lex.NAME) x = table.find(scan.name()) if type(x) != cat.Type: Expected("имя типа") nextLex() gen.Const(scan.MAXINT) elif x.name == "ODD": intExpr() Gen(1) Gen(cm.MOD) Gen(0) Gen(cm.IFNE) else: assert False
def varDecl(): while lex() == Lex.NAME: table.new(cat.Var(scan.name(), Types.Int, 0)) nextLex() while lex() == Lex.COMMA: nextLex() check(Lex.NAME) table.new(cat.Var(scan.name(), Types.Int, 0)) nextLex() skip(Lex.COLON) Type() skip(Lex.SEMI)
def Factor(): T = None if lex() == Lex.NUM: Gen(scan.num()) nextLex() T = Types.Int elif lex() == Lex.NAME: x = table.find(scan.name()) if type(x) == cat.Var: gen.Addr(x) Gen(cm.LOAD) nextLex() T = x.type elif type(x) == cat.Const: gen.Const(x.val) T = x.type nextLex() elif type(x) == cat.Func: nextLex() skip(Lex.LPAR) Function(x) T = x.type skip(Lex.RPAR) else: Expected("функция, константа или переменная") elif lex() == Lex.LPAR: nextLex() T = Expression() skip(Lex.RPAR) else: Expected("имя число или выражение в скобках") return T
def ConstDecl(): while lex() == Lex.NAME: ident = scan.name() nextLex() skip(Lex.EQ) val = ConstExpr() table.new(cat.Const(ident, val, Types.Int)) skip(Lex.SEMI)
def Variable(): check(Lex.NAME) x = table.find(scan.name()) if type(x) == cat.Var: gen.Addr(x) else: Expected("переменная") nextLex()
def AssOrCall(): check(Lex.NAME) x = table.find(scan.name()) nextLex() if type(x) == cat.Module: module = x.name skip(Lex.DOT) check(Lex.NAME) pname = module + "." + scan.name() x = table.find(pname) if type(x) == cat.Proc: nextLex() if lex() == Lex.LPAR: nextLex() Procedure(x) skip(Lex.RPAR) else: Procedure(x) else: Expected("процедура") elif type(x) == cat.Proc: if lex() == Lex.LPAR: nextLex() Procedure(x) skip(Lex.RPAR) else: Procedure(x) elif type(x) == cat.Var: gen.Addr(x) skip(Lex.ASS) p = loc.lexPos T = Expression() if T != x.type: posError("Несоответствие типа", p) Gen(cm.SAVE) else: Expected("вызов процедуры или присваивание")
def ConstExpr(): sign = -1 if lex() == Lex.MINUS else +1 if lex() in {Lex.PLUS, Lex.MINUS}: nextLex() if lex() == Lex.NUM: val = sign * scan.num() nextLex() elif lex() == Lex.NAME: const = table.find(scan.name()) if type(const) != cat.Const: Expected("константа") val = sign * const.val nextLex() else: Expected("константа") return val
def Type(): check(Lex.NAME) x = table.find(scan.name()) if type(x) != cat.Type: Expected("имя типа") nextLex()
def ImportName(): check(Lex.NAME) if scan.name() not in {"In", "Out"}: cntError("Неизвестный модуль") table.new(cat.Module(scan.name())) nextLex()