-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathfind-paren-loc.rkt
66 lines (56 loc) · 2.9 KB
/
find-paren-loc.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#lang racket
(require syntax-color/scheme-lexer)
(require rackunit)
(define-struct paren (text type paren-type start end) #:transparent)
;;port -> (listof paren)
(define (paren-problem p)
(letrec ([paren-problem-help
(lambda (port stack)
(define-values (text type paren-type start end)
(scheme-lexer port))
(cond
[(eof-object? text) (if (empty? stack)
'()
(list (first stack)))]
[(or (string=? text "[")
(string=? text "(")
(string=? text "{"))
(paren-problem-help port (cons (make-paren text type paren-type start end) stack))]
[(or (string=? text "]")
(string=? text ")")
(string=? text "}"))
(if (empty? stack)
(list (make-paren text type paren-type start end))
(if (not (string=? (paren-text (first stack)) (get-match text) )) ;;if doesnt match
(list (first stack) (make-paren text type paren-type start end))
(paren-problem-help port (rest stack))))]
[else (paren-problem-help port stack)]))])
(paren-problem-help p '())))
;;get-match: string -> string
;;finds matching parenthesis
(define (get-match p)
(cond
[(string=? p ")") "("]
[(string=? p "]") "["]
[(string=? p "}") "{"]
[(string=? p "(") ")"]
[(string=? p "{") "}"]
[(string=? p "[") "]"]
[else " "]))
(check-equal? (paren-problem (open-input-string "(foo")) (list (make-paren "(" 'parenthesis '|(| 1 2)))
(check-equal? (paren-problem (open-input-string "{)")) (list (make-paren "{" 'parenthesis '|{| 1 2)
(make-paren ")" 'parenthesis '|)| 2 3)))
(check-equal? (paren-problem (open-input-string "()[][][]{)")) (list (make-paren "{" 'parenthesis '|{| 9 10)
(make-paren ")" 'parenthesis '|)| 10 11)))
(check-equal? (paren-problem (open-input-string "(foo)")) '())
(check-equal? (paren-problem (open-input-string "](){](}][")) (list (make-paren"]" 'parenthesis '|]| 1 2)))
(check-equal? (paren-problem (open-input-string "")) '())
(check-equal? (paren-problem (open-input-string "({]")) (list (make-paren "{" 'parenthesis '|{| 2 3)
(make-paren "]" 'parenthesis '|]| 3 4)))
(provide/contract [struct paren ([text string?]
[type symbol?]
[paren-type symbol?]
[start number?]
[end number?])]
[paren-problem (input-port? . -> . (listof paren?))]
[get-match (string? . -> . string?)])