Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich hab wahrscheinlich eine ganze einfache Frage, aber ich hocke hier seit ner Stunde über dieser Frage und blockiere mich selber:
Ich will einen rekursiven Datentyp in dieser Form erstellen (zur Schachtelung von Quelltexten): SourceCode = [Block]
Block = Block | Comment | Code
Code = [String]
Comment = [String]
Wie implementier ich so einen Datentyp in Java?
Bisher kam ich auf:
Java:
class SourceCode
class Block extends SourceCode
class Comment extends Block
class Code extends Block
Aber da fehlt mir ja noch die Rekursion, so dass ein Block aus 2 Blöcken der 2. Ebene bestehen kann, die wiederum Blöcke UND Kommentare haben.
Im Java 6 Übungsbuch hab ich dazu mal was gesehen, das sah ungefähr so aus:
Java:
public class Buch {
Seite seite;
private class Seite {
Seite naechsteSeite;
}
}
Ein Objekt der Klasse Seite hält also immer einen Verweis auf ein anderes Objekt der Klasse Seite (in diesem Fall die nächste Seite). Die so gefundene Seite hat wieder einen Verweis auf die nächste Seite und so weiter. Meinst du so?
Ich habs jetzt erstmal so gelöst (obs funktioniert wird sich in den nächsten 3-4 Tagen herausstellen):
Java:
public class SourceCode {
Block root;
}
public class Block {
List<Block> block = new LinkedList<Block>();
}
public class Comment extends Block{
List<String> line = new LinkedList<String>();
}
public class Code extends Block{
List<String> line = new LinkedList<String>();
}
Somit ist SourceCode die RootDatei (das weisse Blatt), Block ist jeweils ein Block von Blöcken, Codelines oder Commentlines, die auch nebeneinander stehen können...
Statt direkte Vererbung würde ich hier eher ein Interface verwenden.
Comment und Code sind ja eigentlich nur Bestandteil eines Blocks und sollten selbst keine Subelemente vom Typ Block, Code oder Comment besitzen können.
Java:
interface BlockElement {...}
class Block implements BlockElement {
List<BlockElement> elementList = new ArrayList<BlockElement>();
}
class Code implements BlockElement {
}
class Comment implements BlockElement {
}
Statt direkte Vererbung würde ich hier eher ein Interface verwenden.
Comment und Code sind ja eigentlich nur Bestandteil eines Blocks und sollten selbst keine Subelemente vom Typ Block, Code oder Comment besitzen können.
Java:
interface BlockElement {...}
class Block implements BlockElement {
List<BlockElement> elementList = new ArrayList<BlockElement>();
}
class Code implements BlockElement {
}
class Comment implements BlockElement {
}
Das gefällt mir... darauf hät ich auch kommen können. Mit etwas Abstraktion...
Man könnte auch aus BlockElement ne abstrakte Klasse machen, dort die List einbauen und den Rest stehen lassen!
Würde ich mit EMF machen, da ist dann auch Mehrfachvererbung kein Problem.
Da du das ganze in einer Pseudogrammatik geschrieben hast:
Wenn es tatsächlich um eine Grammatik bzgw. einen Parser geht, dann nimm Xtext.
Xtext generiert dir aus einer solchen Grammatik direkt das EMF Modell, den Lexer, Parser, Linker und wenn du magst einen Eclipse Editor.
Würde ich mit EMF machen, da ist dann auch Mehrfachvererbung kein Problem.
Da du das ganze in einer Pseudogrammatik geschrieben hast:
Wenn es tatsächlich um eine Grammatik bzgw. einen Parser geht, dann nimm Xtext.
Xtext generiert dir aus einer solchen Grammatik direkt das EMF Modell, den Lexer, Parser, Linker und wenn du magst einen Eclipse Editor.
Das ist keine Pseudogrammatik, sondern Haskell.
Eine Hinterlassenschaft meines Professors, der uns für die Programmierung von Datentypen mit Haskell getriezt hat, es uns aber nie beigebracht hat.
Und diese Grammatik ist bloss ein einfaches Datenmodell, für das was dahinter noch alles kommt. Nur ich kam auf diese einfache Komposition nicht so, wie ich sie haben wollte, aber der Vorschlag von Michael... kommt dem wohl sehr nah!