[GO] [Vierergruppe] Design Pattern Learning - Interpreter

Dolmetscher-Dolmetscher

** Inhaltsverzeichnis ** Es dauerte lange, bis dieses Muster die Struktur verstand. es ist schwierig.

Ist das Muster, für das Sie einen Syntaxbaum generieren möchten? Dieses Muster drückt eine Gruppe vom Start-Tag bis zum End-Tag mit einem Objekt aus. Composite Es ist, als würde man anhand eines Musters analysieren und es als Gruppe verarbeiten.

Zweck

Definieren Sie für eine Sprache einen grammatikalischen Ausdruck und einen Interpreter, der ihn zur Interpretation des Satzes verwendet.

Komponente

-AbstractExpression Abstrakte Klasse für alle Knoten -TerminalExpression Eine Klasse, die das Ende darstellt -NonterminalExpression Eine Klasse, die etwas anderes als das Ende ausdrückt ・ Kontext Kontext / Situation ・ Client-Benutzer

Implementierung

Implementieren Sie ein Beispielprogramm, das Daten für vier Regeln mit hierarchischer Struktur verarbeitet. <+> ~ </ +> Addition <-> ~ </-> Subtraktion <\ *> ~ </ \ *> Multiplikation </> ~ /> Teilen

Zielproben-Daten.xml


<+>
    1 
    <-> 
        2 
        3 
        4 
        5 
        6 
        <*> 
            7 
            8 
        </*> 
        9 
    </->
    10 
    11 
    </> 
        12 
        4 
    <//> 
</+>

Wenn Sie die obigen Beispieldaten in eine vertraute Form formatieren, sind dies "1 + (2 - 3 - 4 - 5 - 6 - (7 * 8) -9) + 10 + 11 + (12/4)" und die Lösung `` `-56``` ist der erwartete Wert.

AbstractExpression Abstrakte Klasse für alle Knoten

Expression.kt


package interpreter

interface Expression {
    enum class Operator(val startTag: String, val endTag: String) {
        Plus("<+>", "</+>"),
        Minus("<->", "</->"),
        Multiplication("<*>", "</*>"),
        Divide("</>", "<//>"),
    }
    fun interpret(context: Context): Int

    companion object {
        fun getExpression(token: String?): Expression? {
            return when (token) {
                Operator.Plus.startTag -> {
                    PlusNonterminalExpression()
                }
                Operator.Minus.startTag -> {
                    MinusNonterminalExpression()
                }
                Operator.Multiplication.startTag -> {
                    MultiplicationExpression()
                }
                Operator.Divide.startTag -> {
                    DivideExpression()
                }
                Operator.Plus.endTag,
                Operator.Minus.endTag,
                Operator.Multiplication.endTag,
                Operator.Divide.endTag -> {
                    null
                }
                else -> {
                    TerminalExpression()
                }
            }
        }
    }
}

TerminalExpression Eine Klasse, die das Ende darstellt

Das Element, das das Ende des Baums darstellt. In diesen Beispieldaten ist dies die Nummer.

TerminalExpression.kt


package interpreter

class TerminalExpression: Expression {
    private var saveToken: String? = null

    override fun interpret(context: Context): Int {
        saveToken = context.token
        context.nextToken()
        return Integer.parseInt(saveToken ?: "0")
    }

    override fun toString(): String {
        return saveToken ?: "0"
    }
}

NonterminalExpression Eine Klasse, die etwas anderes als das Ende darstellt

Das Element, das der Baum verzweigt. In diesen Beispieldaten entsprechen <+> und <-> diesen.

Rechenunterricht

CalcExpression.kt


package interpreter

import java.util.ArrayList

abstract class CalcExpression: Expression {
    protected val numList = ArrayList<Int>()
    protected val list = ArrayList<Expression>()

    override fun interpret(context: Context): Int {
        context.nextToken()
        loop@ while (!context.isEnd) {
            val childExpressions = Expression.getExpression(context.token)
            if (childExpressions == null) {
                context.nextToken()
                break@loop
            } else {
                numList.add(childExpressions.interpret(context))
                list.add(childExpressions)
            }
        }
        return calc()
    }

    abstract fun calc(): Int
    abstract override fun toString(): String
}

Zusatzklasse

PlusNonterminalExpression.kt


package interpreter

/**
 *Zusatz(<+> ~ </+>)
 */
class PlusNonterminalExpression: CalcExpression() {
    override fun calc(): Int {
        var result = numList.first().toInt()
        for (i in 1 until numList.size) {
            result += numList[i]
        }
        return result
    }

    override fun toString(): String {
        return "+$list"
    }
}

Subtraktionsklasse

MinusNonterminalExpression.kt


package interpreter

/**
 *Subtraktion(<-> ~ </->)
 */
class MinusNonterminalExpression: CalcExpression() {
    override fun calc(): Int {
        var result = numList.first().toInt()
        for (i in 1 until numList.size) {
            result -= numList[i]
        }
        return result
    }

    override fun toString(): String {
        return "-$list"
    }
}

Multiplikationsklasse

MultiplicationExpression.kt


package interpreter

/**
 *Multiplikation(<*> ~ </"*>)
 */
class MultiplicationExpression: CalcExpression() {
    override fun calc(): Int {
        var result = numList.first().toInt()
        for (i in 1 until numList.size) {
            result *= numList[i]
        }
        return result
    }

    override fun toString(): String {
        return "*$list"
    }
}

Divisionsklasse

DivideExpression.kt


package interpreter

class DivideExpression: CalcExpression() {
    override fun calc(): Int {
        var result = numList.first().toInt()
        for (i in 1 until numList.size) {
            result /= numList[i]
        }
        return result
    }

    override fun toString(): String {
        return "/$list"
    }
}

Kontext Kontext / Situation

Context.kt


package interpreter

import java.util.*

class Context(source: String) {
    private val tokens: StringTokenizer = StringTokenizer(source)
    var token: String? = null
        private set

    val isEnd: Boolean
        get() = !tokens.hasMoreElements()

    init {
        nextToken()
    }

    fun nextToken() {
        var token: String? = null
        if (!isEnd) {
            token = tokens.nextToken() //Standard.nextToken()Anruf
        }
        this.token = token
    }
}

Client-Benutzer

Main.kt


package interpreter

import interpreter.Expression.Companion.getExpression

fun main(args: Array<String>) {
    val source = "<+> 1 <-> 2 3 4 5 6 <*> 7 8 </*> 9 </-> 10 11 </> 12 4 <//> </+>"
    val context = Context(source)
    val expression = getExpression(context.token)

    println(expression?.interpret(context))
    println(expression.toString())
}

Ausgabeergebnis

[out-put]
-56
+[1, -[2, 3, 4, 5, 6, *[7, 8], 9], 10, 11, /[12, 4]]

Die Formel und Lösung waren wie erwartet.

Recommended Posts

[Vierergruppe] Design Pattern Learning - Interpreter
[Viererbande] Design Pattern Learning - Singleton
[Viererbande] Design Pattern Learning --Decorator
[Viererbande] Designmuster lernen --Besucher
[Viererbande] Design Pattern Learning - Vermittler
[Viererbande] Designmusterlernen --Iterator
[Viererbande] Designmuster lernen - Fassade
[Viererbande] Design Pattern Learning - Composite
[Viererbande] Designmuster lernen - Prototyp
[Viererbande] Designmuster lernen - Andenken
[Viererbande] Designmuster lernen - Staat
[Viererbande] Design Pattern Learning - Builder
[Viererbande] Designmuster lernen - Brücke
[Viererbande] Designmuster lernen --Proxy
[Viererbande] Design Pattern Learning - Strategie
[Viererbande] Designmuster lernen --Adapter
[Viererbande] Design Pattern Learning - Beobachter
[Viererbande] Designmuster lernen - Befehl
[Viererbande] Designmuster lernen - Fluggewicht
[Viererbande] Designmusterlernen - Abstract Factory
[Viererbande] Designmuster lernen - Kette der Verantwortung
[Viererbande] Design Pattern Learning - Template-Methode
Gang of Four (GoF) -Muster in Python
Entwurfsmuster #Builder
Entwurfsmuster #Adapter
Entwurfsmuster #Decorator
Lernen der Mustererkennung im Video Teil 1 Bereich der Mustererkennung
Entwurfsmuster #Facade
Entwurfsmuster #Strategie
Entwurfsmuster #Proxy
Lernen Sie das Entwurfsmuster "Chain of Responsibility" in Python
Entwurfsmuster #Factory-Methode
Deep Learning 1 Übung des Deep Learning
Entwurfsmuster # Template-Methode