-
Notifications
You must be signed in to change notification settings - Fork 0
/
tokenizer.rkt
41 lines (35 loc) · 1.12 KB
/
tokenizer.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
#lang racket
(require brag/support)
(define (make-tokenizer ip)
(port-count-lines! ip)
(define the-lexer
(lexer-src-pos
[":" (token 'COLON lexeme)]
[";" (token 'SEMICOLON lexeme)]
["|" (token 'ALTERATION lexeme)]
["*" (token 'STAR lexeme)]
["?" (token 'QUESTION lexeme)]
[(repetition 1 +inf.0 upper-case)
(token 'NON-TERMINAL lexeme)]
[(repetition 1 +inf.0 lower-case)
(token 'TERMINAL lexeme)]
[whitespace
(token 'WHITESPACE lexeme #:skip? #t)]
[(eof)
(void)]))
(define (next-token) (the-lexer ip))
next-token)
(provide make-tokenizer)
(module+ test
(require rackunit)
(define (test-first-token str)
(token-struct-type
(position-token-token
((make-tokenizer (open-input-string str))))))
(check-equal? (test-first-token ":") 'COLON)
(check-equal? (test-first-token ";") 'SEMICOLON)
(check-equal? (test-first-token "|") 'ALTERATION)
(check-equal? (test-first-token "*") 'STAR)
(check-equal? (test-first-token "?") 'QUESTION)
(check-equal? (test-first-token "S") 'NON-TERMINAL)
(check-equal? (test-first-token "noun") 'TERMINAL))