[plt-scheme] Re: Parsing style [Was: proof checking: a, subproblem]

From: David Van Horn (dvanhorn at cs.brandeis.edu)
Date: Fri Jan 20 18:22:28 EST 2006

Anton van Straaten wrote:
> Scheme macros require input in s-expression form, so for anything else,
> you need something to transform the input syntax, even if you just
> transform it into s-expressions and deal with it from there.  A
> yacc-style parser is a reasonable choice if the language you're
> implementing justifies it.
> You could, in theory, write a macro named e.g. "formula" that accepts
> input like the following:
>   (formula ~(p V ~q) -> (q -> ~p A r))
> But with input such as the above, you'll be essentially writing a parser
> of your own anyway, as part of the implementation of the "formula"
> macro [...]

If you wanted such a macro, you could have the macro do just the lexing,
then let a generated parser take over.  For example, using calcp from
the parser-tools examples:

(define-syntax calc
  (syntax-rules ()
    ((calc #t () accum)
      (let ((tokens (reverse 'accum)))
        (lambda ()
          (if (null? tokens)
              (let ((s (car tokens)))
                (set! tokens (cdr tokens))
                (case s
                  ((= + - * / ^ OP CP) s)
                  ((sin) (token-FNCT sin))
                     ((symbol? s) (token-VAR s))
                     ((number? s) (token-NUM s)))))))))))

    ((calc #t ((x ...) . rest) accum)
     (calc #t (OP x ... CP . rest) accum))
    ((calc #t (x . rest) accum)
     (calc #t rest (x . accum)))
    ((calc . exp)
     (calc #t exp ()))))

Instead of writing:

(calc (open-input-string "(1 + 2 * 3) - (1+2)*3"))
(calc (open-input-string "(x=1) x+sin(x)"))

You'd write:

(calc (1 + 2 * 3) - (1 + 2) * 3)
(calc (x = 1) x + sin(x))

[ The macro serves little purpose here beyond replacing ( and ) with OP
and CP; it could just as easily have been written as a function taking
an S-expression. ]

Does this have any benefits?  Probably not.


Posted on the users mailing list.