The Artima Developer Community
Sponsored Link

Scala Buzz
Mini-Parsers to the rescue

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Eric Torreborre

Posts: 36
Nickname: etorreborr
Registered: Oct, 2007

Eric Torreborre is Tokyo programmer in love with Scala (and the author of the specs framework)
Mini-Parsers to the rescue Posted: May 6, 2010 5:22 AM
Reply to this message Reply

This post originated from an RSS feed registered with Scala Buzz by Eric Torreborre.
Original Post: Mini-Parsers to the rescue
Feed Title: A++ [Eric Torreborre's Blog]
Feed URL: http://etorreborre.blogspot.com/feeds/posts/default/-/scala
Feed Description: This blog is "Software on my mind" and I try to write one post a month. As Scala is a lot on my mind recently, you can expect more Scala posts quite soon!
Latest Scala Buzz Posts
Latest Scala Buzz Posts by Eric Torreborre
Latest Posts From A++ [Eric Torreborre's Blog]

Advertisement
An example of curryfication

I'm implementing a reasonably complex algorithm at the moment with different transformation phases. One transformation is a "curryfication" of some terms to be able to transform some expressions like:

f(a, b, c)

to

.(.(.(f, a), b), c)

Being test-compulsive, I want to be able to test that my transformation works. Unfortunately the data structures I'm dealing with are pretty verbose in my tests.

One of my specs examples was this:

"A composed expression, when curried" should {
"be 2 successive applications of one parameter" +
"when there are 2 parameters to the method expression" in {
ComposedExp(MethodEx(method), const :: arb :: Nil).curryfy must_==
Apply(Apply(Curry(method), Curry(const)), Curry(arb))
}
}

But Apply(Apply(Curry(method), Curry(const)), Curry(arb))) is really less readable than .(.(method, const), arb).

With the help of a mini-parser

So I thought that I could just write a parser to recreate a "Curried" expression from a String.

A first look at the Scala 2.8.0 Scaladoc(filter with "parser") was a bit scary. Especially because my last parser exercise was really a long time ago now.

But no, parser combinators and especially small, specific parsers like the one I wrote are really straightforward:

object CurriedParser extends JavaTokenParsers {
val parser: Parser[Curried] = application | const
val const = ident ^^ { s => Curry(s) }
val application = (".(" ~> parser) ~ (", " ~> const <~ ")") ^^ { case a ~ b =>
Apply(a, b)
}
def fromString(s: String): Curried = parser.apply(new CharSequenceReader(s)).get
}

In the snippet above I declare that:

  • my parser is returns a Curried object

  • my parser is either an application or a constant (with the | operator)

  • a constant is a Java identifier (because of the inheritance of the JavaTokenParsers trait)

  • a constant should be transformed to a Curry object

  • an application is composed of two parts (separated by ~). The first part is something that can be parsed with my parser (i.e. an application or a constant). The second part is a constant. And in each part I get rid of the syntactic elements (using a "discard" operator <~ or ~>)

  • once an application is parsed, part 1 and part 2 must be used to build an Apply object

  • the fromString method simply passes a String to the parser and gets the result



I have to say that this parser is really rudimentary. It doesn't handle errors in the input text, there needs to be a space after the comma, and so on.

Yet it really fits my testing purpose for a minimum amount of development time.

Open question (for later,...)

The only question that is open for me at the moment is this one: is there a way to define algebraic datatypes in Scala so that:
  • each class has a proper toString representation (as with case classes)

  • there is an implicit parser that is able to reconstruct the hierarchy of objects from the string representation of the tree

Read: Mini-Parsers to the rescue

Topic: Scala Stream Fusion and Specialization, Part 2 Previous Topic   Next Topic Topic: Using types to help refactor

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use