duckyscript with comparse pasted by wasamasa on Sun Jun 23 22:07:21 2019
(import scheme) (import (chicken base)) (import (chicken irregex)) (import (chicken pretty-print)) (import comparse) ;; key = "[A-Z0-9_]+" ;; char = "[^\r\n ]" ;; string-arg = "[^\r\n]+" ;; number = "[0-9]+" ;; newline = ("\r\n" | "\n") ;; whitespace = "[\t\v ]+" ;; comment = "REM" whitespace string-arg ;; default_delay = ("DEFAULTDELAY" | "DEFAULT_DELAY") whitespace number ;; delay = "DELAY" whitespace number ;; string = "STRING" whitespace string-arg ;; mod = ("WINDOWS" | "GUI" | "MENU" | "APP" | "SHIFT" | "ALT" | "CONTROL" | "CTRL") ;; modifiers = (mod whitespace)* ;; shortcut = modifiers? (char | key) ;; repeat = "REPEAT" whitespace number ;; command = (comment | default_delay | delay | string | repeat | shortcut) (define (parse-duckyscript input) (define (as-number parser) (bind (as-string parser) (lambda (s) (result (string->number s))))) (define (prefixed-argument prefix-parser arg-parser type) (sequence* ((_ prefix-parser) (_ whitespace) (arg arg-parser)) (result (list type arg)))) (define key (char-seq-match "[A-Z0-9_]+")) (define char (char-seq-match "[^\t\v ]")) (define string-arg (char-seq-match ".+")) (define digits (char-seq-match "[0-9]+")) (define whitespace (char-seq-match "[\t\v ]+")) (define comment (prefixed-argument (char-seq "REM") string-arg 'comment)) (define default-delay (prefixed-argument (any-of (char-seq "DEFAULTDELAY") (char-seq "DEFAULT_DELAY")) (as-number digits) 'default-delay)) (define delay (prefixed-argument (char-seq "DELAY") (as-number digits) 'delay)) (define string (prefixed-argument (char-seq "STRING") string-arg 'string)) (define repeat (prefixed-argument (char-seq "REPEAT") (as-number digits) 'repeat)) (define modifier (any-of (char-seq "WINDOWS") (char-seq "GUI") (char-seq "MENU") (char-seq "APP") (char-seq "SHIFT") (char-seq "ALT") (char-seq "CONTROL") (char-seq "CTRL"))) (define modifiers (zero-or-more (sequence* ((mod modifier) (_ whitespace)) (result mod)))) (define shortcut (sequence* ((mods modifiers) (key (any-of key char))) (result (list 'shortcut mods key)))) (define command (any-of comment default-delay delay string repeat shortcut)) (map (lambda (line) (parse (followed-by command end-of-input) line)) (irregex-split "\r\n\|\n" input))) (pp (parse-duckyscript "REM Hello Rick! DEFAULTDELAY 30 DELAY 3000 GUI r DELAY 200 STRING https://www.youtube.com/watch?v=dQw4w9WgXcQ ENTER DELAY 3000 STRING f"))
duckyscript with irregex pasted by wasamasa on Sun Jun 23 23:00:48 2019
(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)))
duckyscript with irregex, take 2 pasted by wasamasa on Mon Jun 24 09:37:25 2019
(define (parse-duckyscript input) (define blank '(+ ("\t\v "))) (define number '(+ numeric)) (define string '(+ nonl)) (define comment-cmd `(: (=> cmd "REM") ,blank (=> string ,string))) (define default-delay-name '(: (=> cmd "DEFAULT") (? "_") "DELAY")) (define default-delay-cmd `(: ,default-delay-name ,blank (=> number ,number))) (define delay-cmd `(: (=> cmd "DELAY") ,blank (=> number ,number))) (define string-cmd `(: (=> cmd "STRING") ,blank (=> string ,string))) (define repeat-cmd `(: (=> cmd "REPEAT") ,blank (=> number ,number))) (define mod '(or "WINDOWS" "GUI" "MENU" "APP" "SHIFT" "ALT" "CONTROL" "CTRL")) (define key '(+ (or upper numeric #\_))) (define char '(~ #\space)) (define shortcut-cmd `(: (=> strings (* (: ,mod (? ,blank)))) (=> string (? (or ,key ,char))))) (define command-rx `(: (or ,comment-cmd ,default-delay-cmd ,delay-cmd ,string-cmd ,repeat-cmd ,shortcut-cmd))) (define (to-lower s) (list->string (map char-downcase (string->list s)))) (define (non-blank-string s) (if (zero? (string-length s)) #f s)) (define (parse line) (define $ irregex-match-substring) (let ((m (irregex-match command-rx line))) (if m (let ((command ($ m 'cmd))) (case (and command (string->symbol (to-lower command))) ((rem) `(comment ,($ m 'string))) ((default) `(default-delay ,(string->number ($ m 'number)))) ((delay) `(delay ,(string->number ($ m 'number)))) ((string) `(string ,($ m 'string))) ((repeat) `(repeat ,(string->number ($ m 'number)))) (else `(shortcut ,(irregex-split blank ($ m 'strings)) ,(or (non-blank-string ($ m 'string)) (error "Missing key or character" line)))))) (error "Unrecognized line" line)))) (map parse (irregex-split "\r\n|\n" input))) (pp (parse-duckyscript "REM Hello Rick! DEFAULTDELAY 30 DELAY 3000 GUI r DELAY 200 STRING https://www.youtube.com/watch?v=dQw4w9WgXcQ ENTER DELAY 3000 STRING f REPEAT 3")) ;; ((comment "REM") ; why ;; (default-delay 30) ;; (delay 3000) ;; (shortcut ("GUI") "r") ;; (delay 200) ;; (string "STRING") ; no ;; (shortcut () "ENTER") ;; (delay 3000) ;; (string "STRING") ; plz ;; (repeat 3))
duckyscript with irregex, take 3 pasted by wasamasa on Mon Jun 24 11:30:31 2019
(define (parse-duckyscript input) (define blank '(+ ("\t\v "))) (define number '(+ numeric)) (define string '(+ nonl)) (define comment-cmd `(: (=> cmd "REM") ,blank (=> comment ,string))) (define default-delay '((=> cmd "DEFAULT") (? "_") "DELAY")) (define default-delay-cmd `(: ,@default-delay ,blank (=> default-delay ,number))) (define delay-cmd `(: (=> cmd "DELAY") ,blank (=> delay ,number))) (define string-cmd `(: (=> cmd "STRING") ,blank (=> string ,string))) (define repeat-cmd `(: (=> cmd "REPEAT") ,blank (=> repetitions ,number))) (define mod '(or "WINDOWS" "GUI" "MENU" "APP" "SHIFT" "ALT" "CONTROL" "CTRL")) (define key '(+ (or upper numeric #\_))) (define char '(~ #\space)) (define shortcut-cmd `(: (=> modifiers (* (: ,mod (? ,blank)))) (=> key-or-char (? (or ,key ,char))))) (define command-rx `(: (or ,comment-cmd ,default-delay-cmd ,delay-cmd ,string-cmd ,repeat-cmd ,shortcut-cmd))) (define (to-lower s) (list->string (map char-downcase (string->list s)))) (define (non-blank-string s) (if (zero? (string-length s)) #f s)) (define (parse line) (define $ irregex-match-substring) (let ((m (irregex-match command-rx line))) (if m (let ((command ($ m 'cmd))) (case (and command (string->symbol (to-lower command))) ((rem) `(comment ,($ m 'comment))) ((default) `(default-delay ,(string->number ($ m 'default-delay)))) ((delay) `(delay ,(string->number ($ m 'delay)))) ((string) `(string ,($ m 'string))) ((repeat) `(repeat ,(string->number ($ m 'repetitions)))) (else `(shortcut ,(irregex-split blank ($ m 'modifiers)) ,(or (non-blank-string ($ m 'key-or-char)) (error "Missing key or character" line)))))) (error "Unrecognized line" line)))) (map parse (irregex-split "\r\n|\n" input))) (pp (parse-duckyscript "REM Hello Rick! DEFAULTDELAY 30 DELAY 3000 GUI r DELAY 200 STRING https://www.youtube.com/watch?v=dQw4w9WgXcQ ENTER DELAY 3000 STRING f REPEAT 3 CTRL ALT DELETE")) ;; ((comment "Hello Rick!") ;; (default-delay 30) ;; (delay 3000) ;; (shortcut ("GUI") "r") ;; (delay 200) ;; (string "https://www.youtube.com/watch?v=dQw4w9WgXcQ") ;; (shortcut () "ENTER") ;; (delay 3000) ;; (string "f") ;; (repeat 3) ;; (shortcut ("CTRL" "ALT") "DELETE"))
duckyscript with irregex, take 4 added by wasamasa on Sat Jun 29 11:17:12 2019
(define (parse-duckyscript input)
(define blank '(+ ("\t\v ")))
(define number '(+ numeric))
(define string '(+ nonl))
(define mod '(or "WINDOWS" "GUI" "SHIFT" "ALT" "CONTROL" "CTRL"
"COMMAND" "OPTION"))
(define key '(+ (or upper numeric #\_)))
(define char '(~ #\space))
(define comment-cmd `(: bol (or "REM" "//")))
(define default-delay-cmd `(: bol "DEFAULT" (? "_") "DELAY" ,blank))
(define delay-cmd `(: bol "DELAY" ,blank))
(define string-cmd `(: bol "STRING" ,blank))
(define string-delay-cmd `(: bol "STRING_DELAY" ,blank))
(define repeat-cmd `(: bol "REPEAT" ,blank))
(define shortcut-cmd `(: ($ (* (: ,mod (? ,blank)))) ($ (or ,key ,char))))
(define optional-string-arg `(: (? ,blank) ($ (? ,string))))
(define number-arg `($ ,number))
(define string-arg `($ ,string))
(define number-string-arg `(: ($ ,number) ,blank ($ ,string)))
(define dashed-modifier `(: bol ,mod "-" ,key (* (: "-" ,key))))
(define (preprocess line)
(if (irregex-search dashed-modifier line)
(string-translate line "-" " ")
line))
(define (command-match line type-rx args-rx)
(and-let* (((irregex-search type-rx line))
(rest (irregex-replace type-rx line "")))
(or (irregex-match args-rx rest)
(error "Invalid arguments" line))))
(define (parse line)
(define $ irregex-match-substring)
(define ->int string->number)
(let ((line (preprocess line)))
(cond
((command-match line comment-cmd optional-string-arg)
=> (lambda (m) `(comment ,($ m 1))))
((command-match line default-delay-cmd number-arg)
=> (lambda (m) `(default-delay ,(->int ($ m 1)))))
((command-match line delay-cmd number-arg)
=> (lambda (m) `(delay ,(->int ($ m 1)))))
((command-match line string-cmd string-arg)
=> (lambda (m) `(string ,($ m 1))))
((command-match line string-delay-cmd number-string-arg)
=> (lambda (m) `(string-delay ,(->int ($ m 1)) ,($ m 2))))
((command-match line repeat-cmd number-arg)
=> (lambda (m) `(repeat ,(->int ($ m 1)))))
((irregex-match shortcut-cmd line)
=> (lambda (m) `(shortcut ,(irregex-split blank ($ m 1)) ,($ m 2))))
(else
(error "Unrecognized line" line)))))
(map parse (irregex-split "\r\n|\n" input)))