#eingabe = \ """ # a = b a = 4 b = 17 h = 0 tst a jmp (+2) jmp (+3) dec a jmp (-4) tst b jmp (+2) jmp (+5) dec b inc a inc h jmp (-6) tst h jmp (+2) jmp (+4) dec h inc b jmp (-5) print a print b print h """ eingabe = \ """ # a <= b a = 10 b = 13 h1 = 0 h2 = 0 tst a jmp (+4) tst b jmp (+9) jmp (+8) tst b jmp (+2) jmp (+6) dec a dec b inc h2 jmp (-11) inc h1 tst h2 jmp (+2) jmp (+5) dec h2 inc a inc b jmp (-6) print a print b print h1 print h2 """ import ply.lex as lex reserved = {'inc' : 'INC', 'dec' : 'DEC', 'jmp' : 'JMP', 'tst' : 'TST', 'print' : 'PRINT'} tokens = ['VAR','NUMBER'] + list(reserved.values()) literals = '=()' def t_KOMMENTAR(t): r'\#.*' def t_VAR(t): r'[a-zA-Z_][a-zA-Z_0-9]*' t.type = reserved.get(t.value,'VAR') # get gibt Wert aus Dictionary zurueck, return t # wenn nicht gefunden 'VAR' def t_NUMBER(t): r'[+\-]?\d+' t.value = int(t.value) return t def t_newline(t): r'\n+' t.lexer.lineno = t.lexer.lineno + len(t.value) t_ignore = ' \t' def t_error(t): print('Unerwartetes Zeichen:',t.value[0],',Zeile:',s.lineno) t.lexer.skip(1) s = lex.lex() import ply.yacc as yacc mem = [] # Programmspeicher dat = {} # Datenspeicher def p_0(p): 'bon : befehl bon' def p_1(p): 'bon :' def p_2(p): 'befehl : inc' def p_3(p): 'befehl : dec' def p_4(p): 'befehl : jmp' def p_5(p): 'befehl : tst' def p_6(p): 'befehl : zuw' def p_7(p): 'befehl : print' def p_8(p): 'inc : INC VAR' global mem mem = mem + [(p[1],p[2])] def p_9(p): 'dec : DEC VAR' global mem mem = mem + [(p[1],p[2])] def p_10(p): 'jmp : JMP NUMBER' global mem mem = mem + [('jmpabs',p[2])] def p_11(p): "jmp : JMP '(' NUMBER ')'" global mem mem = mem + [('jmprel',p[3])] def p_12(p): 'tst : TST VAR' global mem mem = mem + [(p[1],p[2])] def p_13(p): "zuw : VAR '=' NUMBER" global dat dat.update({p[1]:p[3]}) def p_14(p): 'print : PRINT VAR' global mem mem = mem + [(p[1],p[2])] def p_error(p): print('Syntaxfehler in Zeile:',s.lineno) p = yacc.yacc() p.parse(eingabe) mem = mem + [('hlt',None)] pc = 0 while True: (op,ad) = mem[pc] if op == 'inc': dat.update({ad:dat[ad]+1}) pc += 1 elif op == 'dec': dat.update({ad:dat[ad]-1}) pc += 1 elif op == 'jmpabs': pc = ad elif op == 'jmprel': pc = pc + ad elif op == 'tst': if dat[ad] == 0: pc += 2 else: pc += 1 elif op == 'print': print(dat[ad]) pc += 1 elif op == 'hlt': break else: raise Exception