- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
additional checks in parser combinator
Thu, 2009-02-19, 01:23
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
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
Thu, 2009-02-19, 03:27
#2
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>
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
On Wed, Feb 18, 2009 at 4:23 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
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?
--
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