Wyrażenia regularne - automaty

0

Witam, czy jst ktoś kto pisał podobny projekt: obsługa wyrazeń regularnych w javie - to zaliczenie na automaty. mam kod źródłowy - swój, ale utknąłem. bardzo prosze o pomoc.

0

Ale na czym utknąłeś?

0

oparte jest to o działający automat z epsilon przejsciami.

test, ktorego nie przechodzi, bo sie zapetla, to

    @Test
    public void test_parens_regexp_1() throws Exception {
        check_with_java_regexps("(abc)","abcd");

Kod automatu, tj fragment do obslugi wyr. reg:

 //funkcje budujace automat //qs - start
  public void przetworz_wyrazenie(String wyrazenie)
  {
  Object qs = Automat.addState();
  Automat.markAsInitial(qs);   //ustaw jako stan poczatkowy
  Para para = przetworz_podwyrazenie('(' + wyrazenie + ')', 0, qs); //przypisz do pary
                                                                   // to z funkcji ponizej
  Automat.markAsFinal(para.stan_od);
  }

  public Para przetworz_podwyrazenie(String wyrazenie, int indeks, Object stan)
  {
  int index=indeks; //zaczynamy od 0
  ++index;          //i dodajemy od razu 1

  Object alt_q = Automat.addState();
  Automat.addEpsilonTransition(stan, alt_q);  // ze startowego z powyzszej funkcji do alt_q
  Object fq = Automat.addState();
  Object cq = Automat.addState();
  Automat.addEpsilonTransition(alt_q, cq);  //

  // alt_q(qs) -> cq -> fq

  while (( index < wyrazenie.length()) && (wyrazenie.charAt(index) != ')' )) {

   if (( wyrazenie.charAt(index)=='(') && (wyrazenie.charAt(index+1) == '(' )){
    Para para = przetworz_podwyrazenie(wyrazenie, index+1, cq);
    }
    else
   if ( wyrazenie.charAt(index) == '|' ){
    Automat.addEpsilonTransition(cq, fq);
    cq = Automat.addState();
    Automat.addEpsilonTransition(alt_q, cq);
    ++index;
    }else
   if ( wyrazenie.charAt(index+1) == '\\' ){
   Object nq = Automat.addState(); //do zrobienia
    Automat.addTransition(cq, nq, wyrazenie.charAt(index));
    Automat.addEpsilonTransition(cq, nq);
    cq = nq;
    index += 2;
    } else
   if ( wyrazenie.charAt(index+1) == '*' ){
    Object nq = Automat.addState();
    Automat.addEpsilonTransition(cq, nq);
    Automat.addTransition(nq, nq, wyrazenie.charAt(index));
    cq = nq;
    index += 2;
    }else
   if ( wyrazenie.charAt(index+1) == '+' ){
    Object nq = Automat.addState();
    Automat.addTransition(cq, nq, wyrazenie.charAt(index));
    Automat.addTransition(nq, nq, wyrazenie.charAt(index));
    cq = nq;
    index += 2;
    }else
   if ( wyrazenie.charAt(index+1) == '?' ){
    Object nq = Automat.addState(); 
    Automat.addTransition(cq, nq, wyrazenie.charAt(index));
    Automat.addEpsilonTransition(cq, nq);
    cq = nq;
    index += 2;
    }
    else{
    Object nq = Automat.addState();
    Automat.addTransition(cq, nq, wyrazenie.charAt(index));
    cq = nq;
    ++index;
    }
  }


  Automat.addEpsilonTransition(cq, fq);

  if (index+1 < wyrazenie.length()){

  if (wyrazenie.charAt(index+1) == '*'){
  Automat.addEpsilonTransition(alt_q, fq);
  Automat.addEpsilonTransition(fq, alt_q);
  Automat.addTransition(alt_q,fq, wyrazenie.charAt(index));
  ++index;
  }else
  if (wyrazenie.charAt(index+1) == '+'){
  Automat.addEpsilonTransition(fq, alt_q);
  ++index;
  }else
  if (wyrazenie.charAt(index+1) == '?'){
  Automat.addEpsilonTransition(alt_q, fq);
  ++index;
  }
  }

  return new Para(fq,index+1);
  }

}

test zapetla, robi przepełnienie stosu. jak zaimplementowac nawiasy?
lub jak spełnic wymagania testu:

 @Test
    public void test_parens_plus_regexp_2() throws Exception {
        check_with_java_regexps("(ab)+","aabbc");
    }

z przyjemnoscia wkleje wszystkie klasy, badz wrzuce zrarowany pakiet - wszystkie klasy w javie oraz testy. po prostu nie wiem co poprawic bądź dopisać by automat przechodził testy.

0

Sprawdź czy index jest prawidłowo inkrementowany. na początku metody wstaw wypis parametru index.

0

Kombinacje z indeksem bezsennie sięgają wczorajszego wieczora. problem w tym, ze automat zapetla się, a ja nie wiem mimo dopisywania println'ów gdzie i jak. zdaję sobie sprawe ze to problem z interpretacją nawiasów. zwiekszanie indexu działa jak powinno, przynajmniej w mojej teorii.

jeśli urodzi to jakąś szczególną wskazówkę - klasa para wygląda nastepująco:

 public class Para {
  public Para(Object state_from, int index)
  {
  stan_od = (Integer) state_from;
  indeks = index;
  }

  public Integer stan_od;
  public Integer indeks;

}
0

Jedna rada, do debugowania nie uważaj println, tylko debuggera, przynajmniej się wyśpisz.
Użyj typów prostych int a nie Integer.
Object jako typ parametru metody?

0
  while (( index < wyrazenie.length()) && (wyrazenie.charAt(index) != ')' )) {

   if (( wyrazenie.charAt(index)=='(') && (wyrazenie.charAt(index+1) == '(' )){
    Para para = przetworz_podwyrazenie(wyrazenie, index+1, cq);
    }
   (....)

}

Dlaczego nie zwiększasz zmiennej index? Przecież w każdym obrocie pętli robisz to samo.

0

@__krzysiek85, to nie to. Też na początku tak myślałem, ale tu siedzi rekurencja pogrzebana i nie ma potrzeby zwiększania index. Jest on przekazywany do metody większy o jeden.

0
GhostDog napisał(a)

Użyj typów prostych int a nie Integer.

W czym to pomoże podczas debugowania? Używam Evaluate Expression lub po prostu definiuje Watch-e czyli zmienne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1