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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
{
-- Tests the basic operation.
module Main where
import Data.Char (toUpper)
import Control.Monad
import System.Exit
import System.IO
import Prelude hiding (null)
}
%wrapper "monad"
@word = [A-Za-z]+
@null = \0
$escchars = [abfnrtv\\"\'&]
@escape = \\ ($escchars | \0)
@gap = \\ $white+ \\
@string = $printable # [\"] | " " | @escape | @gap
@inComment = ([^\*] | $white)+ | ([\*]+ ([\x00-\xff] # [\/]))
tokens :-
$white+ ;
<0> {
@null { null }
@word { word }
\" @string \" { string }
"--" @inComment \n { word }
}
{
{- we can now have comments in source code? -}
word (_,_,_,input) len = return (take len input)
null (_,_,_,_) _ = return "\0"
string (_,_,_,input) _ = return (drop 1 (reverse (drop 1 (reverse input))))
alexEOF = return "stopped."
scanner str = runAlex str $ do
let loop = do tok <- alexMonadScan
if tok == "stopped." || tok == "error."
then return [tok]
else do toks <- loop
return (tok:toks)
loop
main = do
let test1 = scanner str1
when (test1 /= out1) $
do hPutStrLn stderr "Test 1 failed:"
print test1
exitFailure
let test2 = scanner str2
when (test2 /= out2) $
do hPutStrLn stderr "Test 2 failed:"
print test2
exitFailure
str1 = "a\0bb\0ccc\0\0\"\\\0\""
out1 = Right ["a","\NUL","bb","\NUL","ccc","\NUL","\NUL","\\\NUL", "stopped."]
str2 = "."
out2 = Left "lexical error at line 1, column 1"
}
|