S-expressions: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: Adjusted type of parser. Added Val -> Tree for diagramming.)
Line 3,036: Line 3,036:
import Data.List.Split (splitOn)
import Data.List.Split (splitOn)
import Data.Maybe (catMaybes, fromMaybe, listToMaybe)
import Data.Maybe (catMaybes, fromMaybe, listToMaybe)
import Data.Tree (Tree (..), drawForest)
import Data.Tree (Forest, Tree (..), drawForest)


------------------------ DATA TYPE -----------------------
------------------------ DATA TYPE -----------------------
Line 3,046: Line 3,046:
| List [Val]
| List [Val]
deriving (Eq, Show, Read)
deriving (Eq, Show, Read)
instance Semigroup Val where
List a <> List b = List (a <> b)

instance Monoid Val where
mempty = List []


--------------------------- MAIN -------------------------
--------------------------- MAIN -------------------------
Line 3,055: Line 3,061:
" (data (!@# (4.5) \"(more\" \"data)\")))"
" (data (!@# (4.5) \"(more\" \"data)\")))"
]
]
putStrLn $
putStrLn $ drawVal $ fst (parseExpr (tokenized expr))
drawForest $
fmap show
<$> fst (parseExpr (tokenized expr))


------------------- S-EXPRESSION PARSER ------------------
------------------- S-EXPRESSION PARSER ------------------


parseExpr :: [String] -> ([Tree Val], [String])
parseExpr :: [String] -> (Val, [String])
parseExpr = until finished parseToken . ([],)
parseExpr = until finished parseToken . (mempty,)
where
where
finished (_, []) = True
finished (_, []) = True
finished (_, token : _) = ")" == token
finished (_, token : _) = ")" == token


parseToken (trees, "(" : rest) =
parseToken (v, "(" : rest) =
bimap
bimap
((trees <>) . return . Node (Symbol "List"))
((v <>) . List . return)
tail
tail
(parseExpr rest)
(parseExpr rest)
parseToken (trees, ")" : rest) = (trees, rest)
parseToken (v, ")" : rest) = (v, rest)
parseToken (trees, t : rest) =
parseToken (v, t : rest) =
(trees <> [Node (atom t) []], rest)
(v <> List [atom t], rest)


----------------------- TOKEN PARSER ---------------------
----------------------- TOKEN PARSER ---------------------


atom :: String -> Val
atom :: String -> Val
atom [] = List []
atom [] = mempty
atom s@('"' : _) =
atom s@('"' : _) =
fromMaybe (List []) (maybeRead ("String " <> s))
fromMaybe mempty (maybeRead ("String " <> s))
atom s =
atom s =
headDef (Symbol s) $
headDef (Symbol s) $
catMaybes $
catMaybes $
maybeRead . (s <>) . (' ' :) <$> ["Int", "Float"]
maybeRead . (<> (' ' : s)) <$> ["Int", "Float"]


maybeRead :: String -> Maybe Val
maybeRead :: String -> Maybe Val
Line 3,112: Line 3,115:
| c `elem` "()" = ' ' : c : " " <> spacedBrackets cs
| c `elem` "()" = ' ' : c : " " <> spacedBrackets cs
| otherwise = c : spacedBrackets cs
| otherwise = c : spacedBrackets cs

----------------------- DIAGRAMMING ----------------------

drawVal :: Val -> String
drawVal v = drawForest $ fmap (fmap show) (forestFromVal v)

forestFromVal :: Val -> Forest Val
forestFromVal (List xs) = treeFromVal <$> xs

treeFromVal :: Val -> Tree Val
treeFromVal (List xs) =
Node (Symbol "List") (treeFromVal <$> xs)
treeFromVal v = Node v []


------------------------- GENERIC ------------------------
------------------------- GENERIC ------------------------