librelist archives

« back to archive

Parser not really eatting whitespace?

Parser not really eatting whitespace?

From:
Zachary Drummond - Bia
Date:
2011-08-24 @ 00:22
I followed the online docs pretty closely and got hit by the fact that the
parser does not seem to always eat whitespace. If you run the following 
code, you will see that the intergers have no whitespace, but the + does, 
which causes the transform to fail. Any ideas of what I am doing wrong?

Thanks,
-Zach
---
require 'parslet'

class MiniP < Parslet::Parser
  # Single character rules
  rule(:lparen) { str('(') >> space? }
  rule(:rparen) { str(')') >> space? }
  rule(:comma) { str(',') >> space? }

  rule(:space) { match('\s').repeat(1) }
  rule(:space?) { space.maybe }

  # Things
  rule(:integer) { match('[0-9]').repeat(1).as(:int) >> space? }
  rule(:identifier) { match['a-z'].repeat(1) }
  rule(:operator) { match('[+]') >> space? }

  # Grammar parts
  rule(:sum) { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
  rule(:arglist) { expression.as(:arg) >> (comma >> expression.as(:arg)).repeat }
  rule(:funcall) { identifier.as(:funcall) >> lparen >> 
arglist.as(:arglist) >> rparen }

  rule(:expression) { funcall | sum | integer }
  root :expression
end

class MiniT < Parslet::Transform
  rule(:int => simple(:x) ) { Integer(x) }
  rule(:op => '+', :left => simple(:l), :right => simple(:r)) { l + r }
end

def parse(str)
  mini = MiniP.new
  tree = mini.parse(str)

  print "Parsing #{str}: -> #{tree}\n"

  result = MiniT.new.apply( tree )
  print "Transform -> #{result}\n\n"

rescue Parslet::ParseFailed => error
  puts error, mini.root.error_tree
end

parse "1 + 2"
#Parsing 1 + 2: -> {:left=>{:int=>"1"@0}, :op=>"+ "@2, :right=>{:int=>"2"@4}}
#Transform -> {:left=>1, :op=>"+ "@2, :right=>2}

parse "1+2"
#Parsing 1+2: -> {:left=>{:int=>"1"@0}, :op=>"+"@1, :right=>{:int=>"2"@2}}
#Transform -> 3


Zachary Drummond
BIA | TotalDiscovery.com

2001 6th Ave
Seattle, WA 98040
O: 206-805-3131
www.biaprotect.com<http://www.biaprotect.com/>
www.TotalDiscovery.com<http://www.TotalDiscovery.com>


DEFENSIBLE DATA SOLUTIONS(tm)

______________________________________________________________________________________________________________________________________
This message may contain confidential and/or legally privileged 
information intended only for the use of the individual(s) named on the 
To:, Cc: and Bcc: lines.  If you are not one of the intended recipient(s),
then you are hereby notified that any disclosure, copying, distribution or
the taking of any action in reliance on the contents of this email 
transmission is strictly prohibited. If you have received this 
communication in error, please delete the email in its entirety and call 
or email us immediately so that we may take appropriate steps to correct 
the problem at no cost to you. Even if this message has reached you in 
error, sender does not in any way waive confidentiality or privilege. 
Thank you.

Re: [ruby.parslet] Parser not really eatting whitespace?

From:
Melissa Whittington
Date:
2011-08-24 @ 15:42
Zach,

The problem is that your operator rule is including the whitespace, so
:op => "+ " (note space) and thus your transform rule is not matching.

You should switch these two rules:

  rule(:operator) { match('[+]') >> space? }
  rule(:sum) { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }

to this instead:

  rule(:operator) { match('[+]').as(:op) >> space? }
  rule(:sum) { integer.as(:left) >> operator >> expression.as(:right) }

and I believe that should work.

-mj

On Tue, Aug 23, 2011 at 8:22 PM, Zachary Drummond - BIA
<zdrummond@biaprotect.com> wrote:
> I followed the online docs pretty closely and got hit by the fact that the
> parser does not seem to always eat whitespace. If you run the following
> code, you will see that the intergers have no whitespace, but the + does,
> which causes the transform to fail. Any ideas of what I am doing wrong?
>
> Thanks,
>
> -Zach

Re: [ruby.parslet] Parser not really eatting whitespace?

From:
Zachary Drummond - Bia
Date:
2011-08-24 @ 18:54
Thanks! That did it. 

Note, the documentation on the site seems to be incorrect in a couple 
places. For example, I copied that operator code directly from the getting
started page

http://kschiess.github.com/parslet/get-started.html
<Example in the section " Making the parser complete"/>
class MiniP < Parslet::Parser
          # Single character rules
          rule(:lparen)     { str('(') >> space? }
          rule(:rparen)     { str(')') >> space? }
          rule(:comma)      { str(',') >> space? }
        
          rule(:space)      { match('\s').repeat(1) }
          rule(:space?)     { space.maybe }
        
          # Things
          rule(:integer)    { match('[0-9]').repeat(1).as(:int) >> space? }
          rule(:identifier) { match['a-z'].repeat(1) }
          rule(:operator)   { match('[+]') >> space? }
          
          # Grammar parts
          rule(:sum)        { integer.as(:left) >> operator.as(:op) >> 
expression.as(:right) }
          rule(:arglist)    { expression >> (comma >> expression).repeat }
          rule(:funcall)    { identifier.as(:funcall) >> lparen >> 
arglist.as(:arglist) >> rparen }
          
          rule(:expression) { funcall | sum | integer }
          root :expression
end

-----Original Message-----
From: ruby.parslet@librelist.com [mailto:ruby.parslet@librelist.com] On 
Behalf Of Melissa Whittington
Sent: Wednesday, August 24, 2011 8:42 AM
To: ruby.parslet@librelist.com
Subject: Re: [ruby.parslet] Parser not really eatting whitespace?

Zach,

The problem is that your operator rule is including the whitespace, so :op
=> "+ " (note space) and thus your transform rule is not matching.

You should switch these two rules:

  rule(:operator) { match('[+]') >> space? }
  rule(:sum) { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }

to this instead:

  rule(:operator) { match('[+]').as(:op) >> space? }
  rule(:sum) { integer.as(:left) >> operator >> expression.as(:right) }

and I believe that should work.

-mj

On Tue, Aug 23, 2011 at 8:22 PM, Zachary Drummond - BIA 
<zdrummond@biaprotect.com> wrote:
> I followed the online docs pretty closely and got hit by the fact that 
> the parser does not seem to always eat whitespace. If you run the 
> following code, you will see that the intergers have no whitespace, 
> but the + does, which causes the transform to fail. Any ideas of what I 
am doing wrong?
>
> Thanks,
>
> -Zach