J'essaie de définir une grammaire pour les commandes ci-dessous.Scala Parser Token Delimiter Problème
object ParserWorkshop {
def main(args: Array[String]) = {
ChoiceParser("todo link todo to database")
ChoiceParser("todo link todo to database deadline: next tuesday context: app.model")
}
}
La deuxième commande doit être tokenizés comme:
action = todo
message = link todo to database
properties = [deadline: next tuesday, context: app.model]
Quand je lance cette entrée sur la grammaire définie ci-dessous, je reçois le message d'erreur suivant:
[1.27] parsed: Command(todo,link todo to database,List())
[1.36] failure: string matching regex `\z' expected but `:' found
todo link todo to database deadline: next tuesday context: app.model
^
En ce qui concerne Je peux voir qu'il échoue parce que le modèle pour faire correspondre les mots du message est presque identique au modèle pour la clé de la clé de propriété: paire de valeurs, de sorte que l'analyseur ne peut pas dire où le message se termine et la propriété commence. Je peux résoudre ce problème en insistant sur le fait que jeton de départ utilisé pour chaque propriété comme ceci:
todo link todo to database :deadline: next tuesday :context: app.model
Mais je préférerais garder le commandement le plus proche du langage naturel que possible. J'ai deux questions:
Que signifie réellement le message d'erreur? Et comment est-ce que je modifierais la grammaire existante pour travailler pour les chaînes d'entrée données?
import scala.util.parsing.combinator._
case class Command(action: String, message: String, properties: List[Property])
case class Property(name: String, value: String)
object ChoiceParser extends JavaTokenParsers {
def apply(input: String) = println(parseAll(command, input))
def command = action~message~properties ^^ {case a~m~p => new Command(a, m, p)}
def action = ident
def message = """[\w\d\s\.]+""".r
def properties = rep(property)
def property = propertyName~":"~propertyValue ^^ {
case n~":"~v => new Property(n, v)
}
def propertyName: Parser[String] = ident
def propertyValue: Parser[String] = """[\w\d\s\.]+""".r
}
Je pense que vous devriez changer votre syntaxe à quelque chose comme ceci: todo "lien todo à la base de données": date limite: "mardi prochain": contexte: "app.model " – ziggystar
C'est une solution que je veux éviter, car je veux garder la grammaire de Todo aussi proche que possible d'un langage naturel –