Skip to content

Instantly share code, notes, and snippets.

@osfameron
Last active August 29, 2020 15:38
Show Gist options
  • Save osfameron/50e21866fe564d15d9b4c97457c4e609 to your computer and use it in GitHub Desktop.
Save osfameron/50e21866fe564d15d9b4c97457c4e609 to your computer and use it in GitHub Desktop.
chainl1 parser example in PureScript
-- attempt to port `chainl1` example from
-- https://hackage.haskell.org/package/parsec-3.1.14.0/docs/Text-Parsec-Combinator.html#v:chainl1
module Main where
import Prelude hiding (between)
import Text.Parsing.StringParser
import Text.Parsing.StringParser.Combinators
import Text.Parsing.StringParser.CodePoints
import Control.Alt
import Partial.Unsafe
import Data.Maybe
import Data.Int as I
import Control.Lazy
parens :: forall a. Parser a -> Parser a
parens = between (string "(") (string ")")
{- the following all have errors like:
The value of term is undefined here, so this reference is not allowed.
PureScript(CycleInDeclaration)
-}
expr = defer (\_ -> term) `chainl1` addop
term = defer (\_ -> factor) `chainl1` mulop
factor = (parens $ defer (\_ -> expr)) <|> int
int :: Parser Int
int =
toInt <$> regex "[0-9]+"
where
toInt :: String -> Int
toInt = unsafePartial fromJust <<< I.fromString
skip :: forall a. Parser a -> Parser Unit
skip = void
mulop =
do
skip $ string "*"
pure (*)
<|> do
skip $ string "/"
pure (/)
addop =
do
skip $ string "+"
pure (+)
<|> do
skip $ string "-"
pure (-)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment