import ply.lex as lex reserved = {'int' : 'INT', 'while' : 'WHILE'} tokens = ['ID','NUMBER','PUBLICZEILE', 'SYSTEMZEILE','GKAUF','GKZU', 'ISTGLEICH','STRICHPUNKT', 'GROESSER','MINUS','PLUS', 'RKAUF','RKZU'] + list(reserved.values()) def t_PUBLICZEILE(t): r'public[^{]*' print(t) return t def t_SYSTEMZEILE(t): r'System[^;]*;' print(t) # kein return, damit die Zeile vom Parser nicht gesehen wird def t_GKAUF(t): r'\{' print(t) return t def t_GKZU(t): r'\}' print(t) return t def t_ISTGLEICH(t): r'=' print(t) return(t) def t_STRICHPUNKT(t): r';' print(t) return(t) def t_GROESSER(t): r'\>' print(t) return(t) def t_MINUS(t): r'\-' print(t) return(t) def t_PLUS(t): r'\+' print(t) return(t) def t_RKAUF(t): r'\(' print(t) return t def t_RKZU(t): r'\)' print(t) return t def t_ID(t): r'[a-zA-Z_][a-zA-Z_0-9]*' t.type = reserved.get(t.value,'ID') print(t) return t def t_NUMBER(t): r'\d+' t.value = int(t.value) print(t) 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() vz = 0 # Variablenzaehler symtab = [] # Symboltabelle import ply.yacc as yacc def p_0(p): "start : PUBLICZEILE GKAUF PUBLICZEILE GKAUF kette GKZU GKZU" p[0] = p[5]+['hlt'] print('start :',p[1],p[2],p[3],p[4],p[5],p[6],p[7]) def p_1(p): 'kette : befehl kette' p[0] = p[1]+p[2] print('kette :',p[1],p[2]) def p_2(p): 'kette :' p[0] = [] print('kette :') def p_3(p): 'befehl : inc' p[0] = p[1] print('befehl :',p[1]) def p_4(p): 'befehl : dec' p[0] = p[1] print('befehl :',p[1]) def p_5(p): 'befehl : tst' p[0] = p[1] print('befehl :',p[1]) def p_6(p): 'befehl : zuw' p[0] = p[1] print('befehl :',p[1]) def p_7(p): 'zuw : INT ID ISTGLEICH NUMBER STRICHPUNKT' p[0] = [] global vz, symtab vz = vz + 1 symtab.append((vz,p[2],p[4])) print('zuw :',p[1],p[2],p[3],p[4],p[5]) def p_8(p): "inc : ID ISTGLEICH ID PLUS NUMBER STRICHPUNKT" p[0] = ['inc'+p[1]] if (p[1] != p[3]) or (p[5] != 1): print('Syntaxfehler in inc, Zeile:',s.lineno) raise SyntaxError print('inc :',p[1],p[2],p[3],p[4],p[5],p[6]) def p_9(p): "dec : ID ISTGLEICH ID MINUS NUMBER STRICHPUNKT" p[0] = ['dec'+p[1]] if (p[1] != p[3]) or (p[5] != 1): print('Syntaxfehler in dec, Zeile:',s.lineno) raise SyntaxError print('dec :',p[1],p[2],p[3],p[4],p[5],p[6]) def p_10(p): 'tst : WHILE RKAUF ID GROESSER NUMBER RKZU GKAUF kette GKZU STRICHPUNKT' lk = len(p[8]) p[0] = ['tst'+p[3],'jmp(2)','jmp('+str(lk+2)+')']+p[8]+['jmp('+str(-lk-3)+')'] print('tst : ',p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10]) def p_error(p): print('Syntaxfehler in Zeile:',s.lineno) pr = yacc.yacc() import sys try: dateiname = sys.argv[1] except: dateiname = 'add1.java' datei = open(dateiname,'r') inhalt = datei.read() datei.close() code0 = pr.parse(inhalt) # Symboltabelle einarbeiten, relative Spruenge ersetzen code = [] for i in range(len(code0)): bef = code0[i] if bef[0:3] == 'jmp': adr = str(1+i+int(bef[4:-1])) # bon-Zeilen ab 1 if len(adr) == 1: adr = ' '+adr code.append('jmp'+adr) elif bef[0:3] == 'hlt': code.append('hlt') else: adr = str([x[0] for x in symtab if x[1] == bef[3:]][0]) if len(adr) == 1: adr = ' '+adr code.append(bef[0:3]+adr) # Ausgabedatei erzeugen ausgabename = dateiname.split('.')[0]+'.bon' datei = open(ausgabename,'w') for bef in code: datei.write(bef+'\r\n') for i in range(1,vz+1): datei.write('# '+str([x[2] for x in symtab if x[0] == i][0])+'\r\n') for i in range(1,vz+1): (n,w) = [(x[1],x[2]) for x in symtab if x[0] == i][0] datei.write('; '+n+' = '+str(w)+'\r\n') datei.close() # Testausgabe datei = open(ausgabename,'r') # DEBUG inhalt = datei.read() # DEBUG datei.close() # DEBUG print(inhalt) # DEBUG