Created
March 16, 2020 15:36
-
-
Save Swendude/466f0617a6fc61ffa4785cd9cee21967 to your computer and use it in GitHub Desktop.
This file contains 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
-- I want to parse sentences like these: | |
-- "There is a #building# over there!" | |
-- Into types like this: | |
-- NonTerminal [Token "There is a ", Symbol "building", Token " over there!" | |
-- However that creates an infite loop | |
import Parser exposing (..) | |
type ProdPart | |
= Symbol String | |
| Token String | |
type Production | |
= Terminal (List ProdPart) | |
| NonTerminal (List ProdPart) | |
parseProd : String -> Result (List DeadEnd) Production | |
parseProd inp = | |
let | |
parsed = run productionParser inp | |
in | |
case parsed of | |
Ok pps -> | |
Ok (NonTerminal pps) | |
Err errors -> | |
Err errors | |
productionParser : Parser (List (ProdPart)) | |
productionParser = | |
succeed identity | |
|= loop [] productionHelper | |
productionHelper : List ProdPart -> Parser (Step (List ProdPart) (List ProdPart)) | |
-- This is where the infinite loop happens | |
productionHelper parts = | |
oneOf [ | |
[ tokenParser |> map (\part -> Loop (part :: parts)) | |
,loop "" symbolParser |> map (\part -> Loop (part :: parts)) | |
,end |> (\_ -> succeed (Done (List.reverse parts))) | |
] | |
tokenParser : Parser ProdPart | |
tokenParser = | |
chompWhile (\c -> c /= '#') | |
|> getChompedString | |
|> map (\part -> Token part) | |
symbolParser : String -> Parser (Step (String) ProdPart) | |
symbolParser loopChunks = | |
oneOf [ | |
token "#" |> map (\_ -> Done (Token loopChunks)) | |
, chompWhile (\c -> c /= '#') |> getChompedString |> map (\chunk -> Loop (loopChunks ++ chunk)) | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment