-
-
Save KiJeong-Lim/da717486ce6fb187dc5d993c0fea75f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Aladdin.Front.Analyzer.Lexer where | |
import Aladdin.Front.Analyzer.Grammar | |
import Aladdin.Front.Header | |
import qualified Control.Monad.Trans.State.Strict as XState | |
import qualified Data.Functor.Identity as XIdentity | |
import qualified Data.Map.Strict as XMap | |
import qualified Data.Set as XSet | |
1 | |
-- the following codes are generated by LGS. | |
-- Warning: The empty string is acceptable! | |
data DFA | |
= DFA | |
{ getInitialQOfDFA :: Int | |
, getFinalQsOfDFA :: XMap.Map Int Int | |
, getTransitionsOfDFA :: XMap.Map (Int, Char) Int | |
, getMarkedQsOfDFA :: XMap.Map Int (Bool, XSet.Set Int) | |
, getPseudoFinalsOfDFA :: XSet.Set Int | |
} | |
deriving () | |
runAladdinLexer :: String -> Either (Int, Int) [Token] | |
runAladdinLexer = runAladdinLexer_this . addLoc 1 1 where | |
-- 0: "abdefzz" | |
-- 1: "abdefz" | |
-- 2: "abdef" | |
-- 3: "abde" | |
-- 4: "abd" | |
-- 5: "ab" | |
-- 6: "a" | |
-- 7: "" | |
-- 8: [. \ 'a'] + "a" ([. \ 'b'] + "b" ([. \ 'd'] + "d" ([. \ 'e'] + "e" ([. \ 'f'] + "f" ([. \ 'z'] + "z" ([. \ 'z'] + "z" [.])))))) + ([. \ 'a'] + "a" ([. \ 'b'] + "b" ([. \ 'd'] + "d" ([. \ 'e'] + "e" ([. \ 'f'] + "f" ([. \ 'z'] + "z" ([. \ 'z'] + "z" [.]))))))) [.]* | |
theDFA :: DFA | |
theDFA = DFA | |
{ getInitialQOfDFA = 7 | |
, getFinalQsOfDFA = XMap.fromAscList [(0, 1), (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2), (7, 2), (8, 2)] | |
, getTransitionsOfDFA = XMap.fromAscList | |
[ ((0, 'a'), 8), ((0, 'b'), 8), ((0, 'c'), 8), ((0, 'd'), 8), ((0, 'e'), 8), ((0, 'f'), 8), ((0, 'g'), 8), ((0, 'h'), 8), ((0, 'i'), 8), ((0, 'j'), 8), ((0, 'k'), 8), ((0, 'l'), 8), ((0, 'm'), 8), ((0, 'n'), 8), ((0, 'o'), 8), ((0, 'p'), 8), ((0, 'q'), 8), ((0, 'r'), 8), ((0, 's'), 8), ((0, 't'), 8), ((0, 'u'), 8), ((0, 'v'), 8), ((0, 'w'), 8), ((0, 'x'), 8), ((0, 'y'), 8), ((0, 'z'), 8) | |
, ((1, 'a'), 8), ((1, 'b'), 8), ((1, 'c'), 8), ((1, 'd'), 8), ((1, 'e'), 8), ((1, 'f'), 8), ((1, 'g'), 8), ((1, 'h'), 8), ((1, 'i'), 8), ((1, 'j'), 8), ((1, 'k'), 8), ((1, 'l'), 8), ((1, 'm'), 8), ((1, 'n'), 8), ((1, 'o'), 8), ((1, 'p'), 8), ((1, 'q'), 8), ((1, 'r'), 8), ((1, 's'), 8), ((1, 't'), 8), ((1, 'u'), 8), ((1, 'v'), 8), ((1, 'w'), 8), ((1, 'x'), 8), ((1, 'y'), 8), ((1, 'z'), 0) | |
, ((2, 'a'), 8), ((2, 'b'), 8), ((2, 'c'), 8), ((2, 'd'), 8), ((2, 'e'), 8), ((2, 'f'), 8), ((2, 'g'), 8), ((2, 'h'), 8), ((2, 'i'), 8), ((2, 'j'), 8), ((2, 'k'), 8), ((2, 'l'), 8), ((2, 'm'), 8), ((2, 'n'), 8), ((2, 'o'), 8), ((2, 'p'), 8), ((2, 'q'), 8), ((2, 'r'), 8), ((2, 's'), 8), ((2, 't'), 8), ((2, 'u'), 8), ((2, 'v'), 8), ((2, 'w'), 8), ((2, 'x'), 8), ((2, 'y'), 8), ((2, 'z'), 1) | |
, ((3, 'a'), 8), ((3, 'b'), 8), ((3, 'c'), 8), ((3, 'd'), 8), ((3, 'e'), 8), ((3, 'f'), 2), ((3, 'g'), 8), ((3, 'h'), 8), ((3, 'i'), 8), ((3, 'j'), 8), ((3, 'k'), 8), ((3, 'l'), 8), ((3, 'm'), 8), ((3, 'n'), 8), ((3, 'o'), 8), ((3, 'p'), 8), ((3, 'q'), 8), ((3, 'r'), 8), ((3, 's'), 8), ((3, 't'), 8), ((3, 'u'), 8), ((3, 'v'), 8), ((3, 'w'), 8), ((3, 'x'), 8), ((3, 'y'), 8), ((3, 'z'), 8) | |
, ((4, 'a'), 8), ((4, 'b'), 8), ((4, 'c'), 8), ((4, 'd'), 8), ((4, 'e'), 3), ((4, 'f'), 8), ((4, 'g'), 8), ((4, 'h'), 8), ((4, 'i'), 8), ((4, 'j'), 8), ((4, 'k'), 8), ((4, 'l'), 8), ((4, 'm'), 8), ((4, 'n'), 8), ((4, 'o'), 8), ((4, 'p'), 8), ((4, 'q'), 8), ((4, 'r'), 8), ((4, 's'), 8), ((4, 't'), 8), ((4, 'u'), 8), ((4, 'v'), 8), ((4, 'w'), 8), ((4, 'x'), 8), ((4, 'y'), 8), ((4, 'z'), 8) | |
, ((5, 'a'), 8), ((5, 'b'), 8), ((5, 'c'), 8), ((5, 'd'), 4), ((5, 'e'), 8), ((5, 'f'), 8), ((5, 'g'), 8), ((5, 'h'), 8), ((5, 'i'), 8), ((5, 'j'), 8), ((5, 'k'), 8), ((5, 'l'), 8), ((5, 'm'), 8), ((5, 'n'), 8), ((5, 'o'), 8), ((5, 'p'), 8), ((5, 'q'), 8), ((5, 'r'), 8), ((5, 's'), 8), ((5, 't'), 8), ((5, 'u'), 8), ((5, 'v'), 8), ((5, 'w'), 8), ((5, 'x'), 8), ((5, 'y'), 8), ((5, 'z'), 8) | |
, ((6, 'a'), 8), ((6, 'b'), 5), ((6, 'c'), 8), ((6, 'd'), 8), ((6, 'e'), 8), ((6, 'f'), 8), ((6, 'g'), 8), ((6, 'h'), 8), ((6, 'i'), 8), ((6, 'j'), 8), ((6, 'k'), 8), ((6, 'l'), 8), ((6, 'm'), 8), ((6, 'n'), 8), ((6, 'o'), 8), ((6, 'p'), 8), ((6, 'q'), 8), ((6, 'r'), 8), ((6, 's'), 8), ((6, 't'), 8), ((6, 'u'), 8), ((6, 'v'), 8), ((6, 'w'), 8), ((6, 'x'), 8), ((6, 'y'), 8), ((6, 'z'), 8) | |
, ((7, 'a'), 6), ((7, 'b'), 8), ((7, 'c'), 8), ((7, 'd'), 8), ((7, 'e'), 8), ((7, 'f'), 8), ((7, 'g'), 8), ((7, 'h'), 8), ((7, 'i'), 8), ((7, 'j'), 8), ((7, 'k'), 8), ((7, 'l'), 8), ((7, 'm'), 8), ((7, 'n'), 8), ((7, 'o'), 8), ((7, 'p'), 8), ((7, 'q'), 8), ((7, 'r'), 8), ((7, 's'), 8), ((7, 't'), 8), ((7, 'u'), 8), ((7, 'v'), 8), ((7, 'w'), 8), ((7, 'x'), 8), ((7, 'y'), 8), ((7, 'z'), 8) | |
, ((8, 'a'), 8), ((8, 'b'), 8), ((8, 'c'), 8), ((8, 'd'), 8), ((8, 'e'), 8), ((8, 'f'), 8), ((8, 'g'), 8), ((8, 'h'), 8), ((8, 'i'), 8), ((8, 'j'), 8), ((8, 'k'), 8), ((8, 'l'), 8), ((8, 'm'), 8), ((8, 'n'), 8), ((8, 'o'), 8), ((8, 'p'), 8), ((8, 'q'), 8), ((8, 'r'), 8), ((8, 's'), 8), ((8, 't'), 8), ((8, 'u'), 8), ((8, 'v'), 8), ((8, 'w'), 8), ((8, 'x'), 8), ((8, 'y'), 8), ((8, 'z'), 8) | |
] | |
, getMarkedQsOfDFA = XMap.fromAscList [] | |
, getPseudoFinalsOfDFA = XSet.fromAscList [] | |
} | |
runDFA :: DFA -> [((Int, Int), Char)] -> Either (Int, Int) ((Maybe Int, [((Int, Int), Char)]), [((Int, Int), Char)]) | |
runDFA (DFA q0 qfs deltas markeds pseudo_finals) = if XSet.null pseudo_finals then Right . XIdentity.runIdentity . runFast else runSlow where | |
loop1 :: Int -> [((Int, Int), Char)] -> [((Int, Int), Char)] -> XState.StateT (Maybe Int, [((Int, Int), Char)]) XIdentity.Identity [((Int, Int), Char)] | |
loop1 q buffer [] = return buffer | |
loop1 q buffer (ch : str) = do | |
(latest, accepted) <- XState.get | |
case XMap.lookup (q, snd ch) deltas of | |
Nothing -> return (buffer ++ [ch] ++ str) | |
Just p -> case XMap.lookup p qfs of | |
Nothing -> loop1 p (buffer ++ [ch]) str | |
latest' -> do | |
XState.put (latest', accepted ++ buffer ++ [ch]) | |
loop1 p [] str | |
loop2 :: XSet.Set Int -> Int -> [((Int, Int), Char)] -> [((Int, Int), Char)] -> XState.StateT [((Int, Int), Char)] XIdentity.Identity [((Int, Int), Char)] | |
loop2 qs q [] buffer = return buffer | |
loop2 qs q (ch : str) buffer = do | |
case XMap.lookup (q, snd ch) deltas of | |
Nothing -> return (buffer ++ [ch] ++ str) | |
Just p -> case p `XSet.member` qs of | |
False -> loop2 qs p str (buffer ++ [ch]) | |
True -> do | |
accepted <- XState.get | |
XState.put (accepted ++ buffer ++ [ch]) | |
loop2 qs p str [] | |
loop3 :: XSet.Set Int -> Int -> [((Int, Int), Char)] -> [((Int, Int), Char)] -> XState.StateT [((Int, Int), Char)] XIdentity.Identity [((Int, Int), Char)] | |
loop3 qs q [] buffer = return buffer | |
loop3 qs q (ch : str) buffer = do | |
case XMap.lookup (q, snd ch) deltas of | |
Nothing -> return (buffer ++ [ch] ++ str) | |
Just p -> case p `XSet.member` qs of | |
False -> loop3 qs p str (buffer ++ [ch]) | |
True -> do | |
accepted <- XState.get | |
XState.put (accepted ++ buffer ++ [ch]) | |
return str | |
runFast :: [((Int, Int), Char)] -> XIdentity.Identity ((Maybe Int, [((Int, Int), Char)]), [((Int, Int), Char)]) | |
runFast input = do | |
(rest, (latest, accepted)) <- XState.runStateT (loop1 q0 [] input) (Nothing, []) | |
case latest >>= flip XMap.lookup markeds of | |
Nothing -> return ((latest, accepted), rest) | |
Just (True, qs) -> do | |
(rest', accepted') <- XState.runStateT (loop2 qs q0 accepted []) [] | |
return ((latest, accepted'), rest' ++ rest) | |
Just (False, qs) -> do | |
(rest', accepted') <- XState.runStateT (loop3 qs q0 accepted []) [] | |
return ((latest, accepted'), rest' ++ rest) | |
runSlow :: [((Int, Int), Char)] -> Either (Int, Int) ((Maybe Int, [((Int, Int), Char)]), [((Int, Int), Char)]) | |
runSlow = undefined | |
addLoc :: Int -> Int -> String -> [((Int, Int), Char)] | |
addLoc _ _ [] = [] | |
addLoc row col (ch : chs) = if ch == '\n' then ((row, col), ch) : addLoc (row + 1) 1 chs else ((row, col), ch) : addLoc row (col + 1) chs | |
runAladdinLexer_this :: [((Int, Int), Char)] -> Either (Int, Int) [Token] | |
runAladdinLexer_this [] = return [] | |
runAladdinLexer_this str0 = do | |
let return_one my_token = return [my_token] | |
dfa_output <- runDFA theDFA str0 | |
(str1, piece) <- case dfa_output of | |
((_, []), _) -> Left (fst (head str0)) | |
((Just label, accepted), rest) -> return (rest, ((label, map snd accepted), (fst (head accepted), fst (head (reverse accepted))))) | |
_ -> Left (fst (head str0)) | |
tokens1 <- case piece of | |
((1, this), ((row1, col1), (row2, col2))) -> return_one (T_q) | |
((2, this), ((row1, col1), (row2, col2))) -> return_one (skip) | |
tokens2 <- runAladdinLexer_this str1 | |
return (tokens1 ++ tokens2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment