tpolecat / atto Goto Github PK
View Code? Open in Web Editor NEWfriendly little parsers
License: MIT License
friendly little parsers
License: MIT License
I wrote this. Would like it to be part of the library? maybe a separate module?
[info] ! Combinator.choice/1: Falsified after 90 passed tests.
[info] > ARG_0: "枇噻㷻讃"
[info] > ARG_1: ""
[info] > ARG_2: "\u0000"
[info] > ARG_2_ORIGINAL: "얐꽭ḋ廧뀎陏ၢ茁迏ἵ䝨쑥醹黜㱩隢ଧꜾ㹉乬䙗⫑뼂ữ॥鈘䇏蠵ܺ漽탳蜥礵㓹䉔눎只睃绪㚱뽈ి蹈쌁쳪鶙ꝺ愛ꄒ늾ᶰ榉泆⑦캳蔅௯抡⦡喝ᥡ讔ᅄ벎ꎏ誹ᑁ涝寣㒿ɜ烞ə윕"
Some combinators like SepBy
which return a List
don't need a user-provided NonEmptyListy
; we can just use the one from stdlib. See #29
The tutorial documentation has not been published since #191 which I noticed after exploring fpcomplete.com for a while and then going to make a PR tweak. But this is how we learn!
I remembered that there were some useful atto tut docs, but after the microsite transition I found them a little difficult to locate and probably wouldn't have kept looking for them if I didn't know that they were there somewhere.
Currently it looks like the only real way to get to them from the site is to click on "Documentation" in the top right. For some reason I had assumed that this would take me to the API ScalaDocs, which might just be a me thing. However, I think that at a minimum it would be helpful to link to the tut docs in the readme/index body.
All the derived specializations of bracket
aren't actually lazy in their argument when the generated parser is finally applied to some string. This prevents me from writing mutually recursive parsers that make use of any of these specializations of bracket
as they will promptly enter an infinite loop when asked to parse any string.
import atto._
import Atto._
def dummyParser: Parser[Char] = {println("activate!"); char('a')}
// Prints activate!
parens(dummyParser).parseOnly("notparentheses")
def myParens[A](p: => Parser[A]): Parser[A] =
bracket(char('('), p, char(')')) // Notice the absence of named
// Does not print anything
myParens(dummyParser).parseOnly("notparentheses")
Current import: "org.tpolecat" %% "atto-core" % "0.4.2"
Example code:
lazy val exprBad: Parser[Int] = eParensBad | eLiteralInt
lazy val eParensBad: Parser[Int] = char('(') *> many(whitespace) *> exprBad <* many(whitespace) <* char(')')
lazy val exprGood: Parser[Int] = eParensGood | eLiteralInt
lazy val eParensGood: Parser[Int] = {
for {
_ <- char('(')
_ <- many(whitespace)
e <- exprGood
_ <- many(whitespace)
_ <- char(')')
} yield (e)
}
lazy val eLiteralInt: Parser[Int] = int
def makeItCrash = exprBad.parse("5").done
def worksFine = exprGood.parse("5").done
scala> worksFine
res0: atto.ParseResult[Int] = Done(,5)
scala> makeItCrash
java.lang.StackOverflowError
<stacktrace bouncing between exprBad and eParensBad>
If the string is "-" then it fails. Ditto with either/left. Low probability so it has only happened once.
get test coverage up!
It'd be nice if there weren't 2 combinators named the same thing.
Ideas for the ParserOps 'as':
withName
asName
named
The ^^^ combinator in ParserOps is just a duplicate of >| in Functor, but it's confusing because Applicative has a ^^^ combinator as well.
It seems reasonable that Parsers should be covariant in their type argument, given values are only output
I am using Atto to parse Uris
in Hammock, but since it doesn't compile to ScalaJS, I cannot merge it yet.
It would be really cool that we could use Atto in scala JS projects.
It appears the sources for atto cannot be located by either sbt-ctags or sbt-sublime.
I'm running SBT 0.13.5 and trying to get atto 0.3 on scala 2.11.
Both of these utilities find org.spire-math.spire, but for some reason they can't find the sources for atto.
There is no termination, once the compiler starts on
val la = many(takeWhile(c => c != 'r')).parseOnly("awe")
.
streams 0.5a is out so we can turn it back on
there are a lot of corner cases depending on chunking of input, so it would be really nice to have fuzz tests for streams
The numeric parsing methods in the JDK stubs delegate to parseInt
, etc., in Javascript which is not as lenient as the parsers on the JVM. In particular c.isDigit
doesn't guarantee that Integer.parseInt
will work. See gemini-hlsw/gem#201
Combinators like many1, sepBy1 should return NEL instances so callers don't need to worry about calling .headOption.
copy settings from doobie
I am using the cats compat lib, and cannot get the stringOf operator to compile. I am getting two errorr:
Error:(7, 21) could not find implicit value for evidence parameter of type atto.compat.NonEmptyListy[F]
term <- stringOf(letter)
Error:(7, 21) not enough arguments for method stringOf: (implicit evidence$1: atto.compat.NonEmptyListy[F])atto.Parser[String].
Unspecified value parameter evidence$1.
term <- stringOf(letter)
the error can be reproduced with this code:
import atto._, Atto._, atto.compat.cats._
object mvp extends App {
val parser = for {
term <- stringOf(letter)
} yield term
}
build.sbt:
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"org.typelevel" %% "cats" % "0.7.2",
"org.tpolecat" %% "atto-core" % "0.5.0-SNAPSHOT",
"org.tpolecat" %% "atto-compat-cats" % "0.5.0-SNAPSHOT"
)
resolvers ++= Seq(
"atto" at "https://oss.sonatype.org/content/repositories/snapshots/"
)
How can I provide this evidence? or should the compat library be handling this?
I'm trying to do something a little funky with Atto by using it from JRuby, and I'm running into a strange issue.
Trying to run the readme example of parsing a list of integers separated by whitespace, but when calling
Parser.parse(Atto.sepBy(Atto.int, Atto.spaceChar), "123 45 6"), it tells me I'm missing an argument (2 for 3) in sepBy, whose signature in the scala code appears to only require 2 arguments. When I try providing different kinds of arguments to the third slot, it suggests i get something coercible to atto.compat.NonEmptyListy.
When i try providing NonEmptyList like inputs into the 3rd argument,
Atto.sepBy(Atto.int, Atto.spaceChar, NonEmptyList(1)), it tells me that I'm missing a method 'cons'. It suggests something about overloading to atto.compat.NonEmptyListy, or scala.Function0, but I'm stuck unable to figure out what the 3rd argument should be. When I look in the code for Atto, I notice there is an implicit Functor in ParseResultInstances. Is there some sort of Functor i should be passing as the third argument to let it accumulate on? or some kind of 'empty parser', like the Ok parser?
I understand that this is not the usual use of this library, but I would very much appreciate any help you can give.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.