[plt-scheme] Re: Parsing style [Was: proof checking: a, subproblem]
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)
(calcp
(let ((tokens (reverse 'accum)))
(lambda ()
(if (null? tokens)
(token-EOF)
(let ((s (car tokens)))
(set! tokens (cdr tokens))
(case s
((= + - * / ^ OP CP) s)
((sin) (token-FNCT sin))
(else
(cond
((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.
David