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] -> ( |
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 ( |
parseToken (v, "(" : rest) = |
||
bimap |
bimap |
||
(( |
((v <>) . List . return) |
||
tail |
tail |
||
(parseExpr rest) |
(parseExpr rest) |
||
parseToken ( |
parseToken (v, ")" : rest) = (v, rest) |
||
parseToken ( |
parseToken (v, t : rest) = |
||
( |
(v <> List [atom t], rest) |
||
----------------------- TOKEN PARSER --------------------- |
----------------------- TOKEN PARSER --------------------- |
||
atom :: String -> Val |
atom :: String -> Val |
||
atom [] = |
atom [] = mempty |
||
atom s@('"' : _) = |
atom s@('"' : _) = |
||
fromMaybe |
fromMaybe mempty (maybeRead ("String " <> s)) |
||
atom s = |
atom s = |
||
headDef (Symbol s) $ |
headDef (Symbol s) $ |
||
catMaybes $ |
catMaybes $ |
||
maybeRead . ( |
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 ------------------------ |