scala: accessing parser stack

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

scala: accessing parser stack

David Pennell
I have a grammar that needs to distinguish between signed and unsigned integers.  The AST does not need to distinguish them and I'd rather not introduce an extra case object.

See the fragment below:

abstract class AstNode
case class IntegerNode(value:Int) extends AstNode

def UnsignedInteger:Rule1[IntegerNode] = rule {oneOrMore("0"-"9") ~>
     (s => IntegerNode(Integer.parseInt(s))) }          // this works fine
       
       
def SignedInteger:Rule1[IntegerNode] = rule {
          group(optional("-") ~> (s => s!="-") ~ UnsignedInteger) ~~>
          (/* Can I map the Boolean and IntegerNode into a new IntegerNode without using withContext()?  */}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: scala: accessing parser stack

David Pennell
OK, I figured it out:

abstract class AstNode
case class IntegerNode(value:Int) extends AstNode

def UnsignedInteger:Rule1[IntegerNode] = rule {oneOrMore("0"-"9") ~>
     (s => IntegerNode(Integer.parseInt(s))) }  

def SignedInteger:Rule1[IntegerNode] = rule {
     (optional("-" ~> (s => if (s=="-") -1 else 1) ~ UnsignedInteger)) ~~>
     (o => IntegerNode(o.get._1*o.get._2.value))
}

Is there any condition under which I'll need to deal with None in the action?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: scala: accessing parser stack

David Pennell
Please ignore that last post.  Something similar to the following was my first attempt.  I'm still learning Scala and forgot the () around the arguments to the action function...  Now I know.

abstract class AstNode
case class IntegerNode(value:Int) extends AstNode

def UnsignedInteger:Rule1[IntegerNode] = rule {oneOrMore("0"-"9") ~>
     (s => IntegerNode(Integer.parseInt(s))) }  

def SignedInteger:Rule1[IntegerNode] = rule {
     (optional("-") ~> (s => if (s=="-") -1 else 1) ~ UnsignedInteger) ~~>
          ((a,b) => IntegerNode(a*b.value))
}

and this one is arguably better:

def SignedInteger:Rule1[IntegerNode] = rule {
  (optional("-") ~> ((s) => s) ~ UnsignedInteger) ~~> ((s,u) => if (s=="-") IntegerNode(-u.value) else u)
}

I'm curious why I couldn't just use ~~> after optional("-") and then use 's exists' in the action function.  Doing so results in a "missing parameter type".  I would have expected Option[String].
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: scala: accessing parser stack

mathias
Administrator
David,

why don't you do something like this:

        def SignedInt = rule { group(optional("-") ~ Digits) ~> (_.toInt) }

        def UnsignedInt = rule { Digits ~> (_.toInt) }

        def Digits = rule { oneOrMore(Digit) }

        def Digit = rule { "0" - "9" }

> I'm curious why I couldn't just use ~~> after optional("-") and then use 's exists' in the action function.  Doing so results in a "missing parameter type".  I would have expected Option[String].

`optional("-")` is a Rule0, it doesn't produce any value on the value stack.

HTH and cheers,
Mathias

---
[hidden email]
http://www.parboiled.org

On 23.01.2012, at 23:24, David Pennell [via parboiled users] wrote:

> Please ignore that last post.  Something similar to the following was my first attempt.  I'm still learning Scala and forgot the () around the arguments to the action function...  Now I know.
>
> abstract class AstNode
> case class IntegerNode(value:Int) extends AstNode
>
> def UnsignedInteger:Rule1[IntegerNode] = rule {oneOrMore("0"-"9") ~>
>      (s => IntegerNode(Integer.parseInt(s))) }  
>
> def SignedInteger:Rule1[IntegerNode] = rule {
>      (optional("-") ~> (s => if (s=="-") -1 else 1) ~ UnsignedInteger) ~~>
>           ((a,b) => IntegerNode(a*b.value))
> }
>
> and this one is arguably better:
>
> def SignedInteger:Rule1[IntegerNode] = rule {
>   (optional("-") ~> ((s) => s) ~ UnsignedInteger) ~~> ((s,u) => if (s=="-") IntegerNode(-u.value) else u)
> }
>
> I'm curious why I couldn't just use ~~> after optional("-") and then use 's exists' in the action function.  Doing so results in a "missing parameter type".  I would have expected Option[String].
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/scala-accessing-parser-stack-tp3682846p3683198.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.
> NAML

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: scala: accessing parser stack

David Pennell
See below:

On Tue, Jan 24, 2012 at 3:09 AM, mathias [via parboiled users] <[hidden email]> wrote:
David,

why don't you do something like this:

        def SignedInt = rule { group(optional("-") ~ Digits) ~> (_.toInt) }

        def UnsignedInt = rule { Digits ~> (_.toInt) }

        def Digits = rule { oneOrMore(Digit) }

        def Digit = rule { "0" - "9" }

I elided all the bits of UnsignedInteger that deal with hex and octal to keep the example short.  For context - I'm parsing SQL-2008.  The translation of 1,300 productions from BNF to parboiled was pretty straightforward.  There are a LOT of optional's and nested optional's in this language.
 

> I'm curious why I couldn't just use ~~> after optional("-") and then use 's exists' in the action function.  Doing so results in a "missing parameter type".  I would have expected Option[String].

`optional("-")` is a Rule0, it doesn't produce any value on the value stack.

Ah,  I was looking at (e.g.)

(SomeRule[Rule1[AnAstNode]] ~ optional(anotherRule[Rule1[AnotherAstNode]]) ~~> ((arg1[AnAstNode],  arg2[Some(AnotherAstNode)]) => ....)

and not realizing that you can only get at the optional as part of a rule that produces results on the stack.
 

HTH and cheers,
Mathias

---
[hidden email]
http://www.parboiled.org


On 23.01.2012, at 23:24, David Pennell [via parboiled users] wrote:

> Please ignore that last post.  Something similar to the following was my first attempt.  I'm still learning Scala and forgot the () around the arguments to the action function...  Now I know.
>
> abstract class AstNode
> case class IntegerNode(value:Int) extends AstNode
>
> def UnsignedInteger:Rule1[IntegerNode] = rule {oneOrMore("0"-"9") ~>
>      (s => IntegerNode(Integer.parseInt(s))) }  
>
> def SignedInteger:Rule1[IntegerNode] = rule {
>      (optional("-") ~> (s => if (s=="-") -1 else 1) ~ UnsignedInteger) ~~>
>           ((a,b) => IntegerNode(a*b.value))
> }
>
> and this one is arguably better:
>
> def SignedInteger:Rule1[IntegerNode] = rule {
>   (optional("-") ~> ((s) => s) ~ UnsignedInteger) ~~> ((s,u) => if (s=="-") IntegerNode(-u.value) else u)
> }
>
> I'm curious why I couldn't just use ~~> after optional("-") and then use 's exists' in the action function.  Doing so results in a "missing parameter type".  I would have expected Option[String].
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/scala-accessing-parser-stack-tp3682846p3683198.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.
> NAML




If you reply to this email, your message will be added to the discussion below:
http://users.parboiled.org/scala-accessing-parser-stack-tp3682846p3684070.html
To unsubscribe from scala: accessing parser stack, click here.
NAML

Loading...