2013-10-08 2 views
0

J'écris l'outil de romanisation en utilisant les combinateurs de modèles de Scala.Combinateur d'analyseur correspondant sur la carte

Dans l'un des analyseurs, je veux pouvoir faire correspondre un ensemble de valeurs de chaîne et les transformer en valeurs correspondantes. A savoir, j'utilise Map [String, String] pour traduire entre ces valeurs, mais je n'ai pas trouvé de moyen de faire correspondre les clés de la map sans utiliser d'expression régulière séparée.

object Transliteration extends RegexParsers { 
    private[text] val diphthongsMap = Map(
    "ай" -> "ay", 
    "ей" -> "ey", 
    "ий" -> "iy", 
    "ой" -> "oy", 
    "уй" -> "uy", 
    "ый" -> "yi", 
    "эй" -> "ey", 
    "юй" -> "yuy", 
    "яй" -> "yay" 
) 

def diphthong: Parser[String] = 
    """ай|ей|ий|ой|уй|ый|эй|юй|яй""".r ^^ { diphthongsMap(_) } 

def text: Parser[String] = 
    rep1(notSymbols, extendedWord) ^^ { _.mkString } 

[... bunch of other parsers ...] 

    def translatePhrase(phrase: String): String = 
    parseAll(text, phrase).get 
} 

Puis-je exclure complètement une expression régulière explicite? Peut-être écrire personnalisé Parser?

EDIT: Je n'étais pas tout à fait clair que je veux juste moyen plus efficace de codage méthode diphthong sans hardcode, pas réécriture toute la logique du programme.

Répondre

0

Un analyseur personnalisé n'est probablement pas nécessaire. Une solution consiste à se replier sur la carte:

def romanize(cyrillicString: String) = 
    diphthongsMap.foldLeft(cyrillicString) { 
    case (s, (from, to)) => s.replace(from, to) 
    } 

bien que cette solution est très efficace, avec un temps d'exécution approximatif de O (N^2), bien que pourrait être acceptable d'utiliser pour le texte plus court, que le coût de la mise en place d'un analyseur ou d'une regex peut être amortie.

Questions connexes