def kreiraj_dka( self ): '''stvaranje dka direktno iz enkas''' # treba vratiti frozenset indexa stanja/stavki #dka_pocetno = self._epsilon_okruzenje( self._pocetno_stanje_index ) dka_pocetno = self._epsilon_okruzenje_rekurzivno( self._pocetno_stanje_index, None ) stanja_dka = [ dka_pocetno ] postoji_neprihvatljivo = False neobradjena = Stog( 0 ) prijelazi_dka = Prijelazi() # dict( int_stanje: dict( znak: int_stanje ) ) #i = 0 while not neobradjena.jest_prazan(): # test ispisi #print( i ) #i += 1 #for eo in self._eokruzenja: #print( eo ) #print() index_stanja_za_obradu = neobradjena.dohvati_vrh() neobradjena.skini() stanje_za_obradu = stanja_dka[ index_stanja_za_obradu ] for z in (self.abeceda | set(['<<!>>'])): novo_stanje = set() # postaje set intova (indexa stavki) for index_stavke in stanje_za_obradu: novo_stanje.update( self.prijelaz_za_niz( index_stavke, [z] ) ) #print( 'novo_stanje:', novo_stanje ) #print() novo_stanje = frozenset( novo_stanje ) if novo_stanje: try: index_novog = stanja_dka.index( novo_stanje ) except ValueError: index_novog = len( stanja_dka ) neobradjena.stavi( index_novog ) stanja_dka.append( novo_stanje ) prijelazi_dka.dodaj( index_stanja_za_obradu, z, index_novog ) else: prijelazi_dka.dodaj( index_stanja_za_obradu, z, -1 ) #print( 'stvaram dka') return DKA( self.stanja, stanja_dka, self.abeceda, prijelazi_dka )
def _kreiraj_enka( self ): '''iz gramatike stvara enka ovdje ide algoritam sa strane 148 ''' abeceda = self.gramatika.nezavrsni_znakovi.union( self.gramatika.zavrsni_znakovi ) pocetno_stanje = LR1Stavka( self.gramatika.pocetni_nezavrsni, [], self.gramatika.produkcije[-1].desna_strana, frozenset([ '<<!>>' ]) ) skup_stanja = set([ pocetno_stanje ]) # treba zbog brzine pronalaska stanja u ovom algoritmu niz_stanja = [ pocetno_stanje ] # ovo ce se predavati prijelazi = Prijelazi( type( set() ) ) # dict( stanje: dict( znak: set( index-stavke ) ) ) neobradjena_stanja = { 0 } # index u niz stanja while( len( neobradjena_stanja ) > 0 ): trenutno_stanje_index = neobradjena_stanja.pop() trenutno_stanje = niz_stanja[ trenutno_stanje_index ] # tip: LR1Stavka # potpuna stavka if trenutno_stanje.desno_poslije_tocke == "": continue # slucaj iz knjige: 4 b) if trenutno_stanje.je_li_potpuna(): continue znak_poslije_tocke = trenutno_stanje.desno_poslije_tocke[0] nastavak_beta = [] if len( trenutno_stanje.desno_poslije_tocke ) > 1: nastavak_beta = trenutno_stanje.desno_poslije_tocke[1:] novo_stanje = LR1Stavka( trenutno_stanje.lijeva_strana, trenutno_stanje.desno_prije_tocke + [znak_poslije_tocke ], nastavak_beta, trenutno_stanje.skup_zapocinje ) index_novog = -1 if novo_stanje not in skup_stanja: skup_stanja.add( novo_stanje ) index_novog = len( niz_stanja ) niz_stanja.append( novo_stanje ) neobradjena_stanja.add( index_novog ) else: index_novog = niz_stanja.index( novo_stanje ) prijelazi.dodaj( trenutno_stanje_index, znak_poslije_tocke, index_novog ) # slucaj iz knjige: 4 c) if znak_poslije_tocke in self.gramatika.nezavrsni_znakovi: # stvori stavku za svaku produkciju iz nezavrsnog znaka q.poslije[0] nova_stanja = set([]) for produkcija in self.gramatika.produkcije: if znak_poslije_tocke == produkcija.lijeva_strana: # T iz knjige, za nastavak LR1Stavke skup_T = self.gramatika.odredi_zapocinje_za_niz( nastavak_beta ) if self.gramatika.je_li_niz_prazan( nastavak_beta ): skup_T |= ( trenutno_stanje.skup_zapocinje ) desni_dio = [] if produkcija.desna_strana[0] != '$': desni_dio = produkcija.desna_strana nova_stanja.add( LR1Stavka( znak_poslije_tocke, [], desni_dio, skup_T) ) # stavi te sve stavke u prijelaze i stanja (ako nisu u stanjima) for novo_stanje in nova_stanja: index_novog = -1 if novo_stanje not in skup_stanja: skup_stanja.add( novo_stanje ) index_novog = len( niz_stanja ) niz_stanja.append( novo_stanje ) neobradjena_stanja.add( index_novog ) else: index_novog = niz_stanja.index( novo_stanje ) prijelazi.dodaj( trenutno_stanje_index, '$', index_novog ) return ENKA( niz_stanja, abeceda, prijelazi )