Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Bartosz Szmit
    @bszmit

    Hi ;)
    Is it possible to implement arithmetic grammar WITH substitution and division in atto?
    Grammar like this one (I know it's left recursive)

    <Exp> ::= <Exp> + <Term> | <Exp> - <Term> | <Term>
    <Term> ::= <Term> * <Factor> | <Term> / <Factor> | <Factor>
    <Factor> ::= int | ( <Exp> )

    So far I have only seen grammars without substitution and division. They require left-associativity and I guess it's a reason they are often left out in examples.

    Rob Norris
    @tpolecat
    No, not in that form. Recursive grammars end up being tricky.
    Partly because they're just tricky, partly because atto is derived from Haskell code so it's stricter than it should be in some places, partly because of bugs.
    Rob Norris
    @tpolecat
    A pattern that works iirc is, expr = listof(addend + addened) and then addend = listof(factor * factor) and factor = int | (expr). So it only recurses in the rightmost position. It's been a while, sorry. There should really be an example.
    Bartosz Szmit
    @bszmit
    I think this pattern will work for me. Thank you very much :)
    Rob Norris
    @tpolecat
    Good luck. It's treacherous. Make sure they're all lazy vals because they'll reference each other.
    jportway
    @jportway
    Hi - this is proba bly a stupid question, but i can't find an example anywhere - is there a way to match all text until something that matches another parser is encountered? I have to decode something like this:
    BLAH BLAH This is some 42 text 123\n
    I need to extract it like this:
    [BLAH][BLAH][This is some 42 text][123]
    I can extract the BLAHs easily, and I can write a parser that will match the number at the end :[whitespace number \n] but I don't know how to extract the text in between because I can only delimit that lazily - after I have found the number token at the end. This seems like it should be easy, but I can't find any documentation anywhere on how to do it.
    Rob Norris
    @tpolecat
    Hm, yeah it's not going to backtrack that way.
    jportway
    @jportway
    this seems like it must be a very common case - i'm really surprised there isn't a way to deal with it
    is this where i'd use some kind of recursive parser? I can't find any documentation about how to do that, or what it would be for...
    Rob Norris
    @tpolecat
    You could do (stringOf(elem(!_.isDigit)).token ~ int.token).many1 and then post-process the result into (String, Int). Not great.
    jportway
    @jportway
    ok - so it seems like Atto just isn't intended to do this kind of thing then? It looks like i might save some pain by just trying to stop forcing it into doing something it's not supposed to. Thanks for your help
    Rob Norris
    @tpolecat
    It's an old port of a Haskell library and I admit I have had to figure out its behavior on the fly.
    jportway
    @jportway
    :)
    the manyUntil parser seems to almost do the trick, but it discards results of the delimiting parser. I might try hacking at it a bit
    Rob Norris
    @tpolecat
    In principle you want parsers to emit every possible parse, but in practice that's really inefficient. So you end up with various compromises.
    Joseph Hajduk
    @josephhajduk
    Thanks for the awsome library. Is there a nicer way to do parser.filter(k => Try(k.toInt).isSuccess).map(_.toInt) ?
    Rob Norris
    @tpolecat
    You could use the int parser?
    Joseph Hajduk
    @josephhajduk
    I mean for the general case where you can have an exception in your map, and want the parser to roll back rather then throw the exception.
    Rob Norris
    @tpolecat
    I would use flatMap there I think.
    Salvador Fandiño
    @salva
    Hi, I am writting a parser for file system glob expressions, the code is here: https://github.com/salva/scala-glob/blob/master/src/main/scala/com/github/salva/scala/glob/GlobParser.scala
    The issue I am facing is that when I try to parse an string with it, it throws a stack overflow exception
    The parser is recursive because it has to handle nested curly brackets
    Salvador Fandiño
    @salva
    Any idea about what I am doing wrong?
    Paul Snively
    @paul-snively
    Turning an HList of Parsers and a function whose arguments are of the Parsers' types into a function taking a String to an Either of Throwable or the function's result type:
    
    import cats._, implicits._                // Be very Cats-centric
    import cats.sequence._
    
    import shapeless.{ HList, HNil }          // Only what we need from Shapeless
    import shapeless.ops.function.FnToProduct
    import shapeless.ops.hlist.IsHCons
    import shapeless.UnaryTCConstraint._
    
    import atto._, Atto._
    
    object command {
      implicit class Command[P <: HList : IsHCons : *->*[Parser]#λ](parsers: P) {
        def command[InF, InL <: HList, R](f: InF)
          (implicit
            fntop: FnToProduct.Aux[InF, InL => R],
            seq:   Sequencer.Aux[P, Parser, InL]
          ): String => Either[Throwable, R] = { s =>
            val parser = parsers.sequence
            val args   = parser.parseOnly(s).either.leftMap(s => new RuntimeException(s))
            args.map(a => fntop(f)(a))
          }
      }
    
      def describe(name: String, age: Int, height: Double) = {
        println(s"name: $name")
        println(s"age: $age")
        println(s"height: $height")
        42
      }
    
      val descCommand = (token(stringOf1(letter)) :: token(int) :: token(double) :: HNil).command(describe _)
    
      def main(args: Array[String]): Unit = descCommand("Paul 55 6.25").fold(_ => (), _ => ())
    }
    Thanks to Atto and Kittens.
    @salva: That gives me a 404.
    Rob Norris
    @tpolecat
    neato :-)
    Paul Snively
    @paul-snively
    I hadn’t encountered FnToProduct before. Kinda blows my mind that we can say “I’d like the argument list and result type of an arbitrary function, please.”
    And Kittens gives us Cats typeclasses for HList. Bam!
    “It has been 0 days since the answer was traverse/sequence.”
    Rob Norris
    @tpolecat
    :-)
    Christopher Davenport
    @ChristopherDavenport
    At some point I want to do this for some ridiculous tracing context, but don't have the time.
    Paul Snively
    @paul-snively
    Right? Arbitrary transformations of arbitrary Kleislis...
    Ryan Heins
    @RyanHeins

    Hello, I'm new here. I have a question about atto, and I already know the answer is traverse, but traverse doesn't seem to be defined. What I want is

    val myParser: Parser[MyType] = ???
    
    val myThings: ParseResult[List[MyType]] = List("thing1", "thing2").traverse(myParser.parse)

    Since I have a list of strings to parse and not just a single string I can't get sequence to work for me.

    Christopher Davenport
    @ChristopherDavenport
    Do you have cats.implicits._ in scope?
    Ryan Heins
    @RyanHeins
    I do
    Christopher Davenport
    @ChristopherDavenport
    Ah,m ParseResult only ofrms a functor, not an applicative.
    Rob Norris
    @tpolecat
    yeah
    Christopher Davenport
    @ChristopherDavenport
    Try, .traverse(a => myParser.parse(a).either)
    Rob Norris
    @tpolecat
    yeah
    @ List("1","2","3").traverse(int.parseOnly(_).either) 
    res4: Either[String, List[Int]] = Right(List(1, 2, 3))
    
    @ List("1","woozle","3").traverse(int.parseOnly(_).either) 
    res5: Either[String, List[Int]] = Left("Failure reading:bigInt")
    Ryan Heins
    @RyanHeins
    That worked, thanks!
    Christopher Davenport
    @ChristopherDavenport
    Pure is easy, but Not sure how youd implement ap over Partials
    Actually you do both in terms of partial that way you could feed.
    def pure(a: A): ParseReseult[A] = Partial(k: String => Done(k, a))
    def ap(ff: ParseResult[A => B], fa: ParseResult[A] ): ParseResult[B] = case (ff, fa) match {
        case (e@Fail(_,_,_), _) => e
        case (_, e@Fail(_,_,_) => e
        case (Done(s1, f), Done(s2, a) => Done(???, f(a))
        case (Partial(f1), _) => ???
        case (_, Partial(_)) =>  ???
    Christopher Davenport
    @ChristopherDavenport
    Thats tricky, I see why you went with functor
    Wojtek Pituła
    @Krever
    Hey, did anyone of you have a need for a more generic version of atto, where parser abstract over input (so Parser[In, Out])?
    Christopher Davenport
    @ChristopherDavenport
    I have one, gato-parsec. @Krever