1 {
2 
3 module Main (main) where
4 import System.Exit
5 import Prelude hiding (lex)
6 
7 }
8 
9 %wrapper "monad"
10 %token "Token s"
11 %typeclass "Read s"
12 
13 tokens :-
14 
15 [a-b]+$                     { idtoken 0 }
16 [c-d]+/"."                  { idtoken 1 }
17 [e-f]+/{ tokpred }          { idtoken 2 }
18 ^[g-h]+$                    { idtoken 3 }
19 ^[i-j]+/"."                 { idtoken 4 }
20 ^[k-l]+/{ tokpred }         { idtoken 5 }
21 [m-n]+$                     { idtoken 6 }
22 [o-p]+/"."                  { idtoken 7 }
23 [q-r]+/{ tokpred }          { idtoken 8 }
24 [0-1]^[s-t]+$               { idtoken 9 }
25 [2-3]^[u-v]+/"."            { idtoken 10 }
26 [4-5]^[w-x]+/{ tokpred }    { idtoken 11 }
27 [y-z]+                      { idtoken 12 }
28 [A-B]+$                     ;
29 [C-D]+/"."                  ;
30 [E-F]+/{ tokpred }          ;
31 ^[G-H]+$                    ;
32 ^[I-J]+/"."                 ;
33 ^[K-L]+/{ tokpred }         ;
34 [M-N]+$                     ;
35 [O-P]+/"."                  ;
36 [Q-R]+/{ tokpred }          ;
37 [0-1]^[S-T]+$               ;
38 [2-3]^[U-V]+/"."            ;
39 [4-5]^[W-X]+/{ tokpred }    ;
40 [Y-Z]+                      ;
41 \.                          ;
42 [ \n\t\r]+                  ;
43 [0-9]                       ;
44 
45 {
46 
47 alexEOF :: Alex (Token s)
48 alexEOF = return EOF
49 
50 tokpred :: () -> AlexInput -> Int -> AlexInput -> Bool
51 tokpred _ _ _ _ = True
52 
53 idtoken :: Read s => Int -> AlexInput -> Int -> Alex (Token s)
54 idtoken n (_, _, _, s) len = return (Id n (read ("\"" ++ take len s ++ "\"")))
55 
56 data Token s = Id Int s | EOF deriving Eq
57 
58 lex :: Read s => String -> Either String [Token s]
59 lex inp =
60   let
61     lexAll =
62       do
63         res <- alexMonadScan
64         case res of
65           EOF -> return []
66           tok ->
67             do
68               rest <- lexAll
69               return (tok : rest)
70   in
71     runAlex inp lexAll
72 
73 input = "abab\ndddc.fff\ngh\nijji.\nllmnm\noop.rq0tsst\n3uuvu.5xxw"
74 
75 tokens = [ Id 0 "abab", Id 1 "dddc", Id 2 "fff", Id 3 "gh", Id 4 "ijji",
76            Id 5 "ll", Id 6 "mnm", Id 7 "oop", Id 8 "rq", Id 9 "tsst",
77            Id 10 "uuvu", Id 11 "xxw"]
78 
79 main :: IO ()
80 main =
81   let
82     result = lex input
83   in do
84     case result of
85       Left _ -> exitFailure
86       Right toks ->
87         do
88           if toks /= tokens
89             then exitFailure
90             else exitWith ExitSuccess
91 
92 }
93