I've been re-reading A5 (regexen), and I was trying to work out how to incorporate a preprocessor into regex, without a separate lexer. I came to the conclusion that preprocessor commands are part of the whitespace in the higher layer of the grammer. So we just need to define the <ws> rule appropriately. Proprocessing also requires maintenance of filename and linenum as we move between files.

The following code illustrates my thoughts: am I anywhere near close?


grammar expression is preprocessed { rule main { <expression>* <EOF> }

    rule expression
    {
        :w <number> <op> <number> { print eval join $op, @number }
    }
}

grammar preprocessed
{
    rule ws
    {
        <SUPER.ws> # we are extending the default <ws> rule

        # match #include _filename_.
        | ^^ \# <SUPER.ws>* include <SUPER.ws>* <filename>
          < <SUPER.ws> - \n >* \n
            # assume .pos acts like a stack: push the
            # new filehandle onto it: hope the handle
            # will supply filename and line_num
            { .pos.push open "<$filename" or fail }

        # at end of file, pop the .pos stack, if not empty
        | <EOF> { .pos.empty and fail } { .pos.pop }
    }

    # assume Safe module gives us a filename with no dangerous
    # meta-chars
    rule filename { Safe.filename }
}

--
Dave.



Reply via email to