Recently I was playing with this...
#################################
module Parslet
class << Parser
alias_method :_rule, :rule
def rule(name, &definition)
if name.to_s[0] == '_'
_rule(name, &definition)
else
define_method(name) do
@rules ||= {} # <name, rule> memoization
return @rules[name] if @rules.has_key?(name)
# Capture the self of the parser class along with the definition.
definition_closure = proc {
self.instance_eval(&definition).as(name)
}
@rules[name] = Atoms::Entity.new(name, &definition_closure)
end
end
end
end
class Atoms::Base
def +(); self.repeat(1);end
def *(); self.repeat();end
def _?(); self.maybe();end
def _!(); self.absent?();end
end
class Parser
alias_method :`, :str
def m(); match();end
end
end
####################################
This lets you define rules like this
scope.+ is repeat scope more than once.
scope.* is repeat scope (zero allowed)
`x` is str("x")
scope._? is optional
m[...] is match[...]
scope._! is 'not' or absent
It also sets up a convention where rules automatically put an "as" clause
with the same name as the rule (unless they start with an _)
I am still undecided if this actually makes anything clearer :) but it was
a good experiment.
#####################################
I also use the naming convention that any rule that could match a zero
length string ends in a '?'
Nigel
---
"Man, I'm going to have so many chickens when this lot hatch!"
On Sat, May 11, 2013 at 4:10 AM, Ammon Christiansen <
[email protected]> wrote:
> I want to ask some questions about how to accomplish some syntax sugar I
> would like.
>
> 1. For example,
> In boost spirit qi in C++ there was a % operator which would allow
> a % str(',')
> instead of
> a << (str(',') >> a).repeat(0)
>
>
> 2. Also, it had two modes, one where all atoms could have optional
> whitespace between them and a way to get out of that mode temporarily.
> I was wondering whether we could use operator > instead of >> to simplify
> a >> space? >> b
> to a > b
>
> I see in the examples that most of the time you just add optional
> whitespace eaters to base atoms
>
>
> I had trouble understanding the code for >> or I would just implement
> these locally.
> Maybe if you don't like the idea of adding any of this sugar, you could
> help me understand this code:
>
>
> 18
> 19
> 20
>
> # File 'lib/parslet/atoms/sequence.rb', line 18
> def >>(parslet)
> self.class.new(* @parslets+[parslet])end
>
>
>