<div dir="ltr">Thank you. Reading the match docs, I didn&#39;t infer the significance of quasipatterns for XML parsing.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 25, 2013 at 6:14 AM, Matthias Felleisen <span dir="ltr">&lt;<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
On Jun 24, 2013, at 9:52 PM, Matthew Butterick wrote:<br>
<br>
&gt; I&#39;ve seen this technique recommended numerous times. Would anyone have a link to an idiomatic example of the technique in use? Thank you.<br>
</div>&gt; ____________________<br>
&gt;  Racket Users list:<br>
&gt;  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
<br>
Your question is somewhat generic. So here is a generic answer:<br>
<br>
#lang racket<br>
<br>
(require xml)<br>
<br>
(module+ test<br>
  (require rackunit))<br>
<br>
;; -----------------------------------------------------------------------------<br>
;; recognizing an XML that belongs to a grammar<br>
<br>
;; E = &lt;plus&gt;E E&lt;/plus&gt; | &lt;number value=String /&gt;<br>
<br>
(define (ex i) (format &quot;&lt;number value =\&quot;~a\&quot; /&gt;&quot; i))<br>
(define (ex2 i j) (string-append &quot;&lt;plus&gt;&quot; (ex i) (ex j) &quot;&lt;/plus&gt;&quot;))<br>
<br>
;; String -&gt; Boolean<br>
;; does E produce e?<br>
<br>
(module+ test<br>
  (check-true (parse (ex2 5 42)))<br>
  (check-false (parse (ex &quot;hello world&quot;)))<br>
  (check-false (parse (ex2 5 &quot;hello world&quot;))))<br>
<br>
(define (parse e:str)<br>
  (define e:xml (read-xml/element (open-input-string e:str)))<br>
  (define e:xexpr (xml-&gt;xexpr e:xml))<br>
  (let parse ((e e:xexpr))<br>
    (match e<br>
      [`(number ((value ,v))) (number? (string-&gt;number v))]<br>
      [`(plus () ,e1 ,e2) (and (parse e1) (parse e2))]<br>
      [else #f])))<br>
<br>
;; -----------------------------------------------------------------------------<br>
;; creating a parse tree for a valid XML<br>
<br>
;; A = Number | (list &#39;+ Number Number)<br>
<br>
;; String -&gt; [maybe/c A]<br>
;; does E produce e? if so, create an a, otherwise #f<br>
<br>
(module+ test<br>
  (check-equal? (parse-to (ex2 5 42)) &#39;(+ 5 42))<br>
  (check-false (parse-to (ex &quot;hello world&quot;)))<br>
  (check-false (parse-to (ex2 5 &quot;hello world&quot;))))<br>
<br>
(define (parse-to e:str)<br>
  (define e:xml (read-xml/element (open-input-string e:str)))<br>
  (define e:xexpr (xml-&gt;xexpr e:xml))<br>
  (let parse ((e e:xexpr))<br>
    (match e<br>
      [`(number ((value ,v)))<br>
       (define x (string-&gt;number v))<br>
       (if (number? x) x #f)]<br>
      [`(plus () ,e1 ,e2)<br>
       (define p1 (parse e1))<br>
       (cond<br>
         [(boolean? p1) #f]<br>
         [else (define p2 (parse e2))<br>
               (and p2 `(+ ,p1 ,p2))])]<br>
      [else #f])))<br>
<br>
I have not include exception handling for invalid and/or incomplete XML strings.<br>
I have also skipped treatment of white space.<br>
<br>
I tend to create macros with which I can specify X-expression grammars<br>
so that I can easily write down parsers and unparsers. That way I don&#39;t<br>
ever see match in real code:<br>
<br>
(define (state-writer s)<br>
  (state-&gt;xexpr s))<br>
<br>
(define state-parser<br>
  (xml-parser (state () (b board-parser) (p player-parser) ... #:action (*create-state b p))))<br>
<br>
(module+ test<br>
  (check-equal? (state-parser (state-writer s0)) s0)<br>
  (check-equal? (state-parser (state-writer s1)) s1))<br>
<br>
These are from a recent game. The tests ensure that the two functions are compatible.<br>
<span class="HOEnZb"><font color="#888888"><br>
-- Matthias<br>
<br>
</font></span></blockquote></div><br></div>