Skip to content

Instantly share code, notes, and snippets.

@KiJeong-Lim
Created March 11, 2023 12:12
Show Gist options
  • Save KiJeong-Lim/da717486ce6fb187dc5d993c0fea75f2 to your computer and use it in GitHub Desktop.
Save KiJeong-Lim/da717486ce6fb187dc5d993c0fea75f2 to your computer and use it in GitHub Desktop.
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