(define (parse-duckyscript input) (define blank '(+ ("\t\v "))) (define number '(+ numeric)) (define string '(+ nonl)) (define comment-rx `(: "REM" ,blank ($ ,string))) (define default-delay-rx `(: "DEFAULT" (? "_") "DELAY" ,blank ($ ,number))) (define delay-rx `(: "DELAY" ,blank ($ ,number))) (define string-rx `(: "STRING" ,blank ($ ,string))) (define repeat-rx `(: "REPEAT" ,blank ($ ,number))) (define mod '(or "WINDOWS" "GUI" "MENU" "APP" "SHIFT" "ALT" "CONTROL" "CTRL")) (define key '(+ (or upper numeric #\_))) (define char '(~ #\space)) (define shortcut-rx `(: ($ (* (: ,mod ,blank))) ($ (or ,key ,char)))) (define submatch irregex-match-substring) (define (parse line) (cond ((irregex-match comment-rx line) => (lambda (m) `(comment ,(submatch m 1)))) ((irregex-match default-delay-rx line) => (lambda (m) `(default-delay ,(string->number (submatch m 1))))) ((irregex-match delay-rx line) => (lambda (m) `(delay ,(string->number (submatch m 1))))) ((irregex-match string-rx line) => (lambda (m) `(string ,(submatch m 1)))) ((irregex-match repeat-rx line) => (lambda (m) `(repeat ,(string->number (submatch m 1))))) ((irregex-match shortcut-rx line) => (lambda (m) `(shortcut ,(irregex-split blank (submatch m 1)) ,(submatch m 2)))) (else (error "Unrecognized line" line)))) (map parse (irregex-split "\r\n|\n" input)))