-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It didn't really make sense to have all the parser functions using a 'Scanner a' monad - changed the type 'Scanner a' to 'Parser a'. Additionally, renamed some other mis-named features: - scanner -> parser - evalScan -> evalParse - ScanError -> ParseError - scanErrText -> parseErrText - scanner benchmarks -> parser benchmarks
- Loading branch information
1 parent
8e8de9d
commit c226a37
Showing
20 changed files
with
278 additions
and
280 deletions.
There are no files selected for viewing
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
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
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
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
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import Angle.Parse.Parser.Internal | ||
|
||
import Criterion.Main | ||
import Criterion.Types | ||
|
||
main :: IO () | ||
main = defaultMainWith config | ||
[ bgroup "literals" | ||
[ bench "list of 1..10" $ whnf parseListInt [1..10] | ||
, bench "list of 1..100" $ whnf parseListInt [1..100] | ||
--, bench "list of 1..1000" $ whnf parseListInt [1..1000] | ||
] | ||
] | ||
where | ||
config = defaultConfig { timeLimit = 1 } | ||
|
||
|
||
parseListInt xs = evalParse (show xs) langLit |
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{-| | ||
Module : Angle.Parse.Helpers | ||
Description : Defines functions for working with the scanner. | ||
Description : Defines functions for working with the parser. | ||
Copyright : Copyright (C) 2015 Ben Moon | ||
License : GNU GPL, version 3 | ||
Maintainer : [email protected] | ||
|
@@ -10,7 +10,7 @@ Provided functions are split into two categories: | |
[@basic@] the functions that work on standard types. | ||
[@advanced@] higher-order scanners. | ||
[@advanced@] higher-order parsers. | ||
-} | ||
module Angle.Parse.Helpers | ||
( | ||
|
@@ -27,16 +27,16 @@ module Angle.Parse.Helpers | |
, followed | ||
, manyTill | ||
, noneFrom | ||
, notScan | ||
, notParse | ||
, sepWith | ||
, surrounded | ||
, tryScan | ||
, tryParse | ||
, within | ||
, lookAhead | ||
|
||
-- ** Other | ||
, evalScan | ||
, Scanner | ||
, evalParse | ||
, Parser | ||
, SourcePos | ||
, sourcePos | ||
, unexpectedErr | ||
|
@@ -53,74 +53,74 @@ import Angle.Scanner | |
|
||
-- | Succeeds if the predicate function returns | ||
-- true when passed the next character. | ||
cond :: (Char -> Bool) -> Scanner Char | ||
cond f = tryScan $ do | ||
cond :: (Char -> Bool) -> Parser Char | ||
cond f = tryParse $ do | ||
ch <- scanChar | ||
if f ch then return ch | ||
else unexpectedErr ("character: " ++ show ch) | ||
|
||
|
||
-- | Attempt to satisfy the provided scanner, but revert | ||
-- | Attempt to satisfy the provided parser, but revert | ||
-- the state upon failure. | ||
tryScan :: Scanner a -> Scanner a | ||
tryScan sc = do | ||
tryParse :: Parser a -> Parser a | ||
tryParse sc = do | ||
st <- get | ||
sc `catchError` (\e -> do | ||
put st | ||
throwError e) | ||
|
||
|
||
-- | Match the specified character. | ||
char :: Char -> Scanner Char | ||
char :: Char -> Parser Char | ||
char ch = cond (==ch) <?> show ch | ||
|
||
|
||
-- | Matches if character is an element of the provided string. | ||
charFrom :: String -> Scanner Char | ||
charFrom :: String -> Parser Char | ||
charFrom str = cond (`elem` str) | ||
|
||
|
||
-- | Match `str' in its entirety. | ||
string :: String -> Scanner String | ||
string str = tryScan (mapM char str) <?> str | ||
string :: String -> Parser String | ||
string str = tryParse (mapM char str) <?> str | ||
|
||
|
||
-- | @within start end sc@ matches @sc@ between @start@ and @end@. | ||
within :: Scanner a -> Scanner b -> Scanner c -> Scanner c | ||
within :: Parser a -> Parser b -> Parser c -> Parser c | ||
within start end sc = start *> sc <* end | ||
|
||
|
||
-- | @surrounded x@ is the same as @within x x@. | ||
surrounded :: Scanner a -> Scanner b -> Scanner b | ||
surrounded :: Parser a -> Parser b -> Parser b | ||
surrounded surr = within surr surr | ||
|
||
|
||
-- | Parses second scanner before first scanner, returning the result | ||
-- of the second scanner. | ||
followed :: Scanner a -> Scanner b -> Scanner b | ||
-- | Parses second parser before first parser, returning the result | ||
-- of the second parser. | ||
followed :: Parser a -> Parser b -> Parser b | ||
followed f sc = sc <* f | ||
|
||
|
||
-- | Use first Scanner that succeeds. | ||
choice :: [Scanner a] -> Scanner a | ||
-- | Use first Parser that succeeds. | ||
choice :: [Parser a] -> Parser a | ||
choice = msum | ||
|
||
|
||
|
||
|
||
-- | Succeeds if it does not parse the specified character. | ||
notChar :: Char -> Scanner Char | ||
notChar :: Char -> Parser Char | ||
notChar ch = cond (/=ch) | ||
|
||
|
||
-- | Matches any character, only fails when there is no more input. | ||
anyChar :: Scanner Char | ||
anyChar :: Parser Char | ||
anyChar = scanChar <?> "any character" | ||
|
||
|
||
-- | Succeeds if the passed scanner succeeds, but does not consume | ||
-- | Succeeds if the parser succeeds, but does not consume | ||
-- input upon success. | ||
lookAhead :: Scanner a -> Scanner a | ||
lookAhead :: Parser a -> Parser a | ||
lookAhead sc = do | ||
pos <- get | ||
res <- sc | ||
|
@@ -129,25 +129,25 @@ lookAhead sc = do | |
|
||
|
||
-- | Succeeds only if `sc' does not succeed. | ||
notScan :: (Show a) => Scanner a -> Scanner () | ||
notScan sc = tryScan (do | ||
res <- optional (tryScan (lookAhead sc)) | ||
notParse :: (Show a) => Parser a -> Parser () | ||
notParse sc = tryParse (do | ||
res <- optional (tryParse (lookAhead sc)) | ||
case res of Nothing -> return () | ||
Just x -> unexpectedErr (show x)) | ||
|
||
|
||
-- | @noneFrom sc scs@ builds a list of scanners by | ||
-- applying @sc@ to each of @scs@, the resultant scanner | ||
-- then succeeds only if all of the resultant scanners | ||
-- | @noneFrom sc scs@ builds a list of parsers by | ||
-- applying @sc@ to each of @scs@, the resultant parser | ||
-- then succeeds only if all of the resultant parsers | ||
-- fail. | ||
noneFrom :: (Show a) => (a -> Scanner a) -> [a] -> Scanner () | ||
noneFrom scf = notScan . oneFrom | ||
noneFrom :: (Show a) => (a -> Parser a) -> [a] -> Parser () | ||
noneFrom scf = notParse . oneFrom | ||
where oneFrom xs = choice $ map scf xs | ||
|
||
|
||
-- | List of `sc' separated with `sep'. | ||
sepWith :: Scanner a -> Scanner b -> Scanner [b] | ||
sepWith sep sc = tryScan (do | ||
sepWith :: Parser a -> Parser b -> Parser [b] | ||
sepWith sep sc = tryParse (do | ||
fsm <- optional sc | ||
case fsm of | ||
Nothing -> return [] | ||
|
@@ -159,8 +159,8 @@ sepWith sep sc = tryScan (do | |
|
||
|
||
-- | Collect sc until `ti' succeeds. | ||
manyTill :: (Show b) => Scanner b -> Scanner a -> Scanner [a] | ||
manyTill ti sc = many (notScan ti *> sc) | ||
manyTill :: (Show b) => Parser b -> Parser a -> Parser [a] | ||
manyTill ti sc = many (notParse ti *> sc) | ||
|
||
|
||
|
||
|
Oops, something went wrong.