Probleme bei Java Syntaxchecker

OP #2601928
Lesenswert?

Hallo,
ich habe die Aufgabe einen Syntaxchecker in Java zu programmieren,
der einen vorgegebenen J.Unit test erfolgreich absolviert.

Die Methode public static void parse(String kd) throws ParseException
ist vorgegeben, die restlichen Methoden habe ich bereits programmiert.
Ich versuche also rekursiv den Syntaxbaum zu überprüfen, jedoch erfüllt 
es mir keinen J-Unit Test:

1
 package u3a3;
2

3
public class KD {
4
  
5
  private static int offset = 0;
6
  /**
7
   * Parse a "Klammerdarstellung" (KD) of a tree.
8
   * 
9
   * <ul>
10
   * <li>An empty tree is encoded as '-'.</li>
11
   * <li>A node is encoded as an uppercase letter, i.e. everything accepted by {@link Character#isUpperCase(char)}.</li>
12
   * <li>Children are appended to the father as a ','-separated list of nodes enclosed in round brackets.</li>
13
   * </ul> 
14
   * 
15
   * @param kd Tree encoded in KD
16
   * @throws ParseException if the given String is not a valid KD of a tree.
17
   */
18
  
19
  public static void parse(String kd) throws ParseException
20
  {
21
    if (kd.length() > 1 && kd.charAt(0) != '-' && kd.charAt(1) != '-')
22
    {
23
    tree(kd,0);
24
    }
25
  }
26
  
27
  public static int tree(String str, int offset)
28
  {
29
    offset = follower(str, offset);
30
    while (str.length() > offset && str.charAt(offset) == '+'){
31
    offset = follower(str, offset + 1);
32
    }
33
    return offset;
34
  }
35
  
36
  public static int follower(String str, int offset)
37
  {
38
    offset = node(str, offset);
39
    while (str.length() > offset && str.charAt(offset) == '*'){
40
    offset = node(str, offset + 1);
41
    }
42
    return offset;
43
  }
44
  
45
  public static int node(String str, int offset)
46
  {
47
    while (str.length() > offset && str.charAt(offset) == '(' || str.charAt(offset) == ')'){
48
      offset = node(str, offset + 1);
49
      }
50
    return offset;
51
  }
52
}

Hier noch der JUnit test:
1
 package u3a3;
2

3
import org.junit.Test;
4

5
public class Tests {
6
  void testCase(String lkd) throws ParseException {
7
    KD.parse(lkd);
8
  }
9
  
10
  @Test public void empyTree() throws ParseException { testCase("-"); }
11
  @Test public void onlyRoot() throws ParseException { testCase("A"); }
12
  @Test public void balancedTree() throws ParseException { testCase("A(B,C)"); }
13
  @Test public void listLeft() throws ParseException { testCase("A(B(C,-),-)"); }
14
  @Test public void listLeftImplicit() throws ParseException { testCase("A(B(C))"); }
15
  @Test public void listRight() throws ParseException { testCase("A(-,B(-,C))"); }
16
  @Test public void missingSibling() throws ParseException { testCase("A(B,-,C)");}
17
  @Test public void noChildren() throws ParseException { testCase("A(-,-)");}
18
  @Test public void genericTree() throws ParseException { testCase("A(-,B(C),-,D(E(-,F(G,H)),I))"); }
19
  
20
  @Test(expected = ParseException.class)
21
  public void empyString() throws ParseException { testCase(""); }
22

23
  @Test(expected = ParseException.class)
24
  public void noChild()throws ParseException { testCase("A()"); }
25

26
  @Test(expected = ParseException.class)
27
  public void noSibling()throws ParseException { testCase("A(B,)"); }
28
  
29
  @Test(expected = ParseException.class)
30
  public void twoCommas()throws ParseException { testCase("A(B,,C)"); }
31

32
  @Test(expected = ParseException.class)
33
  public void missingOpenBrace()throws ParseException { testCase("AB)"); }
34

35
  @Test(expected = ParseException.class)
36
  public void missingCloseBrace()throws ParseException { testCase("A(B"); }
37

38
  @Test(expected = ParseException.class)
39
  public void missingComma()throws ParseException { testCase("A(BC)"); }
40
  
41
  @Test(expected = ParseException.class)
42
  public void garbage()throws ParseException { testCase("A(B)C"); }
43

44
  @Test(expected = ParseException.class)
45
  public void garbage2()throws ParseException { testCase("A(B)(C)"); }
46
  
47
  @Test(expected = ParseException.class)
48
  public void noRoot()throws ParseException { testCase("-(A)"); }
49

50
  @Test(expected = ParseException.class)
51
  public void invalidNode()throws ParseException { testCase("A(1)"); }
52

53
  
54
}


Vielleicht sieht jemand was ich falsch mache.

mfg Hans
#2602099
Lesenswert?

@Läubi

ich glaub nicht, dass das stimmt, was du schreibst
throws heitß ja nur dass man eine Parseexception werfen KÖNNTE
und nicht dass man das MUSS

(wird man vermutlich nur tun, wenn man das scheitern eines tests 
kommunizieren will


>von einem Compiler

ich glaub nicht, dass er ein Problem beim compilieren hat ...


@TO

class Tests {

fehlt da ein "extends" ??
OP #2602164
Lesenswert?

Habe nun einmal die erste methode überarbeitet:
1
public static void parse(String kd) throws ParseException
2
  {
3
    
4
    boolean exception = false;
5
    for (int i = 0; i<kd.length(); i++)
6
    {
7
      if (kd.charAt(i) == '(' || kd.charAt(i) == ')' || kd.charAt(i) == ',' || kd.charAt(i) == '-' || kd.charAt(i) >= 'A' && kd.charAt(i) <= 'Z')
8
      {
9
        
10
      } else {
11
        exception = true;
12
        i = kd.length();
13
        
14
      }
15
    }
16
    
17
    if (exception == false)
18
    {
19
      tree (kd,0);
20
    }
21
  }

Jetzt sollte sie zumindest eine Ausnahme erkennen, wie bringe ich das 
nun in diese Junit Test mit ein?
Gast #2602207
Lesenswert?

Hi,

wieso sollte eine Exception erkannt werden, wenn du exception = true; 
setzt?
Vll. solltest du erst mal nachschlagen, was Exceptions sind und wozu sie 
verwendet werden.

Anstelle von exception = true wirfst du einfach eine Exception wenn 
einer deiner Tests fehlgeschlagen ist:
throw new ParseException();

Natürlich sollte die ParseException Informationen über die Fehlerquelle, 
Position etc. enthalten...
#2602215
Lesenswert?

Robert L. schrieb:
> @Läubi
>
> ich glaub nicht, dass das stimmt, was du schreibst
> throws heitß ja nur dass man eine Parseexception werfen KÖNNTE
> und nicht dass man das MUSS

Aber
>  @Test(expected = ParseException.class)

>
> ich glaub nicht, dass er ein Problem beim compilieren hat ...
>
>
> @TO
>
> class Tests {
>
> fehlt da ein "extends" ??

extends TestCase wurde mit JUnit 4 abgeschafft.

Du bist wohl noch bei JUnit 3?;-) Ich auch...


mfg Andreas
Persönliche Seite #2602233
Lesenswert?

Robert L. schrieb:
> ich glaub nicht, dass das stimmt

Glauben heißt nicht wissen, der JUnittest erwartet das die Exception 
geworfen wird siehe weiter unten.

Hans Lüthi schrieb:
> Ich begreiffe einfach diesen JUnit Test nicht, ich weiss
> gar nicht was ich überhaupt erfüllen soll?
Dann sprich mit deinem Betreuer!

Hans Lüthi schrieb:
> @Test(expected = ParseException.class)

Das sagt aus, dass der Test erwartet, dass die Methode eine Exception 
vom Typ ParseException wirft. (siehe z.B. 
http://radio.javaranch.com/lasse/2007/05/17/1179405760728.html)
OP #2602253
Lesenswert?

Also, ich verstehe schon, dass die Ausnahmen als Exceptions geworfen 
werden sollen, mit "throw new ParseException();" klappt das aber nicht, 
zeigt mir Eclipse als Fehler an. Mit exceptions = true meine ich nur, 
dass es sich um eine Ausnahme handelt, somit versuche ich zu verhindern, 
dass es in den Syntaxchecker läuft. Wie aber werfe ich in Junit4 eine 
exception?
Gruss Hans
#2602276
Lesenswert?

Also du scheinst wohl noch ganz am Anfang zu sein;-)

Bei Eclipse kannst du mit F2 die Dokumentation anzeigen lassen, und mit 
F3 in die Sourcen springen (sofern vorhanden).

ParseException ist nirgends importiert, daher wird es wohl eine Klasse 
in der gleichen Package sein.

Ich vermute mal diese Klasse hat einen Konstruktor der z.B. einen String 
als Parameter verlangt, warscheinlich einen Fehler.

(Alles geraten, wissen kannst das nur DU).

dann würde es heissen throw new ParserException("Mein Fehler");

Aja, ganz wichtig: Wenn du auf den Fehler klickst (also das rote Icon an 
der Linke Seite) sagt dir Eclipse oft einen Lösungsvorschlag.
Schau den dir mal an!

Meistens geht der in die richtige Richtung.


mfg Andreas
OP #2602298
Lesenswert?

So, habe das Programm mal so verändert:
1
package u3a3;
2

3
public class KD {
4
  
5
  private static int offset = 0;
6
  /**
7
   * Parse a "Klammerdarstellung" (KD) of a tree.
8
   * 
9
   * <ul>
10
   * <li>An empty tree is encoded as '-'.</li>
11
   * <li>A node is encoded as an uppercase letter, i.e. everything accepted by {@link Character#isUpperCase(char)}.</li>
12
   * <li>Children are appended to the father as a ','-separated list of nodes enclosed in round brackets.</li>
13
   * </ul> 
14
   * 
15
   * @param kd Tree encoded in KD
16
   * @throws ParseException if the given String is not a valid KD of a tree.
17
   */
18
  
19
  public static void parse(String kd) throws ParseException
20
  {
21
    
22
    boolean exception = false;
23
    for (int i = 0; i<kd.length(); i++) //This for-loop show, if in the tree string has illegal characters
24
    {
25
      if ((kd.charAt(i) == '(' || kd.charAt(i) == ')' || kd.charAt(i) == ',' || kd.charAt(i) == '-' || ((int) kd.charAt(i) >= 65) && ((int) kd.charAt(i) <= 90)))
26
      {
27
        
28
      } else {
29
        exception = true;
30
        i = kd.length();
31
        
32
      }
33
    }
34
    
35
    if (exception == false)
36
    {
37
      tree (kd,0);
38
    } else if (exception == true) // if the string has illegal characters
39
    {
40
      throw new ParseException("",0);
41
    }
42
  }
43
  
44
  public static int tree(String str, int offset)
45
  {
46
    offset = follower(str, offset);
47
    while (str.length() > offset && (((int) str.charAt(offset) >= 65) && ((int) str.charAt(offset) <= 90 ))){
48
    offset = follower(str, offset + 1);
49
    }
50
    return offset;
51
  }
52
  
53
  public static int follower(String str, int offset)
54
  {
55
    offset = node(str, offset);
56
    while (str.length() > offset && str.charAt(offset) == '('){
57
    offset = node(str, offset + 1);
58
    }
59
    return offset;
60
  }
61
  
62
  public static int node(String str, int offset)
63
  {
64
    while (str.length() > offset && (((int) str.charAt(offset) >= 65) && ((int) str.charAt(offset) <= 90 ))){
65
      offset = node(str, offset + 1);
66
      }
67
    return offset;
68
  }
69
}

10 Tests werden noch nicht erfüllt. Das offset soll zeigen, ob die 
Klammerdarstellung auch wirklich richtig ist.
Vielleicht sieht jemand noch einen Fehler.
Persönliche Seite #2602306
Lesenswert?

Was sollen die ganze integer da? Und die Exeption kann man sofort werfen 
wenn etwas schief lief, außerdem solltest du dich mal einigen wo du die 
Klammer setzen willst oder einfach mit STRG+F mal den Source formatieren 
lassen.

Außerdem wäre es ganz gut wenn du mal versuchst zu verstehen was da 
abläuft anstelle aus allen möglichen Quellen was zusammenzukopieren.
OP #2602316
Lesenswert?

Naja, das was da steht habe auch ich so gedacht und nicht einfach so 
zusammenkopiert. Ich konvertiere die Chars in einen Integer um damit zu 
sehen, ob es ein erlaubter Grossbuchstabe ist (Wert zwischen 64 und 91). 
Die Bäume die ich überprüfe sind aus Grossbuchstaben, Kommas, Klammern 
und "-" für keinen Baum.
#2602330
Lesenswert?

Läubi .. schrieb:
> Klammer setzen willst oder einfach mit STRG+F mal den Source formatieren
> lassen.

STRG+SHIF+F, er will nicht suchen;-)

Hans Lüthi schrieb:
> Naja, das was da steht habe auch ich so gedacht und nicht einfach so
> zusammenkopiert. Ich konvertiere die Chars in einen Integer um damit zu
> sehen, ob es ein erlaubter Grossbuchstabe ist (Wert zwischen 64 und 91).

Character.isLetter(ch)
Character.isUpperCase(ch)

Es gibt noch einige mehr, schaue die dir mal an.

Im übrigen ist es leserlicher (und ggf. sogar etwas schneller) wenn du 
statt
>      if ((kd.charAt(i) == '(' || kd.charAt(i) == ')' || kd.charAt(i) ==
> ',' || kd.charAt(i) == '-' || ((int) kd.charAt(i) >= 65) && ((int)
> kd.charAt(i) <= 90)))

etwas schreibst wie

> char c = kd.charAt(i);
>      if ((c == '(' || c == ')' || c == ',' || c == '-' || ((int) c >=
> 65) && ((int) c <= 90)))


mfg Andreas
OP #2602482
Lesenswert?

So, habe alles probiert, das ist dabei rausgekommen, funktioniert leider 
nicht ganz, vielleicht sieht jemand noch einen Fehler:
1
package u3a3;
2

3
public class KD {
4

5
  private static int offset = 0;
6

7
  /**
8
   * Parse a "Klammerdarstellung" (KD) of a tree.
9
   * 
10
   * <ul>
11
   * <li>An empty tree is encoded as '-'.</li>
12
   * <li>A node is encoded as an uppercase letter, i.e. everything accepted by
13
   * {@link Character#isUpperCase(char)}.</li>
14
   * <li>Children are appended to the father as a ','-separated list of nodes
15
   * enclosed in round brackets.</li>
16
   * </ul>
17
   * 
18
   * @param kd
19
   *            Tree encoded in KD
20
   * @throws ParseException
21
   *             if the given String is not a valid KD of a tree.
22
   */
23

24
  public static void parse(String kd) throws ParseException {
25

26
    boolean exception = false;
27

28
    for (int i = 0; i < kd.length(); i++) // This for-loop show, if in the
29
                        // tree string has illegal
30
                        // characters
31
    {
32
      offset = i;
33
      if ((kd.charAt(i) == '(' || kd.charAt(i) == ')'
34
          || kd.charAt(i) == ',' || kd.charAt(i) == '-' || Character
35
            .isUpperCase(kd.charAt(i)))) {
36

37
      } else {
38
        exception = true;
39
        i = kd.length();
40

41
      }
42
    }
43

44
    if (exception == false && kd.length() > 0) {
45
      offset = 0;
46
      tree(kd, offset);
47
      if (offset != kd.length()) 
48
      {
49
        throw new ParseException(kd, offset);
50
      }
51
    } else if (exception == true || kd.length() == 0) {
52
      throw new ParseException(kd, offset);
53
    }
54
  }
55

56
  public static int tree(String str, int offset) {
57
    offset = node(str, offset);
58
    if (str.length() > offset && (str.charAt(offset) == '(' )) {
59
      offset = undertree(str, offset + 1);
60
    } else if (str.charAt(offset) == ')')
61
    {
62
      offset = offset + 1;
63
    }
64
    return offset;
65
  }
66

67
  public static int node(String str, int offset) {
68

69
    if (str.length() > offset && (Character.isUpperCase(str.charAt(offset)) || str.charAt(offset) == '-')) {
70
      return (offset + 1);
71
    } else {
72
      return 0;
73
    }
74
  }
75

76
  public static int undertree(String str, int offset) {
77
    offset = tree(str,offset + 1);
78
    while (str.length() > offset && str.charAt(offset) == ',') {
79
      offset = node(str, offset + 1);
80
    }
81
    return offset;
82
  }
83

84
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren