Hi,
First, just want to say thank you for writing "Parslet", I don't know what
I'd do without it!
Now, on to the grim business at hand... ;)
According to the doc,
Matching something once or not at all can be achieved by repeat(0,1), but
also through the prettier:
str('foo').maybe # same as str('foo').repeat(0,1)
(http://kschiess.github.com/parslet/parser.html)
But the following yields different results depending on whether I use
".repeat(0,1)" or ".maybe". In the line with the comment " #### THIS LINE
####, using ".repeat(0,1)" exits the code (maybe_test.rb, at bottom) without
an error; but if the ".repeat(0,1)" is changed to ".maybe", I get
/home/jenko/Ruby/query_engine/maybe_test.rb:9:in `<top (required)>': private
method `eval' called for #<Hash:0x00000001f75bb0> (NoMethodError)
from -e:1:in `load'
from -e:1:in `<main>'
I chopped this down from my original project as much as I could.
Thank you!
PS, Here are the repro files:
#myparser.rb:
require 'parslet'
class MiniP < Parslet::Parser
rule(:comma) { str(',') >> space? }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.repeat(0,1) }
rule(:digit) { match("[0-9]") }
rule(:integer) {
((str('+') | str('-')).repeat(0,1) >> digit.repeat(1)).as(:int) >>
space? #### THIS LINE ####
}
rule(:offset_params) { (integer >> (comma >>
expression).repeat(0,1).as(:offset_params) }
rule(:expression){
offset_params
}
root :expression
end
========================================================
#mytransform.rb
require 'parslet'
require './myparser.rb'
class IntExp < Struct.new(:int)
def eval; int.to_i; end
end
class OffsetParamsExp < Struct.new(:offset_params)
def eval
offset_params.map do |s|
if s.class == Parslet::Slice
s.to_s.to_i
else
s.eval
end
end
end
end
class MiniT < Parslet::Transform
rule(:int => simple(:int)) {
IntExp.new(int) }
rule(:offset_params => sequence(:offset_params)) {
OffsetParamsExp.new(offset_params) }
rule(:offset_params => simple(:offset_params)) {
OffsetParamsExp.new(offset_params) }
end
========================================================
#maybe_test.rb
require 'parslet'
require './myparser.rb'
require './mytransform.rb'
@minip = MiniP.new
@transf = MiniT.new
tree = @minip.parse("-3,1")
ast = @transf.apply(tree)
result = ast.eval