On 26 sep, 02:54, Clifford H. [email protected] wrote:
Wincent C. wrote:
One of the things I always liked about the system was that you wrote
your grammars in Ruby.
I think that’s an error, based on the presumption that “is Ruby, is good”.
Not all that’s Ruby is golden, err… red ;-).
Well, using a Ruby DSL brought with it three advantages:
-
Could develop incrementally seeing as I already had a working
interpreter (the Ruby interpreter); no need to develop a custom parser
to parse the DSL. This allowed me to develop very very quickly with
minimal time between “initial idea” and “first basic, working
implementation”.
-
Could leverage existing Ruby functionality to take shortcuts; for
example, regular expressions were already just sitting there waiting
to be used, or lambda blocks to create miniature “sub-parsers” and
handle embedded langauges etc.
-
(Debatably) A shorter learning curve because I already know Ruby.
None of these are show-stopping “deal-winners”, but they were things
that lead me down the DSL-in-Ruby path. That and the fact that there
are so many DSLs written in Ruby out there that you find yourself
using them all the time (to a person with a hammer, everything looks
like a nail).
On 26 sep, 04:30, Eric M. [email protected] wrote:
Just because you are using a Ruby DSL, you shouldn’t be limited. There is
nothing that says your DSL couldn’t build exactly the same data structures
that you’d build if you read/parsed in a non-Ruby DSL. In my Grammar
project, I create a Grammar tree with a Ruby DSL (simply methods that create
and combine Grammars). I can parse directly using this tree or I can
generate highly optimized code. Here are a few optimizations: flattening
(method calls only needed for recursion), tail call optimization (right
recursion), left recursion (normally unheard of with LL)
Yes, although Pappy, written in Haskell and one of the first Packrat
parsers (if not the first) does it using Higher Order functions. I do
it using Ruby continuations.
some refactoring,
and boolean minimizations. The main thing that should matter in terms of
analysis should be your data structures, not how you get there. A ruby DSL
will only enhance flexibility.
I think part of the problem is that the Ruby DSL is too open-ended, at
least as I’ve used it. This is simultaneously a great advantage but
also a great disadvantage when it comes to static analysis.
Let’s take regular expressions, for example. By using a Ruby DSL you
can allow the user to specify something using a regular expression and
you can suddenly recognize all those regular language structures
basically “for free”. But if you want to do static grammar analysis on
something that uses Ruby regular expressions you either have to look
inside the expressions at runtime (effectively writing yet another
parser to break them down), or you have to forgo Ruby’s and roll your
own. This is because in order to do any kind of useful static analysis
you have to be able to reduce the regular expression into a canonical
DFA.
Another example would be the use of lambda’s to provide dynamic
context-sensitivity at runtime. I use these, for example, to parse
“here documents”, where you don’t know what the end marker is going to
look like at the time you construct the grammar. This is a great
convenience for the user and allows you to recognize some pretty
powerful stuff, but it is also pretty much immune to static analysis
because you can’t know what’s going in inside the lambda.
Cheers,
Wincent