Analyseurs syntaxiques Scala - Distinguer entre les chaînes numériques et les chaînes variables

StackOverflow https://stackoverflow.com/questions/256694

  •  05-07-2019
  •  | 
  •  

Question

Je fais des exercices d'analyse syntaxique du combinateur Cay Horstmann. Je me demande quel est le meilleur moyen de distinguer les chaînes représentant des nombres et les chaînes représentant des variables dans une instruction de correspondance:

def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
    case a: wholeNumber  => Number(a.toInt)
    case a: String => Variable(a)
}

La deuxième ligne à cet endroit, & "; cas a: nom entier"! & "; n'est pas légal. J'ai pensé à une expression rationnelle, mais je n'ai pas trouvé le moyen de la faire fonctionner avec & "Case &";.

.
Était-ce utile?

La solution

Je le séparerais un peu et je placerais l’analyse de cas dans le |. C’est l’un des avantages des combinateurs et de l’analyse LL (*) en général:

def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
                               | "(" ~> expr <~ ")" 
                               | ident ^^ { Variable(_) } )

Je m'excuse si vous n'êtes pas familiarisé avec la syntaxe de soulignement. En gros, cela signifie simplement que & "Substituer le n paramètre à la valeur de fonction englobante &"; Ainsi, { Variable(_) } est équivalent à { x => Variable(x) }.

Les opérateurs ~> et <~ au lieu de ~ sont un autre élément magique de la syntaxe. Ces opérateurs signifient que l'analyse de ce terme doit inclure la syntaxe des deux parenthèses, mais le résultat doit être uniquement déterminé par le résultat de expr. Ainsi, "(" ~> expr <~ ")" correspond exactement à la même chose que "(" ~ expr ~ ")", mais aucune analyse de cas supplémentaire n'est nécessaire pour extraire la valeur de résultat interne de <=>.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top