Ejemplo n.º 1
0
 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 )