Last active
February 11, 2018 13:37
-
-
Save robx/482a71be0438a4d02d7d00ba75a679ae 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
module Thing exposing (Thing(..), thing) | |
import List | |
import Parser as P exposing ((|.), (|=), Parser) | |
{- | |
lookAhead : Parser a -> Parser a | |
lookAhead (Parser parse) = | |
Parser <| | |
\state -> | |
case parse state of | |
Bad x _ -> | |
Bad x state | |
Good a _ -> | |
Good a state | |
-} | |
{- | |
Some sample inputs: | |
(12 (34)) | |
(()) | |
(()44) | |
(()()123 (456)) | |
( 11 22 33 ) | |
( 11 ( 22 )( 33) ) | |
(1()2) | |
-} | |
type Thing | |
= Number Int | |
| Things (List Thing) | |
thing : Parser Thing | |
thing = | |
P.oneOf | |
[ number | |
, P.lazy (\_ -> things) | |
] | |
number : Parser Thing | |
number = | |
P.succeed Number | |
|= P.int | |
|. sep | |
things : Parser Thing | |
things = | |
let | |
spaceOrThing = | |
P.oneOf | |
[ P.succeed Nothing |. space | |
, P.succeed Just |= P.lazy (\_ -> thing) | |
] | |
in | |
P.succeed (Things << List.filterMap identity) | |
|. P.symbol "(" | |
|= P.repeat P.zeroOrMore spaceOrThing | |
|. P.symbol ")" | |
sep : Parser () | |
sep = | |
P.oneOf | |
[ space | |
, P.end | |
, P.lookAhead <| | |
P.oneOf | |
[ P.symbol "(" | |
, P.symbol ")" | |
] | |
] | |
space : Parser () | |
space = | |
P.ignore P.oneOrMore (\c -> c == ' ') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment