[JAVA] Entwurfsmuster ~ Interpreter ~

1. Zuallererst

Hier ist eine Zusammenfassung des ** Interpreter-Musters ** im GoF-Entwurfsmuster.

2. Was ist das Interpreter-Muster?

3. Beispielklassendiagramm

Interpreter.PNG

4. Beispielprogramm

Ein Programm, das die in einer Textdatei geschriebene Sprache analysiert. Die BNF-Notation wird in der Grammatik der Sprache verwendet, die in dem zu analysierenden Text verwendet wird.

<program> ::= program <command list>
<command list> ::= <command>* end
<command> ::= <repeat command> | <primitive command>
<repeat command> ::= repeat <number> <command list>
<primitive command> ::= go | right | left

--<Programm>・ ・ ・ Auf das Token-Programm folgt die Befehlsspalte . --<Befehlsliste>・ ・ ・ wird 0 oder mehr wiederholt, gefolgt vom Token-Ende. --<Befehl>・ ・ ・ Entweder der Wiederholungsbefehl oder der Basisbefehl . (| Repräsentiert oder) --<Wiederholungsbefehl>・ ・ ・ Auf die Token-Wiederholung folgt die Anzahl der Wiederholungen , gefolgt von der Befehlsspalte . --<primitiver Befehl>・ ・ ・ gehen oder rechts oder links.

4-1. Kontextklasse

Eine Klasse, die den Kontext für die syntaktische Analyse darstellt.

Context.java


import java.util.StringTokenizer;

public class Context {

	private StringTokenizer tokenizer;
	private String currentToken;

	public Context(String text) {
		tokenizer = new StringTokenizer(text);
		nextToken();
	}

	public String nextToken() {
		if (tokenizer.hasMoreTokens()) {
			currentToken = tokenizer.nextToken();
		} else {
			currentToken = null;
		}
		return currentToken;
	}

	public String currentToken() {
		return currentToken;
	}

	public void skipToken(String token) throws Exception {
		if (!token.equals(currentToken)) {
			throw new Exception("Warning: " + token + " is expected, but " + currentToken + " is found.");
		}
		nextToken();
	}

	public int currentNumber() throws Exception {
		int number = 0;
		try {
			number = Integer.parseInt(currentToken);
		} catch (NumberFormatException e) {
			throw new Exception("Warning: " + e);
		}
		return number;
	}
}

4-2. Knotenklasse

Diese Klasse ist der "Knoten" des Syntaxbaums.

Node.java


public abstract class Node {
	public abstract void parse(Context context) throws Exception;
}

4-3. ProgramNode-Klasse

Diese Klasse entspricht .

ProgramNode.java


// <program> ::= program <command list>
public class ProgramNode extends Node {

	private Node commandListNode;

	public void parse(Context context) throws Exception {
		context.skipToken("program");
		commandListNode = new CommandListNode();
		commandListNode.parse(context);
	}

	public String toString() {
		return "[program " + commandListNode + "]";
	}
}

4-4. CommandNode-Klasse

Diese Klasse entspricht .

CommandNode.java


// <command> ::= <repeat command> | <primitive command>
public class CommandNode extends Node {

	private Node node;

	public void parse(Context context) throws Exception {
		if (context.currentToken().equals("repeat")) {
			node = new RepeatCommandNode();
			node.parse(context);
		} else {
			node = new PrimitiveCommandNode();
			node.parse(context);
		}
	}

	public String toString() {
		return node.toString();
	}
}

4-5. RepeatCommandNode-Klasse

Diese Klasse entspricht .

RepeatCommandNode.java


// <repeat command> ::= repeat <number> <command list>
public class RepeatCommandNode extends Node {

	private int number;
	private Node commandListNode;

	public void parse(Context context) throws Exception {
		context.skipToken("repeat");
		number = context.currentNumber();
		context.nextToken();
		commandListNode = new CommandListNode();
		commandListNode.parse(context);
	}

	public String toString() {
		return "[repeat " + number + " " + commandListNode + "]";
	}
}

4-6. CommandListNode-Klasse

Diese Klasse entspricht .

CommandListNode.java


import java.util.ArrayList;

// <command list> ::= <command>* end
public class CommandListNode extends Node {

	private ArrayList list = new ArrayList();

	public void parse(Context context) throws Exception {
		while (true) {
			if (context.currentToken() == null) {
				throw new Exception("Missing 'end'");
			} else if (context.currentToken().equals("end")) {
				context.skipToken("end");
				break;
			} else {
				Node commandNode = new CommandNode();
				commandNode.parse(context);
				list.add(commandNode);
			}
		}
	}

	public String toString() {
		return list.toString();
	}
}

4-7. PrimitiveCommandNode-Klasse

Diese Klasse entspricht .

PrimitiveCommandNode.java


// <primitive command> ::= go | right | left
public class PrimitiveCommandNode extends Node {

	private String name;

	public void parse(Context context) throws Exception {
		name = context.currentToken();
		context.skipToken(name);
		if (!name.equals("go") && !name.equals("right") && !name.equals("left")) {
			throw new Exception(name + " is undefined");
		}
	}

	public String toString() {
		return name;
	}
}

4-8. Zu analysierender Text

Der zu syntaktisch zu analysierende Text.

program.txt


program end
program go end
program go right go right go right go right end
program repeat 4 go right end end
program repeat 4 repeat 3 go right go left end right end end

4-9 Hauptklasse

Diese Klasse führt die Hauptverarbeitung durch.

Main.java


import java.io.BufferedReader;
import java.io.FileReader;

public class Main {
	public static void main(String[] args) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader("program.txt"));
			String text;
			while ((text = reader.readLine()) != null) {
				System.out.println("text = \"" + text + "\"");
				Node node = new ProgramNode();
				node.parse(new Context(text));
				System.out.println("node = " + node);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

4-10 Ausführungsergebnis

text = "program end"
node = [program []]
text = "program go end"
node = [program [go]]
text = "program go right go right go right go right end"
node = [program [go, right, go, right, go, right, go, right]]
text = "program repeat 4 go right end end"
node = [program [[repeat 4 [go, right]]]]
text = "program repeat 4 repeat 3 go right go left end right end end"
node = [program [[repeat 4 [[repeat 3 [go, right, go, left]], right]]]]

5. Vorteile

Das Interpreter-Muster erleichtert das Hinzufügen oder Ändern von Regeln. Eines der Merkmale des Interpreter-Musters ist, dass "eine Regel durch eine Klasse dargestellt wird". Mit anderen Worten, wenn Sie eine neue Regel hinzufügen möchten, müssen Sie lediglich eine Unterklasse der Node-Klasse hinzufügen. Wenn Sie die Regel ändern, müssen Sie nur die Unterklasse der Node-Klasse ändern.

  1. GitHub

7. Liste der Entwurfsmuster

8. Referenz

Dieser Artikel und das Beispielprogramm wurden basierend auf den folgenden Büchern erstellt.

Es war sehr leicht zu verstehen und ich habe viel gelernt. Vielen Dank. Die detaillierten Erklärungen zu den Entwurfsmustern und Beispielprogrammen sind geschrieben. Schauen Sie sich also auch die Bücher an.

Recommended Posts

Entwurfsmuster ~ Interpreter ~
Entwurfsmuster ~ Besucher ~
Java-Entwurfsmuster
Entwurfsmuster ~ Proxy ~
Entwurfsmuster ~ Zustand ~
Entwurfsmuster ~ Strategie ~
Entwurfsmuster ~ Singleton ~
Entwurfsmuster ~ Composite ~
Entwurfsmuster (2): Builder
Entwurfsmuster (1): AbstractFactory
Entwurfsmuster ~ Befehl ~
Entwurfsmuster ~ Iterator ~
Entwurfsmuster ~ Brücke ~
Entwurfsmuster ~ Mediator ~
Entwurfsmuster ~ Dekorateur ~
Entwurfsmuster ~ Beobachter ~
Entwurfsmuster ~ Prototyp ~
Entwurfsmuster ~ Memento ~
Entwurfsmuster ~ Adapter ~
Entwurfsmuster ~ Fliegengewicht ~
C ++ - Entwurfsmuster (TemplateMethod-Muster)
Entwurfsmuster ~ Fabrikmethode ~
Entwurfsmuster ~ Abstrakte Fabrik ~
Zusammenfassung des GoF-Entwurfsmusters
Entwurfsmuster ~ Vorlagenmethode ~
Zusammenfassung des Java-Entwurfsmusters
Entwurfsmuster ~ Verantwortungskette ~
[Entwurfsmuster] Java-Kernbibliothek
Entwurfsmuster nach Ruby Template-Methode Musternotiz
C # gekautes Designmuster: TemplateMethod
Anwendungsbeispiel für Entwurfsmuster (Nr. 1)
Java-Anfänger-Entwurfsmuster (Factory-Methodenmuster)
Prototypmuster
Vermittlermuster
Iteratormuster
Zusammengesetztes Muster
Beobachtermuster
Builder-Muster
Brückenmuster
Befehlsmuster
Builder-Muster
Strategiemuster
Iteratormuster
Besuchermuster
Adaptermuster
Proxy-Muster
Strategiemuster
Zusammengesetztes Muster
Singleton-Muster
Singleton-Muster
Prototypmuster
[Entwurfsmuster] Allgemeine Logik mit der Vorlagenmethode
Fassadenmuster
Dekorationsmuster
Fliegengewichtsmuster
Dekorateur Muster
Vermittlermuster
Fassadenmuster
Besuchermuster
Brückenmuster
PrintObserver "Observer Design Pattern: Beschreibung und Implementierungsbeispiel"