1 { 2 -- Tests the basic operation. 3 module Main where 4 5 import Data.Char (toUpper) 6 import Control.Monad 7 import System.Exit 8 import System.IO 9 } 10 11 %wrapper "monad" 12 13 @word = [A-Za-z]+ 14 15 tokens :- 16 17 <0> { 18 "αω" { string } 19 [AΓ] { character } 20 . { other } 21 } 22 23 24 { 25 string :: AlexInput -> Int -> Alex String 26 string (_,_,_,_) _ = return "string!" 27 28 other :: AlexInput -> Int -> Alex String 29 other (_,_,_,input) len = return (take len input) 30 31 character :: AlexInput -> Int -> Alex String 32 character (_,_,_,_) _ = return "PING!" 33 34 alexEOF :: Alex String 35 alexEOF = return "stopped." 36 37 scanner :: String -> Either String [String] 38 scanner str = runAlex str $ do 39 let loop = do tok <- alexMonadScan 40 if tok == "stopped." || tok == "error." 41 then return [tok] 42 else do toks <- loop 43 return (tok:toks) 44 loop 45 46 main :: IO () 47 main = do 48 let test1 = scanner str1 49 when (test1 /= out1) $ 50 do hPutStrLn stderr "Test 1 failed:" 51 print test1 52 exitFailure 53 54 let test2 = scanner str2 55 when (test2 /= out2) $ 56 do hPutStrLn stderr "Test 2 failed:" 57 print test2 58 exitFailure 59 60 let test3 = scanner str3 61 when (test3 /= out3) $ 62 do hPutStrLn stderr "Test 3 failed:" 63 print test3 64 exitFailure 65 66 let test4 = scanner str4 67 when (test4 /= out4) $ 68 do hPutStrLn stderr "Test 4 failed:" 69 print test4 70 exitFailure 71 72 73 74 str1 = "A." 75 out1 = Right ["PING!",".","stopped."] 76 77 str2 = "\n" 78 out2 = Left "lexical error at line 1, column 1" 79 80 81 str3 = "αω --" 82 out3 = Right ["string!"," ","-","-","stopped."] 83 84 str4 = "βΓ" 85 out4 = Right ["β","PING!","stopped."] 86 87 } 88