FileReader Zeilenangabe

misaki

Mitglied
Hallo! :)

Wir sollen dieses Mal als Hausaufgabe einen "kleinen Compiler" schreiben - und zwar soll mithilfe eines Stacks überprüft werden ,ob die Klammersetzung nach java korrekt ist.
Die Strings , chars und Kommentare sollen dabei ignoriert werden.

Bei der Fehlerausgabe soll die Zeilennummer mit angegeben werden - mir ist aber keine Methode des FileReader bekannt ,bei der man die bekommt?

Java:
import java.util.*;
import java.io.*;

public class JavaChecker {

	private static int lineNr = 0;

	public static String checkBrackets(String filename) throws FileNotFoundException, IOException {
		java.io.FileReader myReader = new java.io.FileReader(filename); // erzeuge Reader für gewählte Datei
		java.util.Stack<Integer> stack = new java.util.Stack<Integer>(); // erzeuge einen Stack für Klammerung
		
		int found = myReader.read();
        while(found > -1){             //"-1" signalisert Datei-Ende
            if (found == '"') { // Anfang eines Strings, also ignorieren
				found = myReader.read();
				while (found != '"' && found > -1) { // solange nicht ende des Strings kommt
					found = myReader.read(); // lese einfach weiter und mache nichts
				}
			}
			if (found == '\'') { // char Zeichen
				// Wenn ein char-Zeichen auftritt, sollen einfach die nächsten beiden Zeichen überlesen werden, denn das ist der
				// character Wert der ignoriert werden soll und das ' das Ende char signalisiert
				found = myReader.read();
				found = myReader.read(); 
			}
			if (found == '/') {
				found = myReader.read();
				if (found == '/') { // zwei // signalisieren Kommentar
					/** lese bis zum Zeilenende, ignoriere alles **/
				}
				if (found == '*') { // Kommentar über mehrere Zeilen signalisiert durch /*
					found = myReader.read();
					while (found != '*') { // */ signalisiert ende, deshalb bis zum Stern lesen und dann schauen ob / kommt
						found = myReader.read();
						if (found == '/') {
							break; // Kommentarende, weiter im Suchen
						}
					}
				}
			}
			else if (found == '{') {
				stack.push(found);
			}
			else if (found == '(') {
				stack.push(found);
			}
			else if (found == ')') {
				if (stack.peek() == '(') {
					stack.pop();
				}
				else if (stack.peek() == '{') {
					return (") without (; line Nr " + lineNr);
				}
				else {
					return ("eine schliessende Klammer zu viel");
				}
			}
			else if (found == '}') {
				if (stack.peek() == '{') {
					stack.pop();
				}
				else if (stack.peek() == '(') {
					return ("} without {; line Nr " + lineNr);
				}
				else {
					return ("eine schliessende Klammer zu viel");
				}
			}
            found = myReader.read();
        }
		
		// Am Ende noch überprüfen ob der Keller auch wirklich leer, nur dann Kammersetzung korrekt
		if (stack.peek() == null) {
			return ("ok");
		}
		else {
			return ("stack not empty on end of file");
		}
		
	}

	/* Die beiden angegebenen Exceptions können beim Gebrauch des FileReaders ausgelöst werden und sollen nicht in der checkBrackets-Methode aufgefangen und behandelt 
	sondern weitergereicht werden.

	Dabei ist der Text in Kommentaren (beide Formen!) und in String-Werten, der ja beliebig sein kann, zu überspringen; ebenso dürfen Klammern, die als char-Werte 
	auftreten, nicht mitgerechnet werden! Die Methode soll die folgenden Fehlersituationen erkennen und sofort mit der entsprechenden Meldung returnieren:  */
}
 

Volvagia

Top Contributor
Java:
...
private int currentLineNumber++;
...

private char readChar(FileReader reader)
{
	int character = reader.read();
	if(character == 10) // Könnte auch 13 sein, ich bin mir jetzt nicht absolut sicher.
		currentLineNumber++;
	return(character);
}
private int getCurrentLineNumber()
{
	return(currentLineNumber);
}

Das throwen von der FileNotFoundException kannst du dir spaaren, weil die von IOException erbt.
 
Zuletzt bearbeitet:

misaki

Mitglied
wir sollen die aber extra werfen :) (hab ich noch nicht, ich weiß, das muss ich noch irgendwo einbauen)

das mit dem == 10 versteh ich nicht. Bedeutet das, das es hier einen Zeilenumbruch gibt? und was bringt mir das wenn ich dann nur den letzten character zurückgebe, ich muss ja alle von der zeile lesen?

edit:

Ah ich verstehs schon. Ich soll dann praktisch immer über diese innere Methode die einzelnen Character lesen. Ist die Methode wirklich notwendig? Bei der Angabe steht nämlich:

Schreiben Sie eine public class JavaChecker zur Prüfung von Java-Programmen auf korrekte Klammerung. Die Klasse soll eine einzige statische Methode anbieten, nämlich
public static String checkBrackets(String filename) throws FileNotFoundException, IOException
 

Volvagia

Top Contributor
Ja. Eins der Haupt-OSe nutzt so weit ich weiß 13/10, und eine nur 10, oder umgekehrt. Musst du einfach ausprobieren. Du ließt ja sowieso immer nur 1 Zeichen im Code.

Ich halte es für sinnvoll. Wenn das die Aufgabenstellung ist, kannst du aber das ganze natürlich in der statischen Methode prüfen.

Edit: Nach nochmaligen durchdenken finde ich es garnicht mehr so sinnvoll.

Java:
int currentLineNumber = 0;
int found = myReader.read();
	while(found > -1){             //"-1" signalisert Datei-Ende
...
else if (found == '}') {
	if (stack.peek() == '{') {
        	stack.pop();
	}
        else if (stack.peek() == '(') {
        	return ("} without {; line Nr " + lineNr);
	}
        else {
        	return ("eine schliessende Klammer zu viel");
	}
}
else if(found == 10) {
	currentLineNumber++;
}
 
Zuletzt bearbeitet:

misaki

Mitglied
Ok alles klar, danke, dann werd ich mich noch etwas herumspielen :)

Kann mir übrigens jemand kurz Rückmeldung geben ob das mit String / Kommentare und char-Werte ignorieren so funktioniert, wie ich das geplant habe:

ich prüfe ob ein " vorkommt, wenn ja, lese ich so lange weiter bis das nächste " kommt (Strings ignorieren)
ich prüfe ob ein ' kommt und ignoriere die nächsten zwei Zeichen (char wert)
ich prüfe ob ein / kommt und unterscheide dann jeweils ein erneutes / bzw ein * und lese bis zum Zeilende beziehungsweise bis */ kommt und ignoriere diese Zeichen?
 

Volvagia

Top Contributor
Klingt richtig.

Vielleicht ist eine do für die Aufgabe besser.

Java:
int fount = 0;
do
{
	found = myReader.read();
	if(found...
	....
}
while(found != -1);

Und du importierst die Package, in denen FileReader und Stack liegen, gibst aber den kompletten Pfad zur Klasse an. Warum das?
 

misaki

Mitglied
keine ahnung, ich dachte das muss man machen :D Habs aber geändert.

Naja ich werd mich dann mal bisschen spielen und bei Fehlern, die ich nicht finde, melde ich mich wieder ;) Danke schonmal!
 

Volvagia

Top Contributor
Nein. Importieren ist dazu da, dass er bei gleichnamigen Klassen/Interface etc. (im nachfolgenden nur noch als "Klassen" bezeichnet) bescheid weis, welche zu nutzen ist. Beispielweiße liegt in java.awt List, als grafische Auswahlbox, in java.util List als Interface, welches von Listcollections verwendet wird.

Dabei nimmt er als erste "Priorität" eine Klasse, welche im selben Package wie die Klasse liegt. Als 2. nimmt er Klassen aus java.lang.Package, die du auch nicht importieren musst. (String z. B.)
Danach musst du importieren, z. B. import java.io.FileReader. Danach kannst du FileReader als "FileReader" verwenden, und er wird immer dem aus java.io verwenden. Nur falls du noch auf eine 2. Klasse namens FileReader zugreifen musst, musst du das Package mit angeben. Wenn du immer Package angibst, musst du garnichts importieren, da nie Zweifel daran besteht, welche Klasse wirklich gemeint ist. Allerdings wird imho der Code sehr viel unlesbarer, und wirklich davon haben tut man nicht.

Hoffe, das war verständlich.
 

misaki

Mitglied
ookay. ich habe meine programm jetzt fertig - aber irgendetwas scheint etwas nicht zu funktionieren. denn wenn ich online überprüfe bekomme ich ein timeout, weils angeblich zu lange dauert?

übrigens weiß ich noch nicht wo und wie ich die exceptions werfen soll

Java:
import java.util.*;
import java.io.*;

public class JavaChecker {

	private static int lineNr = 0; // Variable für Zeilenangabe

	public static String checkBrackets(String filename) throws FileNotFoundException, IOException {
		
		FileReader myReader = new FileReader(filename); // erzeuge Reader für gewählte Datei
		Stack<Integer> stack = new Stack<Integer>(); // erzeuge einen Stack für Klammerung
		
		int found = 0;
		String check = "fehler"; // gebe fehler aus, wenn irgendwo was falsch gemacht wurde
		do {
			found = myReader.read();
            if (found == '"') { // Anfang eines Strings, also ignorieren
				found = myReader.read();
				while (found != '"' && found > -1) { // solange nicht Ende des Strings oder der Datei kommt kommt
					found = myReader.read(); // lese einfach weiter und mache nichts
				}
			}
			else if (found == '\'') { // char Zeichen, also ignorieren
				found = myReader.read();
				while (found != '\'' && found > -1) { // solange nicht Ende des Char-Wertes oder der Datei kommt kommt
					found = myReader.read(); // lese einfach weiter und mache nichtsfound = myReader.read();
				}
			}
			else if (found == '/') {
				found = myReader.read(); // lese nächstes Zeichen
				if (found == '/') { // zwei // signalisieren Kommentar
					found = myReader.read();
					while (found != 13) { // 13 signalisiert Zeilenende, lese solange
						found = myReader.read(); // lese bis das Zeilenende erreicht wurde
					}
					lineNr++; // hier wird ein Zeilenende erreicht ohne dass es anders wahrgenommen wird, Anzahl erhöhen
				}
				if (found == '*') { // Kommentar über mehrere Zeilen signalisiert durch /*
					found = myReader.read();
					while (found != '*') { // */ signalisiert ende, deshalb bis zum Stern lesen und dann schauen ob / kommt
						found = myReader.read();
					}
					found = myReader.read(); // nach Stern muss / kommen		
				}
			}
			else if (found == 13) { // bei Zeilenumbruch wird 13 returned
				lineNr++;
			}
			// wird eine öffnende Klammer gefunden - in Stack gebunden
			else if (found == '{') {
				stack.push(found);
			}
			else if (found == '(') {
				stack.push(found);
			}
			// wird eine schließende Klammer gefunden - schau ob passende zuoberst in Stack, wenn ja, pop, sonst Fehler!
			else if (found == ')') {
				if (!stack.empty() && stack.peek() == '(') {
					stack.pop();
				}
				else {
					check = ") without (; line Nr " + lineNr;
				}
			}
			else if (found == '}') {
				if (!stack.empty() && stack.peek() == '{') {
					stack.pop();
				}
				else {
					check = "} without {; line Nr " + lineNr;
				}
			}	
		}
		while (found != -1); // signalisiert File-Ende
		
		// Am Ende noch überprüfen ob der Keller auch wirklich leer, nur dann Klammersetzung korrekt
		if (stack.empty()) {
			check = "ok";
		}
		else {
			check = "stack not empty on end of file";
		}
		
		return check;
	}
}

Java:
public class Bsp05 {
	public static void main(String[] args) {
		try {
			System.out.println("Ueberpruefe Klammersetzung von " + args[0]);
			System.out.println(JavaChecker.checkBrackets(args[0]));
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

???:L???:L???:L???:L???:L
 
Zuletzt bearbeitet:

misaki

Mitglied
ich habe einfach mal die javachecker überprüft. kann die ja auch als zweite datei abspeichern und dabei klammern verändern und so weiter?
 

Volvagia

Top Contributor
Ach so. Wenn ich sie einfach so checke, bekomme ich ein ok. Wie meintest du das mit online? Das Parsen einer Datei, die heruntergeladen wird?
Ums Exception werfen brauchst du dich nicht zu kümmern. Der Stream könnte eine werfen, und durchs throws fliegt sie gleich weiter zum Aufrufer (in dem Fall main), wie es vom Auftraggeber gewünscht war. :)
 

misaki

Mitglied
"Die beiden angegebenen Exceptions können beim Gebrauch des FileReaders ausgelöst werden und sollen nicht in der checkBrackets-Methode aufgefangen und behandelt sondern weitergereicht werden. " --> das heißt ich muss nichts machen?

ja, das ok bekomme ich auch. aber wenn ich das ganze online bei unserem tollen automatischen überprüfer teste (wovon ich die testdatei nicht habe) bekomme ich ein timeout.
 

Volvagia

Top Contributor
Genau, machst du per throws ja schon.
Heißt dass, das ist ein Programm, welches prüft, ob es zum selben Ergebniss wie euer Programm kommt? Dann liegt der Fehler aber nicht bei dir.
 

misaki

Mitglied
weil in der angabe steht wir sollen den file-reader verwenden und ich dachte, dann brauch ich eh nichts anderes mehr ;) aber es geht eh so auch schon.

ja das ist ein programm online, das prüft, ob das richtige ergebnis (also wahrscheinlich das selbe) rauskommt.

ich habe aber gerade festgestellt dass wenn ich folgendes teste
Java:
// Als Testdatei für Klammersetzung!!!!

import java.util.*;
import java.io.*;

public class JavaChecker {

	private static int lineNr = 0; // Variable für Zeilenangabe

	public static String checkBrackets(String filename) throws FileNotFoundException, IOException {
		
		FileReader myReader = new FileReader(filename); // erzeuge Reader für gewählte Datei
		Stack<Integer> stack = new Stack<Integer>(); // erzeuge einen Stack für Klammerung
		
		int found = 0;
		String check = "fehler"; // gebe fehler aus, wenn irgendwo was falsch gemacht wurde
		do {
			found = myReader.read();
            if (found == '"') { // Anfang eines Strings, also ignorieren
				found = myReader.read();
				while (found != '"' && found > -1) { // solange nicht Ende des Strings oder der Datei kommt kommt
					found = myReader.read(); // lese einfach weiter und mache nichts
				}
			}
			else if (found == '\'') { // char Zeichen, also ignorieren
				found = myReader.read();
				while (found != '\'' && found > -1) { // solange nicht Ende des Char-Wertes oder der Datei kommt kommt
					found = myReader.read(); // lese einfach weiter und mache nichtsfound = myReader.read();
				}
			}
			else if (found == '/') {
				found = myReader.read(); // lese nächstes Zeichen
				if (found == '/') { // zwei // signalisieren Kommentar
					found = myReader.read();
					while (found != 13) { // 13 signalisiert Zeilenende, lese solange
						found = myReader.read(); // lese bis das Zeilenende erreicht wurde
					}
					lineNr++; // hier wird ein Zeilenende erreicht ohne dass es anders wahrgenommen wird, Anzahl erhöhen
				}
				if (found == '*') { // Kommentar über mehrere Zeilen signalisiert durch /*
					found = myReader.read();
					while (found != '*') { // */ signalisiert ende, deshalb bis zum Stern lesen und dann schauen ob / kommt
						found = myReader.read();
					}
					found = myReader.read(); // nach Stern muss / kommen		
				}
			}
			else if (found == 13) { // bei Zeilenumbruch wird 13 returned
				lineNr++;
			}
			// wird eine öffnende Klammer gefunden - in Stack gebunden
			else if (found == '{') {
				stack.push(found);
			}
			else if (found == '(') {
				stack.push(found);
			}
			// wird eine schließende Klammer gefunden - schau ob passende zuoberst in Stack, wenn ja, pop, sonst Fehler!
			else if (found == ')') {
				if (!stack.empty() && stack.peek() == '(') {
					stack.pop();
				}
				else {
					check = ") without (; line Nr " + lineNr;
				}
			}
			else if (found == '}') {
				if (!stack.empty() && stack.peek() == '{') {
					stack.pop();
				}
				else 
					check = "} without {; line Nr " + lineNr;
				}
			}	
		}
		while (found != -1); // signalisiert File-Ende
		
		// Am Ende noch überprüfen ob der Keller auch wirklich leer, nur dann Klammersetzung korrekt
		if (stack.empty()) {
			check = "ok";
		}
		else {
			check = "stack not empty on end of file";
		}
		
		return check;
	}
}

wo ich vor beendigung der while schleife bei einem else das {entfernt habe, auch das "ok" bekomme. Wieso das jetzt??
 

Volvagia

Top Contributor
Java:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;
 
public class JavaChecker
{
    private static int lineNr = 0; // Variable für Zeilenangabe

     public static String checkBrackets(String filename) throws FileNotFoundException, IOException {
        
        FileReader myReader = new FileReader(filename); // erzeuge Reader für gewählte Datei
        Stack<Integer> stack = new Stack<Integer>(); // erzeuge einen Stack für Klammerung
        
        int found = 0;

        do{
            found = myReader.read();
            if (found == '"') { // Anfang eines Strings, also ignorieren
                found = myReader.read();
                while (found != '"' && found > -1) { // solange nicht Ende des Strings oder der Datei kommt kommt
                    found = myReader.read(); // lese einfach weiter und mache nichts
                }
            }
            else if (found == '\'') { // char Zeichen, also ignorieren
                found = myReader.read();
                while (found != '\'' && found > -1) { // solange nicht Ende des Char-Wertes oder der Datei kommt kommt
                    found = myReader.read(); // lese einfach weiter und mache nichtsfound = myReader.read();
                }
            }
            else if (found == '/') {
                found = myReader.read(); // lese nächstes Zeichen
                if (found == '/') { // zwei // signalisieren Kommentar
                    found = myReader.read();
                    while (found != 13) { // 13 signalisiert Zeilenende, lese solange
                        found = myReader.read(); // lese bis das Zeilenende erreicht wurde
                    }
                    lineNr++; // hier wird ein Zeilenende erreicht ohne dass es anders wahrgenommen wird, Anzahl erhöhen
                }
                if (found == '*') { // Kommentar über mehrere Zeilen signalisiert durch /*
                    found = myReader.read();
                    while (found != '*') { // */ signalisiert ende, deshalb bis zum Stern lesen und dann schauen ob / kommt
                        found = myReader.read();
                    }
                    found = myReader.read(); // nach Stern muss / kommen        
                }
            }
            else if (found == 13) { // bei Zeilenumbruch wird 13 returned
                lineNr++;
            }
            // wird eine öffnende Klammer gefunden - in Stack gebunden
            else if (found == '{') {
                stack.push(found);
            }
            else if (found == '(') {
                stack.push(found);
            }
            // wird eine schließende Klammer gefunden - schau ob passende zuoberst in Stack, wenn ja, pop, sonst Fehler!
            else if (found == ')') {
                if (!stack.empty() && stack.peek() == '(') {
                    stack.pop();
                }
                else {
                    return(") without (; line Nr " + lineNr);
                }
            }
            else if (found == '}') {
                if (!stack.empty() && stack.peek() == '{') {
                    stack.pop();
                }
                else {
                    return("} without {; line Nr " + lineNr);
                }
            }   
        }
        while (found != -1); // signalisiert File-Ende

        // Am Ende noch überprüfen ob der Keller auch wirklich leer, nur dann Klammersetzung korrekt
        if (stack.empty()) {
            return("ok");
        }
        else {
        	return("stack not empty on end of file");
        }
    }
}
 

misaki

Mitglied
haha, ja , diese variante hatte ich auch schonmal - ist wahrscheinlich doch einfacher.

so noch zwei fallprobleme:

1. wenn ich eine schließende } entferne, kommt trotzdem das ok
2. ganz am ende muss ich mindestens drei } entfernen, damit ich das "stack not empty" bekomme ... ??
3. beim self check kommt kein ok mehr!

gott ich verzweifle noch! :D

Java:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;

public class JavaChecker {

	private static int lineNr = 0; // Variable für Zeilenangabe

	public static String checkBrackets(String filename) throws FileNotFoundException, IOException {
		
		FileReader myReader = new FileReader(filename); // erzeuge Reader für gewählte Datei
		Stack<Integer> stack = new Stack<Integer>(); // erzeuge einen Stack für Klammerung
		
		int found = 0;
		
		do {
			found = myReader.read();
            if (found == '\"') { // Anfang eines Strings, also ignorieren
				do {
					found = myReader.read(); // lese einfach weiter und mache nichts
				}
				while (found != '\"' && found != -1); // solange nicht Ende des Strings oder der Datei kommt
			}
			else if (found == '\'') { // char Zeichen, also ignorieren
				do {
					found = myReader.read(); // lese einfach weiter und mache nichts
				}
				while (found != '\'' && found != -1);  // solange nicht Ende des Char-Wertes oder der Datei kommt
			}
			else if (found == '/') {
				found = myReader.read(); // lese nächstes Zeichen
				if (found == '/') { // zwei // signalisieren Kommentar
					do {
						found = myReader.read();
					}
					while (found != 13); // 13 signalisiert Zeilenende, lese solange
					lineNr++; // hier wird ein Zeilenende erreicht ohne dass es anders wahrgenommen wird, Anzahl erhöhen
				}
				else if (found == '*') { // Kommentar über mehrere Zeilen
					do {
						do { // */ signalisiert ende, deshalb bis zum Stern lesen und dann schauen ob / kommt
							found = myReader.read();
						}
						while (found != '*');
						found = myReader.read(); // nach Stern muss / kommen		
						if (found == '/') {
							// Kommentar beendet, normal weiter
							break;
						}
						else {
							// weitersuchen
						}
					}
					while (found != -1);
				}
			}
			else if (found == 13) { // bei Zeilenumbruch wird 13 returned
				lineNr++;
			}
			// wird eine öffnende Klammer gefunden - in Stack gebunden
			else if (found == '{') {
				stack.push(found);
			}
			else if (found == '(') {
				stack.push(found);
			}
			// wird eine schließende Klammer gefunden - schau ob passende zuoberst in Stack, wenn ja, pop, sonst Fehler!
			else if (found == ')') {
				if (!stack.empty() && stack.peek() == '(') {
					stack.pop();
				}
				else {
					return (") without (; line Nr " + lineNr);
				}
			}
			else if (found == '}') {
				if (!stack.empty() && stack.peek() == '{') {
					stack.pop();
				}
				else {
                    return ("} without {; line Nr " + lineNr);
				}
			}	
		}
		while (found != -1); // signalisiert File-Ende
		
		// Am Ende noch überprüfen ob der Keller auch wirklich leer, nur dann Klammersetzung korrekt
		if (stack.empty()) {
            return ("ok");
        }
        else {
            return ("stack not empty on end of file");
        }
	}
}

hab den code noch etwas verschönert, das ist die aktuelle version:(
 
Zuletzt bearbeitet:

Volvagia

Top Contributor
Tut mir leid, ich finde den Fehler nicht.
Entweder bin ich blind oder einfach nur zu blöd.
Ich bin es im Debuger durchgegangen und habe auch eigene Dateien zum parsen geschrieben, um die Funktion jedes if's zu prüfen. Bei denen hat es immer funktioniert, nur bei der Sourcedatei nie. Oo

Java:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;
 
public class JavaChecker
{
    public static String checkBrackets(String filename) throws FileNotFoundException, IOException
    {
        FileReader myReader = new FileReader(filename);
        Stack<Integer> stack = new Stack<Integer>();
        
        int lineNr = 1	;
        int found = 0;
        do
        {
            found = myReader.read();
            if (found == '"')
            {
                found = myReader.read();
                do
                {
                	found = myReader.read();
                	if(found == 13)
        				lineNr++;
                }
                while (found != '"' && found != -1);
            }
            else if (found == '\'')
            {
            	do
            	{
            		found = myReader.read();
            		if(found == 13)
        				lineNr++;
            	}
            	while (found != '\'' && found != -1);
            }
            else if (found == '/')
            {
                found = myReader.read();
            	if(found == '/')
            	{
            		do
            		{
                        found = myReader.read();
                        if(found == 13)
            				lineNr++;
                    }
            		while(found != 13 && found != -1);
                }
            	else if (found == '*')
                {
            		do
            		{
            			found = myReader.read();
            			if(found == 13)
            				lineNr++;
            		}
            		while (found != '*');
                    if(myReader.read() != '/')
                    	throw new RuntimeException("Parse Exception");
                }
            	else
            	{
            		System.out.println((char)found);
            		throw new RuntimeException("Parse Exception");
            	}
            }
            else if (found == 13)
            	lineNr++;
            else if (found == '{')
            	stack.add(found);
            else if (found == '(')
                stack.add(found);
            else if (found == ')')
            {
                if (!stack.empty() && stack.peek() == '(')
                    stack.pop();
                else
                    return(") without (; line Nr " + lineNr);
            }
            else if (found == '}')
            {
            	if (!stack.empty() && stack.peek() == '{')
                    stack.pop();
                else
                	return("} without {; line Nr " + lineNr);
            }
            
        }
        while (found != -1);
        
        if (stack.empty())
        	return("ok");
        else
        	return("stack not empty on end of file");
    }
}
 

misaki

Mitglied
Hab jetzt auch noch wen anderen gefragt und der findet auch keinen Fehler. :(
Werd dann wohl mal mit dem Professor sprechen müssen, dass er sichs gesondert anschaut ..

Danke jedenfalls!
 

Antoras

Top Contributor
Ein Fehler liegt im Erkennen von chars:
Code:
'\''
. Es wird nicht beachtet, dass ein char-Zeichen escaped werden kann...
 

misaki

Mitglied
danke, hab jetzt noch folgendes dazugebaut

Java:
else if (found == '\'') { // char Zeichen, also ignorieren
				do {
					found = myReader.read(); // lese einfach weiter und überprüfe nur ob Zeilenwechsel
					if (found == 13) {
                        lineNr++;
					}
					if (found == '\\') { // escaped ', muss auch ignoriert werden sonst zu früh Ende!
						found = myReader.read(); // wenn das nächste Zeichen ein ' ist bricht die Schleife ab
						found = myReader.read();   // übernächstes Zeiche muss kontrolliert werden - wenn es ein ' ist bricht Schleife ab, sonst egal
						if (found == 13) { // es muss nur geschaut werden ob hier zufällig die Zeile aus wäre
							lineNr++;
						}
					}
				}
				while (found != '\'' && found != -1);  // solange nicht Ende des Char-Wertes oder der Datei kommt
			}

aber es is immer noch falsch :/
 

Antoras

Top Contributor
Ich hab mir deinen Code nochmal angeguckt und festgestellt, dass mehrzeilige Kommentare nicht zuverlässig erkannt werden. Weiter Fehler konnte ich aber auch keine feststellen - ich vermute aber, dass sie nach wie vor im Erkennen von chars liegt. Teste mal ob dein Code folgende Strings erkennen kann:
Code:
'\'''/'
,
Code:
'{'')'
Wahrscheinlich ist irgendwo ein
Code:
found = myReader.read();
zu wenig/viel.

Um die mehrzeiligen Kommentare zuverlässig zu erkennen müsste dein Code die Fähigkeit haben das nächste abzuarbeitende Token zu erkennen. Da dies mit einem FileReader nicht geht hab ich den Code so umgebaut, dass erst die ganze Datei eingelesen wird. Weiterhin hab ich Codeteile der Übersichtlichkeit wegen in Methoden ausgelagert und Konstanten für das Zeilen- und Dateiende angelegt um sie komfortabel ändern zu können. Herausgekommen ist das:
Java:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
import java.util.Stack;


public class JavaChecker {
	
	public static void main(final String... args) throws FileNotFoundException {
		System.out.println(new JavaChecker().checkBrackets("test"));
	}
	
	public static final char LINE_SEPARATOR = '\n';
	public static final char FILE_END = 0;
	
	private Stack<Character> stack;
	private String s;
	private char cur;
	private int pos;
	private int line;
	
	public String checkBrackets(final String filename) throws FileNotFoundException {
		stack = new Stack<Character>();
		s = new Scanner(new FileReader(filename)).useDelimiter("\0").next();
		cur = s.charAt(0);
		pos = 0;
		line = 1;
		
		while (cur != FILE_END) {
			switch (cur) {
				case '"':
					readString();
					break;
				case '\'':
					readChar();
					break;
				case '/':
					readComment();
					break;
				case '{':
					stack.add('{');
					break;
				case '}':
					popCurly();
					break;
				case '(':
					stack.add('(');
					break;
				case ')':
					popParen();
					break;
				default:
					break;
			}
			next();
		}
		return stack.empty() ? "ok" : "stack not empty at end of file";
	}
	
	private boolean isValid() {
		return pos < s.length() - 1;
	}
	
	private void next() {
		cur = isValid() ? s.charAt(++pos) : FILE_END;
		if (cur == LINE_SEPARATOR) {
			++line;
			next();
		}
	}

	private char peekNext() {
		return isValid() ? s.charAt(pos + 1) : FILE_END;
	}
	
	private void popCurly() {
		if (stack.empty() || stack.peek() != '{') {
			throw new RuntimeException("} without { (line " + line + ")");
		}
		stack.pop();
	}
	
	private void popParen() {
		if (stack.empty() || stack.peek() != '(') {
			throw new RuntimeException(") without ( (line " + line + ")");
		}
		stack.pop();
	}
	
	private void readString() {
		next();
		while (cur != '"' && cur != FILE_END) {
			next();
		}
	}
	
	private void readChar() {
		do {
			next();
			if (cur == '\\') {
				next();
				next();
			}
		} while (cur != '\'' && cur != FILE_END);
	}
	
	private void readComment() {
		next();
		switch (cur) {
			case '/':
				readSingleLineComment();
				break;
			case '*':
				readMultiLineComment();
				break;
			default:
				throw new RuntimeException("found '" + cur + "' but comment expected (line " + line + ")");
		}
	}
	
	private void readSingleLineComment() {
		while (peekNext() != LINE_SEPARATOR && cur != FILE_END) {
			next();
		}
	}
	
	private void readMultiLineComment() {
		boolean isComment = false;
		while (!isComment && cur != 0) {
			next();
			if (cur == '*' && peekNext() == '/') {
				isComment = true;
				next();
			}
		}
		if (!isComment) {
			throw new RuntimeException("invalid multi line comment found (line " + line + ")");
		}
	}
	
}
Ich hab den Code gegen sich selbst und gegen die größte Klasse des JDK java.awt.Component getestet und er hat beide mit Bravour bestanden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D FileWriter / FileReader Problem Java Basics - Anfänger-Themen 10
S Mit FileReader lesen, in ArrayList speichern Java Basics - Anfänger-Themen 4
T filereader , file aus programm einlesen Java Basics - Anfänger-Themen 12
W FileReader - Bitte um Erklärung Java Basics - Anfänger-Themen 7
L FileReader Java Basics - Anfänger-Themen 7
L FileReader Java Basics - Anfänger-Themen 2
D Hilfe bei FileReader und BufferedReader Java Basics - Anfänger-Themen 2
Y Datei mit relativem Dateipfad per FileReader aus .JAR heraus auslesen Java Basics - Anfänger-Themen 4
A FileReader Problem Java Basics - Anfänger-Themen 14
D JFileChooser & FileReader Java Basics - Anfänger-Themen 4
L Input/Output FileReader Pfadangabe Java Basics - Anfänger-Themen 7
L While-Schleife und filereader Java Basics - Anfänger-Themen 5
L FileReader und Filewriter Java Basics - Anfänger-Themen 4
F wo datei für filereader ablegen? Java Basics - Anfänger-Themen 11
L RandomAcessFile getFilePointer in normalen FileReader Java Basics - Anfänger-Themen 4
H OOP FileReader Einleseergebnis Java Basics - Anfänger-Themen 5
R Von wo nimmt der FileReader seine daten Java Basics - Anfänger-Themen 7
J fileReader: wird dateipfad benötigt? Java Basics - Anfänger-Themen 8
Burny91 FileReader und Writer gleichzeitg nutzen Java Basics - Anfänger-Themen 2
Burny91 FileReader / FileWriter / BufferedWriter An einer bestimmten Zeile String ersetzten Java Basics - Anfänger-Themen 2
F FileReader Frage Java Basics - Anfänger-Themen 3
M Frage zur Klasse FileReader Java Basics - Anfänger-Themen 6
G Character-orientierte File-Streams mit der Klasse FileReader Java Basics - Anfänger-Themen 5
Hamstinator Frage zu BufferedReader/FileReader Java Basics - Anfänger-Themen 4
F FileReader Methode Read() int? Java Basics - Anfänger-Themen 2
calzone FileReader, lesen ohne die Datei zu überschreiben? Java Basics - Anfänger-Themen 3
K FileReader Systempfad Mac Java Basics - Anfänger-Themen 11
hdi FileReader / BufferedReader langsam? Java Basics - Anfänger-Themen 3
A Filereader - An den Anfang des File springen Java Basics - Anfänger-Themen 2
N Pfad und FileReader? Java Basics - Anfänger-Themen 2
S Filereader funktioniert nicht! Fehlersuche Java Basics - Anfänger-Themen 9
K Problem mit .toString und FileReader Java Basics - Anfänger-Themen 2
G filereader Java Basics - Anfänger-Themen 5
G zusätzliche "" bei Pfadangabe z.B. bei FileReader Java Basics - Anfänger-Themen 2
B Problem mit Filereader und filewriter Java Basics - Anfänger-Themen 20
H IOException bei FileReader Java Basics - Anfänger-Themen 3
P BufferedReader / FileReader Key und Values Java Basics - Anfänger-Themen 7
K FileReader BufferedReader & Arrays Java Basics - Anfänger-Themen 14
D Wie funktionieren FileReader Java Basics - Anfänger-Themen 6
M FileReader.read(char[]) - Größe des Arrays? Java Basics - Anfänger-Themen 4
R FileInputStream.read() != FileReader.read(). Pls Help Java Basics - Anfänger-Themen 5
S FileReader-Problem Java Basics - Anfänger-Themen 2
G Textdatei auslesen - Text anfügen - FileReader Java Basics - Anfänger-Themen 18
G FileReader Java Basics - Anfänger-Themen 10
P FileReader Java Basics - Anfänger-Themen 2
V filereader soll aus config.txt pfade lesen Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben