2017-06-04 2 views

Répondre

1

L'API est pas grand: https://static.javadoc.io/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.6/scala/util/parsing/combinator/Parsers.html et https://static.javadoc.io/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.6/scala/util/parsing/combinator/Parsers $ Parser.html

En regardant à travers cela, il semble que la réponse est pas, il n'y a aucun moyen de le faire plus simplement. Cette façon ne semble pas mal du tout, cependant.

+0

Eh oui, il a l'air si: (comme pour la solution actuelle, il peut être compliqué lorsque le nombre de ces conditions augmente. – ikryvorotenko

2

I réalisé en combinant ~ et | parseurs dans l'analyseur personnalisé nommé $

Il ressemble à ~

trait ExtParsers extends JavaTokenParsers { 
    def unordered[T,U](tp: Parser[T], tu: Parser[U]): Parser[$[T, U]] = 
    tp ~ tu ^^ { case (x ~ y) => $(x, y) } | tu ~ tp ^^ 
     { case (x ~ y) => $(y, x) } 

    case class $[+a, +b](_1: a, _2: b) 

    implicit class ExtParser[+T](val parser: Parser[T]) { 
    def $[U](tu: Parser[U]): Parser[$[T, U]] = unordered(parser, tu) 
    } 
} 

object MyParser extends ExtParsers { 
    def unord: Parser[String] = 
    (ident $ stringLiteral $ wholeNumber $ floatingPointNumber) ^^ { 
     case (id $ sl $ wn $ fpn) => 
     s"ident=$id string=$sl int=$wn float=$fpn" 
    } 
} 

Et passé le test:

@Test def test() { 
    val expected = "ident=value string=\"test\" int=10 float=10.99" 

    assertEquals(expected, 
     MyParser.parseAll(MyParser.unord, "value \"test\" 10 10.99").get) 

    assertEquals(expected, 
     MyParser.parseAll(MyParser.unord,"\"test\" value 10 10.99").get) 

    assertEquals(expected, 
     MyParser.parseAll(MyParser.unord,"10 value \"test\" 10.99").get) 
    }