Rekursives Parsen (ohne Reg Expressions)

Joggal

Aktives Mitglied
Hallo an alle,

Ich möchte gerne einen String wie zum Beispiel eine Uhrzeit rekursiv parsen und auf die Syntax überprüfen.

Zum Beispiel ein Ascii Datum:

asctime-date = wkday SP date3 SP time SP 4DIGIT

date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
; month day (e.g., Jun 2)

time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
; 00:00:00 - 23:59:59

wkday = "Mon" | "Tue" | "Wed"
| "Thu" | "Fri" | "Sat" | "Sun"

month = "Jan" | "Feb" | "Mar" | "Apr"
| "May" | "Jun" | "Jul" | "Aug"
| "Sep" | "Oct" | "Nov" | "Dec"

Wie gesagt, möchte ich das ganze rekursiv mit Methoden lösen (eine ruft die andere auf) und so prüfen ob das eingegebene Datum stimmt. (z.B. gültig: Mon Jun 22 12:24:01 )

Mein Problem allerdings: Ich habe überhaupt keinen Plan wie ich das ganze umsetzen soll...
Ich weiß natürlich, dass ich mit einem StringTokenizer parsen muss, aber dann das ganze rekursiv zu machen ... da weiß ich nicht weiter!

Wäre schön wenn mir hier jemand weiterhelfen könnte!

lG
 

DarXun

Aktives Mitglied
Ich verstehe nicht so ganz wo du da Rekursion benötigen würdest?

Du hast Rekursion auch als "eine Methode ruft eine andere auf" beschrieben.
Rekursion bedeutet jedoch, dass eine Methode sich selbst aufruft.

MfG

DarXun
 

Joggal

Aktives Mitglied
Hallo,

Ich weiß, ich habs ein bisschen blöd erklärt, aber vielleicht hilft diese "Musterlösung" weiter:

Main:

Java:
package theMain;

import ahit4.ebnf.ArithmetikParser;

public class TheMain {

	public TheMain() {

		String arith = "3 * ( 5 + 1 ) ";
		//String arith = "5 ? 1";
		ArithmetikParser par = new ArithmetikParser(arith);

	}

	public static void main(String[] args) {
		new TheMain();

	}

}

Interface:

Java:
package ahit4.interf;

public interface Ebnf {

	public enum Symbols {
	    NumSy,PlusSy,MinSy,DivSy,MulSy,ModSy,EndSy,ErrSy,StartSy,LeftParanthesesSy,RightParanthesesSy
	}
	
}

Parser: Es wird eine Arithmetik überprüft (z.B. 2 * (3 + 6) etc. )

Java:
/**
 * 
 */
package ahit4.ebnf;

import java.util.StringTokenizer;

import ahit4.interf.Ebnf;

/**
 * @author franzr
 * 
 *         sum : product [{ (’+’|’-’) product }];
product : term [{ (’*’|’/’|’%’) term }];
term : [{’+’|’-’}] ( Number | ’(’ sum ’)’ ) ;
Number : digit | Number digit ;
digit : ’0’ | ’1’ | ’2’ | ’3’ | ’4’ | ’5’ | ’6’ | ’7’ | ’8’ | ’9’ ;
 * 
 * 
 */

public class ArithmetikParser implements Ebnf {

	private class Lexer {
		private StringTokenizer token = null;
		private String curSym = "";
		private String text;

		public Lexer(String text) {
		
			this.text = text;
			token = new StringTokenizer(text);

		}

		public Symbols getNextSym() {

			if (token.hasMoreTokens()) {
				curSym = token.nextToken();

				if (curSym.matches("[0-9]+"))
					return Symbols.NumSy;

				switch (curSym) {

				case "/":
					return Symbols.DivSy;
				case "*":
					return Symbols.MulSy;
				case "%":
					return Symbols.ModSy;
				case "+":
					return Symbols.PlusSy;
				case "-":
					return Symbols.MinSy;
				case "(":
					return Symbols.LeftParanthesesSy;
				case ")":
					return Symbols.RightParanthesesSy;
				default:
					return Symbols.ErrSy;
				}

			}
			return Symbols.EndSy;
		}

		public final String getText() {
			return text;
		}

		public final String getLastScannedSymbol() {
			return curSym;
		}

	}

	private Lexer lexer = null;
	private Symbols currentSym = Symbols.StartSy;

	
	
	
	public ArithmetikParser(String text) {
		lexer = new Lexer(text);
		currentSym = lexer.getNextSym(); // scanned symbol
		
		if (sum()) {
			System.out.println("Der Ausdruck <<" + lexer.getText()
					+ ">> wurde erfolgreich überprüft.");
		} else {
			System.out.println("Der Ausdruck <<" + lexer.getText()
					+ ">>  ist fehlerhaft.");
		}
	}

	private boolean sum() {

		if (!product()) {
			System.out.println("EIngabe entspricht nicht der Grammatik.");
			return false;
		}
		if (currentSym == Symbols.PlusSy || currentSym == Symbols.MinSy) {
			currentSym = lexer.getNextSym();
			if (!product()) {
				System.out.println("EIngabe entspricht nicht der Grammatik.");
				return false;
			}

		}
		if (currentSym == Symbols.ErrSy) {
			String errSym = lexer.getLastScannedSymbol();
			printErrMsg1("sum", errSym);
			return false;
		}
		return true;
	}

	private boolean product() {

		if (!term())
			return false;
		if (currentSym == Symbols.MulSy || currentSym == Symbols.DivSy
				|| currentSym == Symbols.ModSy) {
			currentSym = lexer.getNextSym();
			if (!term())
				return false;

			
		}

		return true;

	}

	private boolean term() {
		if (currentSym == Symbols.PlusSy || currentSym == Symbols.MinSy)
			currentSym = lexer.getNextSym();
		if (currentSym == Symbols.LeftParanthesesSy) {
			currentSym = lexer.getNextSym();
			if (!sum()) {
				return false;
			}
			if (currentSym != Symbols.RightParanthesesSy) {
				printErrMsg("term", Symbols.RightParanthesesSy, currentSym);
				return false;
			}
			currentSym = lexer.getNextSym();
			return true;

		}
		if (!number()) {
			return false;
		}
		// currentSym = lexer.getNextSym();

		return true;
	}

	private boolean number() {
		if (!digit())
			return false;

		return true;
	}

	private boolean digit() {
		if (currentSym == Symbols.NumSy) {
			currentSym = lexer.getNextSym();
			return true;
		}
		printErrMsg("digit", Symbols.NumSy, currentSym);
		return false;
	}

	private void printErrMsg(String produktion, Symbols exp, Symbols found) {
		System.out.println("Produktion: " + produktion + ", erwarte Symbol: "
				+ exp + ", gefunden: " + found);
	}

	private void printErrMsg1(String produktion, String found) {
		System.out.println("Produktion: " + produktion
				+ ", ungültiges Symbol  <<" + found + ">> gefunden.");

	}
}

Mein Problem: Ich verstehe den Ablauf überhaupt nicht... Sprich, die Methoden sum(), term(), ... etc.
Ich habe versucht so einen Arithmetik Prüfer nachzumachen, aber ich bin gescheitert da ich mir den Ablauf nicht vorstellen kann, wie das ganze immer nacheinander das einzelne Token in den jeweiligen Methoden rekursiv überprüft.

Hoffe ich konnte mein Problem ein bisschen besser erklären und vielleicht kann mir ja jetzt jemand helfen.

lG
 

diggaa1984

Top Contributor
Mein Problem: Ich verstehe den Ablauf überhaupt nicht... Sprich, die Methoden sum(), term(), ... etc.

Also wenn du Grammatiken verstehst ist doch der Algorithmus leicht nachzuvollziehen:
sum : product [{ (’+’|’-’) product }];

Summe ist also ein "product", welches optional mit einem weiteren "product" durch "plus" oder "minus" verknüpft ist.

Java:
private boolean sum() {
    //muss ein product sein
    if (!product()) {       
        System.out.println("EIngabe entspricht nicht der Grammatik.");            
        return false;        
    }        
    
    //optional mit PlusSy oder MinusSy mit
    if (currentSym == Symbols.PlusSy || currentSym == Symbols.MinSy) {            
        currentSym = lexer.getNextSym(); 

        //weiterem product verknuepft           
        if (!product()) {
            System.out.println("EIngabe entspricht nicht der Grammatik.");  
            return false;            
        }
    }

    if (currentSym == Symbols.ErrSy) {
        String errSym = lexer.getLastScannedSymbol();
        printErrMsg1("sum", errSym);
        return false;
    }

    return true;
}

analog für die anderen methoden
 

Joggal

Aktives Mitglied
Hallo,

Danke vielmals für deine Hilfe, das hat mir schon ein wenig weitergeholfen!

Ich werde versuchen das so nach zu programmieren und vielleicht wirds ja was :)


EDIT: Die Methode "term()" ist mir noch nicht ganz klar...

wieso wird da abgefragt if(!sum()) return false; ???

lg
 
Zuletzt bearbeitet:

Joggal

Aktives Mitglied
Hallo,

Ich habe das Programm selbst nach programmiert, und stoße leider auf folgendes Problem:

Wenn ich z.B 4 * 3 überprüfe, erkennt es: zahl mal zahl , allerdings gibt es mir dann ständig "Falsche Syntax" aus... :/

Vielleicht bin ich einfach nur schon blind wegen zu viel vor dem PC sitzen.. aber es wäre schön wenn mal jemand drüber schauen könnte und mir vielleicht weiterhelfen könnte.

Hier der Code:

Lexer Klasse: Gibt immer das nächste Symbol zurück
Java:
package ahit4.lexer;

import java.util.StringTokenizer;

public class Lexer {
	
	private StringTokenizer sT;
	private String currentSymbol;
	
	public enum Symbol{
		lKlammer, rKlammer, zahl, plus,minus,sp, div, mal, mod, ende;
	}
	
	public Lexer(String text) {
		
		sT = new StringTokenizer(text);
	}
	
	public Symbol getNextSymbol(){

		
		if(sT.hasMoreTokens()){
			
			currentSymbol = sT.nextToken();
			
			if(currentSymbol.matches("[1-9]+")){
				return Symbol.zahl;
			}
			
			switch(currentSymbol){
			
			case " ":
				return Symbol.sp;
			case "+":
				return Symbol.plus;
			case "-":
				return Symbol.minus;
			case "/":
				return Symbol.div;
			case "*":
				return Symbol.mal;
			case "%":
				return Symbol.mod;
			case "(":
				return Symbol.lKlammer;
			case ")":
				return Symbol.rKlammer;
	
			}
		}
		
		return Symbol.ende;
		
	}

}

Parser Klasse: Hauptklasse, prüft die Syntax, sprich jedes einzelne Zeichen welches vom Lexer zurück gegeben wird

Java:
package ahit.parser;

/**
 * @author franzr
 * 
 *         sum : product [{ (’+’|’-’) product }];
product : term [{ (’*’|’/’|’%’) term }];
term : [{’+’|’-’}] ( Number | ’(’ sum ’)’ ) ;
Number : digit | Number digit ;
digit : ’0’ | ’1’ | ’2’ | ’3’ | ’4’ | ’5’ | ’6’ | ’7’ | ’8’ | ’9’ ;
 * 
 * 
 */



import ahit4.lexer.Lexer;
import ahit4.lexer.Lexer.Symbol;

public class Parser {
	
	private Lexer lexer;
	private Symbol currentSymbol;

	
	public Parser(Lexer lexer) {
		// TODO Auto-generated constructor stub
		this.lexer = lexer;
	}
	
	
	public void parseText(){
		
		if(!sum()){
			System.out.println("Falsche Syntax");
		}
		else System.out.println("Richtig");
		
	}


	private boolean sum() {
		// TODO Auto-generated method stub
		
		currentSymbol = lexer.getNextSymbol();
		System.out.println(currentSymbol.toString());
		
		if(!product()){
			return false;
		}
		
		if(currentSymbol == Symbol.minus || currentSymbol == Symbol.plus){
			
			currentSymbol = lexer.getNextSymbol();
			System.out.println(currentSymbol.toString());
			
			if(!product()){
				return false;
			}
		}
		
		return false;
	}


	private boolean product() {
		// TODO Auto-generated method stub

		if(!term()){
			return false;
		}
		
		if(currentSymbol == Symbol.mal || currentSymbol == Symbol.div || currentSymbol == Symbol.mod){
			
			currentSymbol = lexer.getNextSymbol();
			System.out.println(currentSymbol.toString());
			if(!term()){
				return false;
			}
		}
		
		return true;
	}


	private boolean term() {
		// TODO Auto-generated method stub
		
		if(currentSymbol == Symbol.minus || currentSymbol == Symbol.plus){
			currentSymbol = lexer.getNextSymbol();
			System.out.println(currentSymbol.toString());
		}
		
		if (currentSymbol == Symbol.lKlammer) {
			currentSymbol = lexer.getNextSymbol();
			
			if (!sum()) {
				return false;
			}
			if (currentSymbol != Symbol.rKlammer) {
			
				return false;
			}
			currentSymbol = lexer.getNextSymbol();
			return true;

		}
	
		if(!number()){
			return false;
		}
		
		return true;
	}


	private boolean number() {
		// TODO Auto-generated method stub
		
		if(!digit()){
			return false;
		}
		return true;
	}


	private boolean digit() {
		// TODO Auto-generated method stub
		
		if(currentSymbol == Symbol.zahl){
			currentSymbol = lexer.getNextSymbol();
			System.out.println(currentSymbol.toString());
			return true;
		}
		
		return false;
	}
	

}

TheMain: Testet das Ganze :p

Java:
package ahit4.main;

import ahit.parser.Parser;
import ahit4.lexer.Lexer;

public class TheMain {

	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		final String text = "4 * 3";
		
		Lexer lexer = new Lexer(text);
		
		Parser parser = new Parser(lexer);
		parser.parseText();

	}

}
 

diggaa1984

Top Contributor
Java:
private boolean sum() {
        // TODO Auto-generated method stub
       
        currentSymbol = lexer.getNextSymbol();
        System.out.println(currentSymbol.toString());
       
        if(!product()){
            return false;
        }
       
        if(currentSymbol == Symbol.minus || currentSymbol == Symbol.plus){
           
            currentSymbol = lexer.getNextSymbol();
            System.out.println(currentSymbol.toString());
           
            if(!product()){
                return false;
            }
        }
       
        return false; //<<------ muss return true; sein
    }

Ohne das jetzt länger analysiert zu haben, sollte der Fehler erstmal darin liegen (siehe Kommentar)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Rekursives Programm zum Anzeigen von Primzahlen Java Basics - Anfänger-Themen 3
C Rekursives Backtracking beim Spiel Peg Java Basics - Anfänger-Themen 22
G Rekursives Programmieren --> harmonische Reihe Java Basics - Anfänger-Themen 3
S Rekursives Problem.... Java Basics - Anfänger-Themen 16
S Rekursives Durchlaufen eines Verzeichnisses - AccessDeniedException behandeln Java Basics - Anfänger-Themen 1
S Rekursives Zählen einer Zahl Java Basics - Anfänger-Themen 8
S Rekursives Umdrehen, Spiegeln. etc. von Strings Java Basics - Anfänger-Themen 3
I Rekursives Löschen in Binärem Suchbaum Java Basics - Anfänger-Themen 2
L rekursives spiel programmieren Java Basics - Anfänger-Themen 4
G Rekursives aufrufen führt zu StackOverflowError Panel durchl Java Basics - Anfänger-Themen 5
M Rekursives suchen im TreeMenu Java Basics - Anfänger-Themen 10
N Rekursives suchen in einer Liste Java Basics - Anfänger-Themen 8
G Primzahlentester als rekursives Programm! Java Basics - Anfänger-Themen 13
H Rekursives einlesen von Lokalen Ordner Java Basics - Anfänger-Themen 4
Beowend String zu Date parsen Java Basics - Anfänger-Themen 1
W Strings und das parsen Java Basics - Anfänger-Themen 8
R String index out of range: -1 beim Datei Parsen Java Basics - Anfänger-Themen 15
K String nach bestimmtem Muster parsen Java Basics - Anfänger-Themen 3
K Datentypen String zu Integer parsen Java Basics - Anfänger-Themen 2
L Jackson JSON parsen Java Basics - Anfänger-Themen 7
7.7GradOst Datentypen Stringeingabe aus z.B. "4,d,<" parsen Java Basics - Anfänger-Themen 7
D InputStream parsen und als Bilddatei abspeichern Java Basics - Anfänger-Themen 1
M JAVA String schnell parsen Java Basics - Anfänger-Themen 14
K Methoden Datum parsen Java Basics - Anfänger-Themen 16
V Java Regex richtig parsen Java Basics - Anfänger-Themen 2
L Beliebigen Datentypen aus String parsen Java Basics - Anfänger-Themen 6
L Datei aus Multipart parsen und speichern, seltsam codiert? Java Basics - Anfänger-Themen 16
J String aus Json File parsen Java Basics - Anfänger-Themen 6
S Date parsen klappt nicht richtig Java Basics - Anfänger-Themen 3
M Webseiten Parsen Java Basics - Anfänger-Themen 2
M Input/Output Probleme beim Parsen von CSV und TXT Dateien Java Basics - Anfänger-Themen 7
V Umlaute beim Parsen einer HTML Seite Java Basics - Anfänger-Themen 4
P String parsen Java Basics - Anfänger-Themen 5
S fehler beim datum parsen Java Basics - Anfänger-Themen 6
T Klassen CSV datei einlesen und parsen Java Basics - Anfänger-Themen 4
F Methoden Termin parsen Java Basics - Anfänger-Themen 2
Luk10 String (Hexadezimal) zu int parsen Java Basics - Anfänger-Themen 12
O Nicht Standard Form boolesche Funktion in Standard Form parsen Java Basics - Anfänger-Themen 3
E Datentypen Unvollständiges Datum parsen Java Basics - Anfänger-Themen 8
U Website parsen Java Basics - Anfänger-Themen 11
D Java - OutOfMemoryError beim Parsen Java Basics - Anfänger-Themen 15
J String zu Double parsen (multiple points) Java Basics - Anfänger-Themen 2
K Fehlerbehandlung beim Parsen von Strings Java Basics - Anfänger-Themen 9
F Datum AM / PM parsen Java Basics - Anfänger-Themen 5
A Datentypen Datum mit "May" zu Date parsen Java Basics - Anfänger-Themen 6
F Datum parsen Java Basics - Anfänger-Themen 6
R Datumsformatierung parsen Java Basics - Anfänger-Themen 8
E Code parsen/ formatieren Java Basics - Anfänger-Themen 3
G String parsen Java Basics - Anfänger-Themen 3
J int Wert mit getter holen und in String parsen Java Basics - Anfänger-Themen 5
trash Double Parsen? Java Basics - Anfänger-Themen 3
M Datum parsen Java Basics - Anfänger-Themen 10
A Parsen von double zu int? Java Basics - Anfänger-Themen 2
L String zu Enum parsen Java Basics - Anfänger-Themen 8
L String zuverlässig nach Char parsen? Java Basics - Anfänger-Themen 4
S String KeyEvent parsen Java Basics - Anfänger-Themen 2
D Datum parsen Java Basics - Anfänger-Themen 11
H XML Parsen Java Basics - Anfänger-Themen 7
J HTML mit XPath parsen Java Basics - Anfänger-Themen 7
H Gleichung parsen Java Basics - Anfänger-Themen 10
Spin SAX parsen ..XML not found Java Basics - Anfänger-Themen 2
W String zu Calendar parsen Java Basics - Anfänger-Themen 4
S String Parsen Java Basics - Anfänger-Themen 3
T Zeitwerte parsen Java Basics - Anfänger-Themen 6
J Scanner - Zeile parsen Java Basics - Anfänger-Themen 8
S String parsen Java Basics - Anfänger-Themen 17
W Char in String parsen Java Basics - Anfänger-Themen 6
E Wochentag String parsen Java Basics - Anfänger-Themen 2
S Ascii Datei parsen Java Basics - Anfänger-Themen 2
bugmenot args parsen Java Basics - Anfänger-Themen 3
G Swing xml parsen - Office Java Basics - Anfänger-Themen 8
M Bilder "parsen" Java Basics - Anfänger-Themen 5
G String parsen Java Basics - Anfänger-Themen 7
G Char Wert in Int Wert parsen Java Basics - Anfänger-Themen 10
P HTML parsen Java Basics - Anfänger-Themen 2
K Objekte zurück parsen Java Basics - Anfänger-Themen 2
D xml parsen mit Java Java Basics - Anfänger-Themen 5
G Vector Strijng parsen Java Basics - Anfänger-Themen 6
G Url parsen? Java Basics - Anfänger-Themen 3
H parsen Java Basics - Anfänger-Themen 24
M probleme beim parsen Java Basics - Anfänger-Themen 7
T Beim XML-Parsen Text einlesen Java Basics - Anfänger-Themen 5
C parsen Java Basics - Anfänger-Themen 2
G Parsen eines Strings Java Basics - Anfänger-Themen 4
M Object[] parsen Java Basics - Anfänger-Themen 9
E Mathematisch parsen, aber mit einer Variablen X ! Java Basics - Anfänger-Themen 6
N Int parsen Java Basics - Anfänger-Themen 3
D Array Parsen Java Basics - Anfänger-Themen 4
N Datum parsen Java Basics - Anfänger-Themen 3
P Datei mit Strings parsen Java Basics - Anfänger-Themen 4
M Html Parsen / Values von Hidden Fields auslesen Java Basics - Anfänger-Themen 10
W html parsen Java Basics - Anfänger-Themen 2
K Tokens in Integer parsen Java Basics - Anfänger-Themen 2
D HTML-Datei einlesen/parsen Java Basics - Anfänger-Themen 9
J java script mit java parsen Java Basics - Anfänger-Themen 6
G parsen von double zu int Java Basics - Anfänger-Themen 4
RaoulDuke java.util.Date parsen Java Basics - Anfänger-Themen 5
B Problem beim XML-Parsen Java Basics - Anfänger-Themen 10
G Parsen des Datums nicht möglich! Wer kann helfen? Java Basics - Anfänger-Themen 7
M.C.S. String parsen in Java Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben