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