Very nice
I'm currently building up and spec'ing my grammar but this is what I have
so far.
module Parslet
module Atoms
module DSL
def %(separator)
item = self
item >> (separator >> item).repeat(0)
end
end
end
end
On Fri, May 10, 2013 at 3:56 PM, Nigel Thorne <[email protected]> wrote:
> 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
>>
>>
>>
>