This page is no longer maintained — Please continue to the home page at www.scala-lang.org

additional checks in parser combinator

2 replies
Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Hi all,

I have just written my first non-trivial parser combinator and am feeling a sense of achievement!

In addition to checking that the input string parses correctly I am also doing some additional checking. For e.g., my grammar allows you to specify the fully qualified name of a Java class. Obviously, a simple pattern-matching is not all that is needed to validate the input string, having matched the pattern I also need to ensure that the fully qualified name is in fact a real class (assuming of course that the JVM's classpath has already been configured correctly to include the class).

So, the parser that matches class names does so using Class.forName(). I have implemented it as an instance of Parser[Class]. It works perfectly when given a valid fully qualified classname.

However, when given an invalid name it results in a ClassNotFoundException rather than a ParseResult of type Error. I understand why it does this, just don't know how to fix it. Currently I've got a try/catch block around the root parser invocation to catch the exception and do something - but I'd much rather have a ParseResult and so be able to give better error feedback around the exact position where the parse failed.

Is this possible?

Regards,
Ishaaq
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: additional checks in parser combinator


On Wed, Feb 18, 2009 at 4:23 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
Hi all,

I have just written my first non-trivial parser combinator and am feeling a sense of achievement!

In addition to checking that the input string parses correctly I am also doing some additional checking. For e.g., my grammar allows you to specify the fully qualified name of a Java class. Obviously, a simple pattern-matching is not all that is needed to validate the input string, having matched the pattern I also need to ensure that the fully qualified name is in fact a real class (assuming of course that the JVM's classpath has already been configured correctly to include the class).

So, the parser that matches class names does so using Class.forName(). I have implemented it as an instance of Parser[Class]. It works perfectly when given a valid fully qualified classname.

However, when given an invalid name it results in a ClassNotFoundException rather than a ParseResult of type Error. I understand why it does this, just don't know how to fix it. Currently I've got a try/catch block around the root parser invocation to catch the exception and do something - but I'd much rather have a ParseResult and so be able to give better error feedback around the exact position where the parse failed.

Is this possible?

Sure:
object P extends Parsers {   type Elem = Char     lazy val digit = elem("digit", c => c >= '0' && c <= '9')     lazy val p: Parser[String] = rep(digit) ^? {    case x :: xs if x >= '3' => (x :: xs).mkString   }}
You'll note that this will only succeed if the first character is >= '3'.  If not, the Parser will fail.
So, you'd use ^? rather than ^^ and use a guard in your partial function (pattern) to test if the class actually exists.
Does this answer your question?
 


Regards,
Ishaaq



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: additional checks in parser combinator
Great! Thanks for that. I ended up using the overloaded version of ^? that takes an error message as well so that I could specify my own message.

Ishaaq

2009/2/19 David Pollak <feeder.of.the.bears@gmail.com>


On Wed, Feb 18, 2009 at 4:23 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
Hi all,

I have just written my first non-trivial parser combinator and am feeling a sense of achievement!

In addition to checking that the input string parses correctly I am also doing some additional checking. For e.g., my grammar allows you to specify the fully qualified name of a Java class. Obviously, a simple pattern-matching is not all that is needed to validate the input string, having matched the pattern I also need to ensure that the fully qualified name is in fact a real class (assuming of course that the JVM's classpath has already been configured correctly to include the class).

So, the parser that matches class names does so using Class.forName(). I have implemented it as an instance of Parser[Class]. It works perfectly when given a valid fully qualified classname.

However, when given an invalid name it results in a ClassNotFoundException rather than a ParseResult of type Error. I understand why it does this, just don't know how to fix it. Currently I've got a try/catch block around the root parser invocation to catch the exception and do something - but I'd much rather have a ParseResult and so be able to give better error feedback around the exact position where the parse failed.

Is this possible?

Sure:
object P extends Parsers {   type Elem = Char     lazy val digit = elem("digit", c => c >= '0' && c <= '9')     lazy val p: Parser[String] = rep(digit) ^? {    case x :: xs if x >= '3' => (x :: xs).mkString   }}
You'll note that this will only succeed if the first character is >= '3'.  If not, the Parser will fail.
So, you'd use ^? rather than ^^ and use a guard in your partial function (pattern) to test if the class actually exists.
Does this answer your question?
 


Regards,
Ishaaq



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland