> grammar Grammars::Languages::C::Preprocessor {
>   rule CompilationUnit {
>     ( <Directive> | <UnprocessedStuff> )*
>   }
> 
>   rule Directive {
>     <Hash> ( Include
>            | Line   
>            | Conditional
>            | Define
>     ) <Continuation>*
>   }
> 
>   rule Hash { /^\s*#\s*/ }
>   rule Include {...}
>   rule Line {...}
>   rule Conditional {...}
>   rule Define {...}
>   rule Continuation {...}
>   rule UnprocessedStuff {...}
> }

We're not quite in the world of ACME::DWIM, so you can't just replace
the important stuff with ... .  :-)

You're not outputting a parse tree, you're just outputting more text
to be parsed with another, text-based, grammar.  It seems to me like
it's a big s//ubstitution, of sorts.

Or maybe not, maybe we make an output stream which will be fed to
Grammars::Languages::C.  Here's an implementation a #include
processor, using as little made-up syntax as possible.

    use Pattern::Common;

    grammar Preprocessor {
        rule include {
            :w(/\h*/)
            \# include "<Pattern::Common::filename>" $$
                { $0 := (<<< open "< $filename") ~~ /<main>/ }
        }

        rule main {
            $0 := ( [<include> | .]* )
        }
    }

Now, to chain them, you do the (seemingly more natural):

    $fh ~~ /<Preprocessor>/ ~~ /<C>/

I've been trying to figure out how one would do Preprocessor lazily,
such that it would not process any more text until C said it needed
it.  Perhaps something with ArrayString (the hypothetical class from
A5)?  Coroutines?

Luke

> Except that it would probably be even better to do this arbitrarily.
> 
> > my $fh = open "<hello.c";
> > $fh =~ /<Grammars::Languages::C>/;
> 
> $fh =~ /<Grammars::Languages::C(input_method =
> Grammars::Languages::C::Preprocessor)>/;
> 
> (Of course, in reality the C grammar would automatically use the
> preprocessor as its input method without having to be told. But it
> should be able to do so as two separate grammars.)
> 
> Likewise:
> 
> my $fh = open "<perl.1.gz";
> 
> $fh =~ /<Grammars::Languages::Runoff::Nroff(input_method
>          = Grammars::Languages::Runoff::tbl(input_method
>            = Grammars::Language::Runoff::eqn(input_method
>              = IO::Gunzip)))>/;
> 
> =Austin

Reply via email to