examples/paren-match-test.scm
#lang scheme

(require "../common.ss" 
         "../simple-parser.ss")


; This is a very simple parser that reads a string and turns it
; into a tree by matching parenthesis.
(define tree-parser (new-parser #:appender 
                                (λ vals (remove* '(||) vals))))
(add-items
 tree-parser
 ('start
  ["\\s+" '||]
  ["\\)" (λ(s)(sub-parse-return))]
  ["\\(" (λ(s)(sub-parse 'start)'||)]
  [#t string->symbol]
  )
 )

; Test:
(parse-text 
 tree-parser 
 "tree:(root (node1 (leaf1 leaf2) 
leaf3) (node2
 leaf4 (node3 leaf5) leaf6) leaf7)")

(newline)
(newline)


; Now let's make a parser that returns a string
; but parser a good subset of scheme source files
; (with comments and strings on mutliple lines).

(define paren-parser (new-parser))

; The string-sub-parser is triggered at the beginning of a string
; and returns immediately the whole string.
; Inner \" are correctly parsed.
; Same for parenthesis, and inner parenthesis, comments and strings are correctly parsed.

(list "("  #\() ; to test the parser on unmatched parenthesis (when parsing this file)
(define (parse-comment txt) txt)

#\( ; for test


(add-items
 paren-parser
 ('start
  ["\\(" (λ(s)(sub-parse 'paren 
                         (λ(text)(string-append "PAREN[" text "]")))s)]
  [(txt "#\\(") (λ(s)(string-append "CHAR[" s "]"))]
  [";.*" parse-comment]
  ["\"" (λ(s)(sub-parse 'string 
                        (λ(text)(string-append "STRING[\"" text "]")))s)]
  )
 ('paren ; parenthesis sub-parser
  ["\\)" (λ(s)(sub-parse-return s))]
  ["\\(" (λ(s)(sub-parse 'paren 
                         (λ(text)(string-append "SPAREN[" text "]")))s)]
  ; recursive call to the sub-parser (ok because there is a stack of sub-parsers)
  [";.*" parse-comment]
  ["\"" (λ(s)(sub-parse 'string
                        (λ(text)(string-append "P-STRING[" text "]")))s)]
  [(map txt '("#\\(" "#\\)")) 
   (λ(s)(string-append "CHAR[" s "]"))]
  )
 ('string ; string sub-parser
  ["[^\\\\\"]*" identity]
  ["\"" (λ(s)(sub-parse-return s))]
  ["\\\\." identity]
  )
 (#t ; for all phases, with top priority (because at lowest position)
  ["λ" "***Lambda***"]
  )
 )


(define text1 (file->lines "paren-match-test.scm"))
;(define text1 (file->lines "../common.scm"))
;(define text1 '("plopi\"sddfvf\"cd\"lklj\"(fcdf\"lkjsdf\"plo)up"))
;(define text1 '("abc(def)ghi"))
(newline)
(newline)
(newline)

(display (apply parse-text paren-parser text1))