Skip to content

Commit

Permalink
Rename Scanner type to Parser
Browse files Browse the repository at this point in the history
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
GuiltyDolphin committed Nov 21, 2015
1 parent 8e8de9d commit c226a37
Show file tree
Hide file tree
Showing 20 changed files with 278 additions and 280 deletions.
4 changes: 2 additions & 2 deletions Angle.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ test-suite properties
default-language: Haskell2010


benchmark lexing
benchmark parsing
type: exitcode-stdio-1.0
main-is: lexing.hs
main-is: parsing.hs
hs-source-dirs: benchmarks
build-depends: base
, criterion
Expand Down
10 changes: 5 additions & 5 deletions angle-commandline/Angle/Interpreter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ runFile fp abort = do
Right source -> runLex source
where
runLex source =
case evalScan source program of
case evalParse source program of
Left err -> handleSyntax fp err abort
Right toExec -> executeProg toExec
executeProg toExec = do
Expand All @@ -53,7 +53,7 @@ runFile fp abort = do
Left err -> handleRuntime fp err abort
Right _ -> return ()

handleSyntax :: FilePath -> ScanError -> Bool -> IO ()
handleSyntax :: FilePath -> ParseError -> Bool -> IO ()
handleSyntax fp e abort = do
putStrLn ("Syntax error in file " ++ fp) >> print e
when abort $ exitWith $ ExitFailure 100
Expand All @@ -80,14 +80,14 @@ handleNoFile fp abort e | isDoesNotExistError e = handleNoFile'
--
-- import Angle.Parse.Parser
-- import Angle.Exec.Exec
-- import Angle.Scanner (ScanError)
-- import Angle.Scanner (ParseError)
-- import Angle.Exec.Error
-- import Angle.Exec.Types
-- import Angle.Types.Lang
--
--
-- stringToStmt :: String -> Either ScanError Stmt
-- stringToStmt s = evalScan s program
-- stringToStmt :: String -> Either ParseError Stmt
-- stringToStmt s = evalParse s program
--
--
-- runStmt :: String -> Stmt -> [String] -> IO (Either AngleError LangLit)
Expand Down
6 changes: 3 additions & 3 deletions angle-commandline/Angle/REPL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ collectLine s multi =
runLine :: String -> ExecIO ()
runLine s = do
r <- collectLine s 0
case evalScan r stmt of
case evalParse r stmt of
Left err -> liftIO $ print err
Right res -> do
toPrint <- execStmt res `catchError` (\e -> liftIO (print e) >> throwError e)
Expand All @@ -63,7 +63,7 @@ printSyn = putStrLn . showSyn
interactiveWithFiles :: [FilePath] -> ExecIO ()
interactiveWithFiles fs = do
fileSources <- liftIO $ mapM readFile fs
let asStmts = map (`evalScan` program) fileSources
let asStmts = map (`evalParse` program) fileSources
if not . null $ lefts asStmts
then liftIO $ mapM_ (putStrLn . ("failed to load file: " ++))
[x ++ "\n" ++ show r | (x,Left r) <- zip fs asStmts]
Expand All @@ -78,7 +78,7 @@ interactiveWithFiles fs = do
return ()
return ()
-- withSource s =
-- case evalScan ('{':s++"}") stmt of
-- case evalParse ('{':s++"}") stmt of
-- Left err -> liftIO (print err) >> interactiveMode
-- Right res -> do
-- toPrint <- execStmt res `catchError` (\e -> liftIO (print e) >> throwError e)
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/execution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ main = defaultMainWith config
config = defaultConfig { timeLimit = 1 }


lexListInt xs = evalScan (show xs) langLit
lexListInt xs = evalParse (show xs) langLit
18 changes: 0 additions & 18 deletions benchmarks/lexing.hs

This file was deleted.

18 changes: 18 additions & 0 deletions benchmarks/parsing.hs
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
6 changes: 3 additions & 3 deletions benchmarks/scanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Control.Monad
import Criterion.Main
import Criterion.Types

import Angle.Scanner (scanChar, evalScan)
import Angle.Scanner (scanChar, evalParse)


main :: IO ()
Expand All @@ -25,6 +25,6 @@ main = defaultMainWith config
config = defaultConfig { timeLimit = 1 }


scanSingleLength n = evalScan (replicate n 'A') scanChar
scanSingleLength n = evalParse (replicate n 'A') scanChar

scanSingleLengthFull n = evalScan (replicate n 'A') (replicateM n scanChar)
scanSingleLengthFull n = evalParse (replicate n 'A') (replicateM n scanChar)
4 changes: 2 additions & 2 deletions src/Angle/Exec/Exec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Control.Monad
import Control.Monad.State
import Data.Maybe (isNothing)

import Angle.Parse.Parser (program, evalScan)
import Angle.Parse.Parser (program, evalParse)
import Angle.Exec.Builtins
import Angle.Exec.Error
import Angle.Exec.Operations
Expand Down Expand Up @@ -414,7 +414,7 @@ callBuiltin (LangIdent x) _ = throwImplementationErr $ "callBuiltin - not a buil

builtinEval :: [LangLit] -> ExecIO LangLit
builtinEval xs = do
let r = evalScan st program
let r = evalParse st program
case r of
Left _ -> throwExecError . callBuiltinErr $ "eval: no parse"
Right res -> execStmt res
Expand Down
6 changes: 3 additions & 3 deletions src/Angle/Exec/Interp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import System.Exit

import Angle.Parse.Parser
import Angle.Exec.Exec
import Angle.Scanner (ScanError)
import Angle.Scanner (ParseError)
import Angle.Exec.Error
import Angle.Exec.Types
import Angle.Types.Lang


stringToStmt :: String -> Either ScanError Stmt
stringToStmt s = evalScan s program
stringToStmt :: String -> Either ParseError Stmt
stringToStmt s = evalParse s program


runStmt :: String -> Stmt -> [String] -> IO (Either AngleError LangLit)
Expand Down
10 changes: 5 additions & 5 deletions src/Angle/Exec/REPL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ replOptions = ReplOptions

--processLine :: String -> IO ()
--processLine s = do
-- case evalScan s program of
-- case evalParse s program of
-- Left err -> print err
-- Right res -> runExecIOEnv startEnv (execStmt res) >>= print

-- execLine :: Env -> String -> IO Env
-- execLine e s = case evalScan s program of
-- execLine e s = case evalParse s program of
-- Left err -> print err
-- Right res -> runExecIOEnv (execStmt e) res >>= print

Expand All @@ -60,7 +60,7 @@ collectLine s multi =
runLine :: String -> ExecIO ()
runLine s = do
r <- collectLine s 0
case evalScan r stmt of
case evalParse r stmt of
Left err -> liftIO $ print err
Right res -> do
toPrint <- execStmt res `catchError` (\e -> liftIO (print e) >> throwError e)
Expand Down Expand Up @@ -89,7 +89,7 @@ printSyn = putStrLn . showSyn

withSource :: String -> ExecIO ()
withSource s =
case evalScan ('{':s++"}") stmt of
case evalParse ('{':s++"}") stmt of
Left err -> liftIO (print err) >> mainProg
Right res -> do
toPrint <- execStmt res `catchError` (\e -> liftIO (print e) >> throwError e)
Expand Down Expand Up @@ -137,4 +137,4 @@ main = do
-- lexer to re-parse a small section of code between the
-- statement boundaries and asks for smaller and smaller
-- chunks until the position of the bad token is resolved.
-- (resolvePosition :: Scanner a -> String -> (SourcePos, SourcePos))
-- (resolvePosition :: Parser a -> String -> (SourcePos, SourcePos))
76 changes: 38 additions & 38 deletions src/Angle/Parse/Helpers.hs
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]
Expand All @@ -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
(
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 []
Expand All @@ -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)



Expand Down
Loading

0 comments on commit c226a37

Please sign in to comment.