[GO] [Gang of Four] Apprentissage des modèles de conception - Interprétation

Interprète-interprète

** Table des matières ** Ce modèle a mis du temps à comprendre la structure. c'est difficile.

Le modèle pour lequel vous souhaitez générer une arborescence de syntaxe? Ce modèle exprime un groupe de la balise de début à la balise de fin avec un objet. Composite C'est comme analyser en utilisant un modèle et le traiter en groupe.

Objectif

Pour une langue, définissez une expression grammaticale et un interprète qui l'utilise pour interpréter la phrase.

Composant

-AbstractExpression Classe abstraite pour tous les nœuds -TerminalExpression Une classe qui représente la fin -NonterminalExpression Une classe qui exprime autre chose que la fin ・ Contexte Contexte / Situation ・ Utilisateur client

la mise en oeuvre

Implémentez un exemple de programme qui traite les données de quatre règles ayant une structure hiérarchique. <+> ~ </ +> Ajout <-> ~ </-> Soustraction <\ *> ~ </ \ *> Multiplication </> ~ </ /> Diviser

Exemple de données cibles.xml


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

Si vous formatez les exemples de données ci-dessus dans une forme familière, ce sera 1 + (2 --3 --4 --- 5 --6- (7 * 8) -9) + 10 + 11 + (12/4) -56``` est la valeur attendue.

AbstractExpression Classe abstraite pour tous les nœuds

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 Une classe qui représente la fin

L'élément qui est la fin de l'arbre. Dans cet exemple de données, c'est le nombre.

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 Une classe qui représente autre chose que la fin

L'élément que l'arbre ramifie. Dans cet exemple de données, <+> et <-> lui correspondent.

Classe arithmétique

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
}

Classe d'addition

PlusNonterminalExpression.kt


package interpreter

/**
 *une addition(<+> ~ </+>)
 */
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"
    }
}

Classe de soustraction

MinusNonterminalExpression.kt


package interpreter

/**
 *soustraction(<-> ~ </->)
 */
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"
    }
}

Classe de multiplication

MultiplicationExpression.kt


package interpreter

/**
 *multiplication(<*> ~ </"*>)
 */
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"
    }
}

Classe de division

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"
    }
}

Contexte Contexte / 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() //la norme.nextToken()Appel
        }
        this.token = token
    }
}

Utilisateur client

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())
}

Résultat de sortie

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

La formule et la solution étaient comme prévu.

Recommended Posts

[Gang of Four] Apprentissage des modèles de conception - Interprétation
[Gang of Four] Apprentissage des modèles de conception --Singleton
[Gang of Four] Apprentissage des modèles de conception - Décorateur
[Gang of Four] Apprentissage des modèles de conception - Visiteur
[Gang of Four] Apprentissage des modèles de conception - Médiateur
[Gang of Four] Apprentissage des modèles de conception - Itérateur
[Gang of Four] Apprentissage des modèles de conception - Façade
[Gang of Four] Apprentissage des modèles de conception - Composite
[Gang of Four] Apprentissage des modèles de conception - Prototype
[Gang of Four] Apprentissage des modèles de conception --Mémento
[Gang of Four] Apprentissage des modèles de conception - État
[Gang of Four] Apprentissage des modèles de conception - Constructeur
[Gang of Four] Apprentissage des modèles de conception - Pont
[Gang of Four] Apprentissage des modèles de conception - Proxy
[Gang of Four] Apprentissage des modèles de conception - Stratégie
[Gang of Four] Apprentissage des modèles de conception - Adaptateur
[Gang of Four] Apprentissage des modèles de conception --Observer
[Gang of Four] Apprentissage des modèles de conception - Commande
[Gang of Four] Apprentissage des modèles de conception - Poids du vol
[Gang of Four] Apprentissage des modèles de conception - Usine abstraite
[Gang of Four] Apprentissage des modèles de conception - Chaîne de responsabilité
[Gang of Four] Apprentissage des modèles de conception - Méthode du modèle
Modèles Gang of Four (GoF) en Python
Modèle de conception #Builder
Modèle de conception #Adapter
Modèle de conception #Decorator
Apprentissage de la reconnaissance de formes en vidéo Partie 1 Champ de reconnaissance de formes
Modèle de conception #Facade
Modèle de conception #Strategy
Modèle de conception #Proxy
Apprenez le modèle de conception «Chaîne de responsabilité» en Python
Design Pattern #Factory, méthode
Deep learning 1 Pratique du deep learning
Design Pattern #Template, méthode