while-lang-parser (empty) → 0.1.0.0
raw patch · 5 files changed
+280/−0 lines, 5 filesdep +basedep +indentsdep +parsecsetup-changed
Dependencies added: base, indents, parsec
Files
- LICENSE +30/−0
- Language/While/Parser.hs +181/−0
- Language/While/Types.hs +42/−0
- Setup.hs +2/−0
- while-lang-parser.cabal +25/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, David Nilsson And Patrik Berggren++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of David Nilsson And Patrik Berggren nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Language/While/Parser.hs view
@@ -0,0 +1,181 @@+--------------------------------------------------------------------+-- |+-- Module : Language.While.Parser+--+-- Provides parsing of while-language code.+-- Supports reading either a file or stdin, resulting in an AST.++module Language.While.Parser (loadFile, loadStdin) where++import Control.Applicative ((<$>), (<*))+import Control.Monad (liftM)+import Language.While.Types+import Text.Parsec+import Text.Parsec.Expr+import Text.Parsec.Indent+import Text.Parsec.Language (GenLanguageDef)+import Text.Parsec.String+import qualified Text.Parsec.Token as P++-- | Parse the specified file and return either failure or the program.+loadFile :: FilePath -> IO (Either String Stm)+loadFile path = parseString "Failed to parse file; " <$> readFile path++-- | Parse stdin and return either failure or the program.+loadStdin :: IO (Either String Stm)+loadStdin = parseString "Failed to parse stdin; " <$> getContents++-- | Parse the supplied string and return either failure or the program.+parseString errMsg input =+ case parseResult of+ Left err -> Left $ errMsg ++ show err+ Right res -> Right res+ where+ parseResult = runIndent "" $ runParserT program () "" input++-- | Parse a binary operation.+binaryOp name fun = Infix body+ where+ body = reservedOp name >> return fun++-- | Parse a prefix operation, e.g. negation.+prefixOp name fun = Prefix $ reservedOp name >> return fun++-- | Parse a whole program, as a series of statements.+program = do+ whiteSpace+ st <- semiSep consecutive+ return $ foldr1 Scomp . concat $ st++-- | Parse a single statement followed optionally by another one.+-- | Needs to be done due to the while-statement.+consecutive = do+ s1 <- statement+ (s1:) <$> option [] (liftM return statement)++-- | Parse a program statement.+statement+ = try stmAssignment+ <|> try stmTryCatch+ <|> try stmSkip+ <|> try stmIf+ <|> try stmWhile <* whiteSpace+ <|> parens stmWhile <* whiteSpace++-- | Parse an arithmetic atom.+arithmeticAtom+ = Numeral <$> integer+ <|> Variable <$> identifier+ <|> parens arithmeticExpr++-- | Table of supported arithmetic operations.+arithmeticOperation =+ [ [binaryOp "*" Amul AssocLeft]+ , [binaryOp "+" Aadd AssocLeft, binaryOp "-" Asub AssocLeft , binaryOp "/" Adiv AssocLeft ]+ ]++-- Parse an arithmetic expression, consisting of parenthesis and supported operators.+arithmeticExpr = buildExpressionParser arithmeticOperation arithmeticAtom++-- | Since Bexp members operate over different domains,+-- there is some boxing/unboxing being done with WrapAtom.+data WrapAtom+ = BexpW Bexp+ | AexpW Aexp++-- | Parse a boolean atom.+booleanAtom+ = (try (symbol "true") >> truthVal Btrue)+ <|> (try (symbol "false") >> truthVal Bfalse)+ <|> (try $ AexpW <$> arithmeticExpr)+ <|> parens booleanExpr'+ where truthVal = return . BexpW++-- | Table of supported boolean operations.+booleanOperation =+ [ [prefixOp "!" bneg]+ , [binaryOp "=" beq AssocLeft+ , binaryOp "<=" bleq AssocLeft+ , binaryOp "^" band AssocLeft ]+ ]+ where+ bneg (BexpW b) = BexpW $ Bneg b+ beq (AexpW a1) (AexpW a2) = BexpW $ Beq a1 a2+ bleq (AexpW a1) (AexpW a2) = BexpW $ Bleq a1 a2+ band (BexpW b1) (BexpW b2) = BexpW $ Band b1 b2++-- | Parse a boolean expression.+booleanExpr = do+ result <- booleanExpr'+ case result of+ (BexpW val) -> return val+ _ -> error "Parse error: failed to extract boolean"++booleanExpr' = buildExpressionParser booleanOperation booleanAtom++-- | Assignment statement.+stmAssignment = do+ var <- identifier+ symbol ":="+ expr <- arithmeticExpr+ return $ Sass var expr++-- | Skip statement.+stmSkip = symbol "skip" >> return Sskip++-- | If-then-else statement.+stmIf = do+ symbol "if"+ check <- booleanExpr+ symbol "then"+ s1 <- program+ symbol "else"+ s2 <- program+ return $ Sif check s1 s2++-- | While statement.+stmWhile = do+ symbol "while"+ check <- booleanExpr+ symbol "do"++ prog <- liftM (foldr1 Scomp) . block $ do+ s <- statement+ optional semi+ return s++ return $ Swhile check prog++-- | Try-catch statement.+stmTryCatch = do+ symbol "try"+ s1 <- program+ symbol "catch"+ s2 <- program+ return $ Stry s1 s2++identifier = P.identifier whileLexer+integer = P.integer whileLexer+parens = P.parens whileLexer+reservedOp = P.reservedOp whileLexer+semi = P.semi whileLexer+symbol = P.symbol whileLexer+semiSep = P.semiSep whileLexer+whiteSpace = P.whiteSpace whileLexer++whileLexer = P.makeTokenParser whileStyle++whileStyle :: Monad m => GenLanguageDef String u m+whileStyle = P.LanguageDef+ { P.commentStart = ""+ , P.commentEnd = ""+ , P.commentLine = "#"+ , P.nestedComments = True+ , P.identStart = letter <|> char '_'+ , P.identLetter = alphaNum <|> oneOf "_'"+ , P.opStart = P.opLetter whileStyle+ , P.opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~"+ , P.reservedOpNames= []+ , P.reservedNames = []+ , P.caseSensitive = True+ }
+ Language/While/Types.hs view
@@ -0,0 +1,42 @@+--------------------------------------------------------------------+-- |+-- Module : Language.While.Types+--+-- Provides shared type definitions forming the parsed AST.+--++module Language.While.Types where++-- | Variables type alias.+type Varname = String++-- | Arithmetic expressions, including integer division.+data Aexp+ = Numeral Integer+ | Variable Varname + | Aadd Aexp Aexp+ | Asub Aexp Aexp+ | Amul Aexp Aexp+ | Adiv Aexp Aexp+ deriving (Show, Eq)+++-- | Boolean expressions.+data Bexp+ = Btrue+ | Bfalse+ | Beq Aexp Aexp+ | Bleq Aexp Aexp+ | Bneg Bexp+ | Band Bexp Bexp+ deriving (Show, Eq)++-- | Statements, including try-catch clauses.+data Stm+ = Sass Varname Aexp + | Sskip+ | Scomp Stm Stm+ | Sif Bexp Stm Stm+ | Swhile Bexp Stm+ | Stry Stm Stm+ deriving (Show, Eq)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ while-lang-parser.cabal view
@@ -0,0 +1,25 @@+name: while-lang-parser+version: 0.1.0.0+synopsis: Parser for the While language.+description: Parser for the While language described in /Semantics with Applications/ by Nielson and Nielson.++homepage: https://github.com/davnils/while-lang-parser++license: BSD3+license-file: LICENSE++author: David Nilsson And Patrik Berggren+maintainer: nilsson.dd+code@gmail.com++category: Language++build-type: Simple+cabal-version: >=1.8+++library+ exposed-modules: Language.While.Parser, Language.While.Types+ build-depends:+ base >= 4.5 && < 5,+ parsec >= 3.1 && < 4,+ indents >= 0.3 && < 0.4