in reply to Re: Re: Using Perl6 patterns/grammar definition for <I>output</I>?
in thread Using Perl6 patterns/grammar definition for 'output'?

Using named rules to key formatting sounds like a good idea; but I'm not sure that I like the idea of using a "derived grammar" to represent the formatting of these named rules: it seems beeter to introduce an explicit formatting object. This formatting object would provide information to a visitor that traverses a parse tree (i.e. a match object plus its grammar); but it would not have the hierarchical structure of the grammar.

Using a separate formating object has several advantages. Firstly, it avoids the parallel hierachies maintenance problem (you want formatting to be robust against modifications to the grammar). Even if you are only overriding the terminal rules of the grammar, you still have the issue that a change to the base grammar would be obscured in the derived grammar.

A more important issue is that it will be common to import terminal symbols from other grammars (e.g. CORE::*). How many grammars to you want to override, just to format some output?

I see a formatting object as a simple map of rule_name => format spec; with some mechanism for composition. This doesn't need to follow the hierarchy of a grammer:

my $format = new Format ( ws => { col >= 70 ? "\n" : " " }, currency => { sprintf("%.2f", $currency) }, date => {sprintf("%04d-%02d-%02d", @$date{qw/year month day/})}, ); $text =~ /<grammar.rule>/; $format.output($0; grammar=>"grammar.rule", fh=>$*STDOUT)
The output method would traverse the grammar; each time it meets a rule that has a format, it applies that format to the corresponding entry in the match object ($0). This does not require a derived grammar: just an extra specification object. Sometimes composition is better than inheritance.

--Dave

Replies are listed 'Best First'.
Re: Re: Re: Re: Using Perl6 patterns/grammar definition for <I>output</I>?
by John M. Dlugosz (Monsignor) on Sep 05, 2002 at 20:39 UTC
    I see: instead of having formatting as a side-effect of the grammar rules, you would supply separate formatting rules that match by name. If there is a match, it uses that and doesn't look at the corresponding grammar rule.

    I think the way you write it should certainly be possible, meaning that the grammar object should be traversible enough to allow format.output to be written in Perl.

    I like that how the return value is the text to output, but I don't see how $date, $currency, etc. would become implicit like they are in the grammar. If the populated $0 becomes the current topic when a call is made, that would be easy enough: $.currency, right?

    —John

      Yes, I definitely want to have an iterator that I can use to traverse a grammar in Perl6. However, a bit more thought gave me this idea:
      class MyFormat is CORE::GrammarVisitor { my $fh is public; method date ($node) { $fh.printf("%04d-%02d-%02d", $node ^. qw(year month day)) } } $0.traverse(MyFormat.new(fh=>$*STDOUT)); # default ctor?
      This is probably the type of code that would have been instantiated by the hash approach; but is more flexible, and allows for more powerful formating concepts (the visitor can maintain state between the things that it outputs).

      But going back to the hash-based approach, I think that it is possible to do something like:

      my $sub = sub {print $value}; $sub.MY{'$value'} = 42; $sub();
      I think this would be kinda scary though.

      --Dave

      Update: Fixed typo: MY{'$date'} becomes MY{'$value'}

        Yes, the GrammarVisitor derived class is symetric with the grammar itself: members match rules, and you can derive from them to alter things. I like it.

        I don't understand your second listing. $sub.MY{'$date'} is going to set a variable inside that closure, I take it? But the sub never uses it.

        —John