Quantcast

Scala Noob Question

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

Scala Noob Question

tsuckow
I'm finally getting back to the parser I was playing with months ago only now porting the limited functionality to Scala. This way I can compare what I had in both and figure out which I like better (So far Scala is winning hands down despite not knowing the language).

One of the things I had done with my Java parser was implement the ability to handle includes on the fly.  To do this I needed to know where in the buffer I was (The position after the end of the include), the filename to include, and the length of the include statement in its entirety (I have to mangle the buffer or backtracking could/will cause infinite include).

My thought for this was put two things on the value stack and then pass both to an action. But I don't know how to do that...

TLDR: I need pop 2 items off the stack for an action.

Snippit:
  case class ASTString(val text: String)
  def Include = rule { IncludeInternal ~> ASTString }
  def IncludeInternal = rule { "include" ~ WhiteSpace ~ SilkString ~ ";" }
  def SilkString = rule { "\"" ~ zeroOrMore(anyOf("abcde")) ~> ASTString ~ "\"" ~ WhiteSpace }

I tried using ~~> with a function taking two parameters as a long shot but it didn't compile :(
Googleing around poprule and reductionrule are really unhelpful.

I am also assuming I need to use withContext somehow so I can get the buffer position.

I am probably missing something fundamental, but any assistance would be appreciated. Also if I have a silly syntax, I wouldn't mind any criticism.

Regards,
Thomas Suckow
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Scala Noob Question

mathias
Administrator
Thomas,

> One of the things I had done with my Java parser was implement the ability to handle includes on the fly.  To do this I needed to know where in the buffer I was (The position after the end of the include), the filename to include, and the length of the include statement in its entirety (I have to mangle the buffer or backtracking could/will cause infinite include).

The key to getting this done is to use get access to the underlying parsing Context as you know them from the java side. The Context has all the "low-level" methods like "getCurrentIndex" that probably want to use for this. There are two ways to get access to the Context from the scala side of parboiled:

- use "pushFromContext", e.g. if you want to put the current parsing index onto the value stack link a "pushFromContext(_.getCurrentIndex)" call into your rule structure
- user the "withContext" wrapper for your parser action functions, for more help search for "withContext" in the mailing list archives

> My thought for this was put two things on the value stack and then pass both to an action. But I don't know how to do that...

A single parser action function can only ever put one object onto the value stack.
Of course, this one object could also be a Tuple...

> I tried using ~~> with a function taking two parameters as a long shot but it didn't compile :(

This works, no problem. You can use "~~>" with a function taking up to 7 parameters. They need to match the types of the topmost objects currently on the value stack at the respective position in the rule structure in order to compile.

The SimpleCalculator1 example (https://github.com/sirthias/parboiled/blob/develop/examples-scala/src/main/scala/org/parboiled/examples/calculators/SimpleCalculator1.scala) shows the "~~>" operator with a function taking two parameters for example.

If you have grammar snippets that don't compile and you don't know why, just post them.
The parboiled for Scala examples assume you already know Scala, so it can probably be a bit confusing for people just starting with the language...

Cheers,
Mathias

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

On 29.07.2011, at 06:01, tsuckow [via parboiled users] wrote:

> I'm finally getting back to the parser I was playing with months ago only now porting the limited functionality to Scala. This way I can compare what I had in both and figure out which I like better (So far Scala is winning hands down despite not knowing the language).
>
> One of the things I had done with my Java parser was implement the ability to handle includes on the fly.  To do this I needed to know where in the buffer I was (The position after the end of the include), the filename to include, and the length of the include statement in its entirety (I have to mangle the buffer or backtracking could/will cause infinite include).
>
> My thought for this was put two things on the value stack and then pass both to an action. But I don't know how to do that...
>
> TLDR: I need pop 2 items off the stack for an action.
>
> Snippit:
>   case class ASTString(val text: String)
>   def Include = rule { IncludeInternal ~> ASTString }
>   def IncludeInternal = rule { "include" ~ WhiteSpace ~ SilkString ~ ";" }
>   def SilkString = rule { "\"" ~ zeroOrMore(anyOf("abcde")) ~> ASTString ~ "\"" ~ WhiteSpace }
>
> I tried using ~~> with a function taking two parameters as a long shot but it didn't compile :(
> Googleing around poprule and reductionrule are really unhelpful.
>
> I am also assuming I need to use withContext somehow so I can get the buffer position.
>
> I am probably missing something fundamental, but any assistance would be appreciated. Also if I have a silly syntax, I wouldn't mind any criticism.
>
> Regards,
> Thomas Suckow
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/Scala-Noob-Question-tp3208611p3208611.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.

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

Re: Scala Noob Question

tsuckow
> If you have grammar snippets that don't compile and you don't know why, just
> post them.

I am not understanding the issue with this. ~~> Test results in:
missing arguments for method Test in class ScalaSilkParser; follow
this method with `_' if you want to treat it as a partially applied
function

  def Test(s:ASTString, r:ASTIndexRange):ASTString = { s }

  def Include = rule { IncludeInternal ~>> ASTIndexRange ~~> Test }
  def IncludeInternal = rule { "include" ~ WhiteSpace ~ SilkString ~ ";" }
  def SilkString = rule { "\"" ~ zeroOrMore(anyOf("abcde")) ~>
ASTString ~ "\"" ~ WhiteSpace }

But if I define Test as:
case class Test(s:ASTString, r:ASTIndexRange)
It does compile.

Ideally I want to use
~~%
so I don't push anything back onto the stack. But I can't figure out
how to do that because case class doesn't work because you can't
extend Unit for obvious reasons.
Idealy I want to call a function as well rather than create an object.

I'll deal with getting the context once I have a grasp on this (One
step at a time).
I changed to IndexRange because I believe this to be what I actually
want and would have computed from the string anyway.

> The SimpleCalculator1 example
> (https://github.com/sirthias/parboiled/blob/develop/examples-scala/src/main/scala/org/parboiled/examples/calculators/SimpleCalculator1.scala)
> shows the "~~>" operator with a function taking two parameters for example.

I took a look at this, unfortunately the action is inline and I am
unsure how to translate that into using a function.

> The parboiled for Scala examples assume you already know Scala, so it can
> probably be a bit confusing for people just starting with the language...

Ya, been spending time with "A tour of scala". Unfortunately I feel I
need to read it several more times before it will really start to sink
in. Took me hours to make my hello world parser that counted "!".

Thank you for your help mathias.  It is a great library you got here.

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

Re: Scala Noob Question

tsuckow
Ok, after a bunch more reading and trying things I am pretty sure it was my lack of understanding about functions vs methods. I still don't totally have my mind around it yet but I have settled on:

def Testing(s:ASTString, r:ASTIndexRange, context: Context[Any]):Unit = {  }
def Include = rule { IncludeInternal ~>> ASTIndexRange ~~% withContext(Testing _) }

And it compiles!

Again, if I am doing something silly please let me know. Otherwise, I shall continue ahead.

Regards,
Thomas Suckow
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Scala Noob Question

mathias
Administrator
Thomas,

one thing to remember is that the operators "~~>", "~~%" and so on are _methods_ that can only sometimes be used in infix notation.
If you feel like you are seeing wiered compiling problems try surrounding the arguments to the operator with parentheses.
Many times this makes the error messages more informative or even resolves the problem completely.

Cheers,
Mathias

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

On 30.07.2011, at 02:36, tsuckow [via parboiled users] wrote:

> Ok, after a bunch more reading and trying things I am pretty sure it was my lack of understanding about functions vs methods. I still don't totally have my mind around it yet but I have settled on:
>
> def Testing(s:ASTString, r:ASTIndexRange, context: Context[Any]):Unit = {  }
> def Include = rule { IncludeInternal ~>> ASTIndexRange ~~% withContext(Testing _) }
>
> And it compiles!
>
> Again, if I am doing something silly please let me know. Otherwise, I shall continue ahead.
>
> Regards,
> Thomas Suckow
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/Scala-Noob-Question-tp3208611p3211016.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.

Loading...