2017-08-10 5 views
1

Je suis en train d'écrire une petite notation de dés (par exemple « 2d6 », où 2 est le count et 6 est la matrice size) analyseur en utilisant la bibliothèque elm-tools/parser.Parsing notation de dés avec Elm

Une expression doit être sous la forme

[int] "d" int 

mais je ne peux pas comprendre pour analyser l'option leader int (qui si elle est manquante par défaut 1).

Jusqu'à présent, je suis venu avec ceci:

import Parser exposing (..) 


type alias Roll = 
    { count : Int 
    , size : Int 
    } 


die : Parser Int 
die = 
    succeed identity 
     |. keyword "d" 
     |= int 

et je voudrais l'analyseur pour retourner un Roll sur une analyse syntaxique réussie, mais je ne suis pas sûr de savoir comment procéder.

Je devine que je vais devoir utiliser oneOf, mais je ne sais pas comment.

Malheureusement, je ne trouve pas de bons exemples d'utilisation de cette bibliothèque.

Répondre

0

Merci à @ réponse du Tchad (https://stackoverflow.com/a/45620875/96233), je l'ai eu à travailler avec ceci:

type alias Dice = 
    { count : Int 
    , size : Int 
    } 


dice : Parser Dice 
dice = 
    succeed Dice 
     |= count 
     |. spaces 
     |. keyword "d" 
     |. spaces 
     |= integer 


count : Parser Int 
count = 
    oneOf 
     [ integer |> andThen succeed 
     , succeed 1 
     ] 


integer : Parser Int 
integer = 
    keep oneOrMore isDigit 
     |> andThen 
      (\s -> 
       case String.toInt s of 
        Ok value -> 
         succeed value 

        Err err -> 
         fail err 
      ) 


spaces : Parser() 
spaces = 
    ignore zeroOrMore (\c -> c == ' ') 
+0

Cette réponse [ne pas analyser l'exemple original que vous avez donné de "" 2d6 "'] (https://ellie-app.com/3YVLMkCqM6ra1/0), puisque 'int' échoue si elle frappe un caractère alphanumérique. Il réussirait cependant si vous aviez un espace après '2'. Avez-vous changé les exigences? –

+0

Non. Je corrige le code maintenant avec un analyseur "integer" "private" au lieu de "int". Il semble que 'int' soit confus sur le' d' parce que c'est un nombre hexadécimal légal. – Ralph

+0

Si la réponse de Tchad vous a aidé, vous devriez le mettre en avant et peut-être l'accepter comme la réponse la plus utile. – rubystallion

2

Vous pouvez d'abord écrire un analyseur qui analyse le cas échéant un entier et si rien n'est consommé, puis retourner une valeur par défaut:

optionalInt : Int -> Parser Int 
optionalInt default = 
    keep zeroOrMore Char.isDigit 
     |> andThen 
      (\str -> 
       case str of 
        "" -> 
         succeed default 

        digits -> 
         case String.toInt digits of 
          Ok val -> 
           succeed val 

          Err err -> 
           fail err 
      ) 

Maintenant, vous pouvez utiliser que l'analyseur pour créer un analyseur syntaxique pour Roll:

roll : Parser Roll 
roll = 
    succeed Roll 
     |= optionalInt 1 
     |. keyword "d" 
     |= int 
+0

Correcte sur 'count' et' size'. Je vais mettre à jour ma question pour clarifier. – Ralph

+0

Merci, j'ai supprimé ma déclaration à propos de l'ambiguïté –