import ply.lex as lex reserved = {'label' : 'LABEL', 'if' : 'IF', 'goto' : 'GOTO', 'else' : 'ELSE' } tokens = ['ID','LID','NUMBER','FROMZEILE', 'PRINTZEILE','KOMMENTAR', 'ISTGLEICH','DOPPELPUNKT', 'GROESSER','MINUS','PLUS'] + list(reserved.values()) def t_ISTGLEICH(t): r'=' print(t) return(t) def t_DOPPELPUNKT(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_LID(t): r'\.[a-zA-Z_][a-zA-Z_0-9]*' print(t) return(t) def t_FROMZEILE(t): r'from.*' print(t) def t_PRINTZEILE(t): r'print.*' print(t) def t_KOMMENTAR(t): r'\#.*' print(t) def t_ID(t): r'[a-zA-Z_][a-zA-Z_0-9]*' t.type = reserved.get(t.value,'ID') # get gibt Wert aus Dictionary zurück, print(t) return t # wenn nicht gefunden 'ID' def t_NUMBER(t): r'\d+' print(t) 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 n = 1 # Zeilennummer der Ausgabe nv = 1 # Variablennummer sym = {} # Symboltabelle, Dictionary var = [] # Liste der Anfangs-Variablen mit Werten lab = [] # Liste der Labels lauf1 = '' # String für 1.Lauf def p_0(p): 'bon : befehl bon' print('bon : befehl bon') def p_1(p): 'bon :' print('bon :') def p_2(p): 'befehl : inc' print('befehl : inc') def p_3(p): 'befehl : dec' print('befehl : dec') def p_4(p): 'befehl : jmp' print('befehl : jmp') def p_5(p): 'befehl : tst' print('befehl : tst') def p_6(p): 'befehl : zuw' print('befehl : zuw') def p_7(p): 'befehl : lab' print('befehl : lab') def p_8(p): "inc : ID ISTGLEICH ID PLUS NUMBER" print('inc :',p[1],p[2],p[3],p[4],p[5]) if (p[1] != p[3]) or (p[5] != 1): print('Syntaxfehler in inc, Zeile:',s.lineno) raise SyntaxError global lauf1,n lauf1 = lauf1+'inc '+p[1]+'\n' print('lauf1:\n'+lauf1) n = n+1 def p_9(p): "dec : ID ISTGLEICH ID MINUS NUMBER" print('dec :',p[1],p[2],p[3],p[4],p[5]) if (p[1] != p[3]) or (p[5] != 1): print('Syntaxfehler in dec, Zeile:',s.lineno) raise SyntaxError global lauf1,n lauf1 = lauf1+'dec '+p[1]+'\n' print('lauf1:\n'+lauf1) n = n+1 def p_10(p): "jmp : GOTO LID" print('jmp :',p[1],p[2]) global lauf1,n lauf1 = lauf1+'jmp '+p[2]+'\n' print('lauf1:\n'+lauf1) n = n+1 def p_11(p): "tst : IF ID GROESSER NUMBER DOPPELPUNKT GOTO LID ELSE DOPPELPUNKT GOTO LID" print('tst :',p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11]) if (p[4] != 0): print('Syntaxfehler in tst, Zeile:',s.lineno) raise SyntaxError global lauf1,n lauf1 = lauf1+'tst '+p[2]+'\n' lauf1 = lauf1+'jmp '+p[7]+'\n' lauf1 = lauf1+'jmp '+p[11]+'\n' print('lauf1:\n'+lauf1) n = n+3 def p_12(p): "zuw : ID ISTGLEICH NUMBER" global var,sym,nv print('zuw:',p[1],p[2],p[3]) sym.update({p[1]:nv}) print('Symboltabelle:',sym) var.append((p[1],p[3])) print('Variablentabelle:',var) nv = nv + 1 def p_13(p): 'lab : LABEL LID' global lab,sym print('lab:',p[1],p[2]) lab.append((p[2],n)) print('Labeltabelle:',lab) sym.update({p[2]:n}) print('Symboltabelle:',sym) def p_error(p): print('Syntaxfehler in Zeile:',s.lineno) pr = yacc.yacc() import sys try: dateiname = sys.argv[1] except: dateiname = 'add0.py' datei = open(dateiname,'r') inhalt = datei.read() datei.close() pr.parse(inhalt) # Symboltabelle einarbeiten und Ausgabedatei erzeugen zeilen = lauf1.split('\n') zeilen.remove('') ausgabename = dateiname.split('.')[0]+'.bon' datei = open(ausgabename,'w') for z in zeilen: zalt = z.split(' ') zneu = zalt[0]+str(sym.get(zalt[1]))+'\r\n' datei.write(zneu) datei.write('hlt\r\n') for v in var: zneu = '# '+str(v[1])+'\r\n' datei.write(zneu) for v in var: zneu = '; '+str(v[0])+' = '+str(v[1])+'\r\n' datei.write(zneu) datei.close() datei = open(ausgabename,'r') # DEBUG inhalt = datei.read() # DEBUG datei.close() # DEBUG print('\nerzeugte Datei:\n\n'+inhalt) # DEBUG