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