56 lines
1.4 KiB
Haskell
56 lines
1.4 KiB
Haskell
module Parser where
|
|
|
|
import Monpar
|
|
import Control.Applicative ((<|>), Alternative, many, some)
|
|
import Data.Char (isDigit, digitToInt)
|
|
import Control.Monad (MonadPlus(mzero), void)
|
|
|
|
type ZorthAST = [ZorthExpr]
|
|
|
|
data ZorthExpr = ZorthASTInteger Int
|
|
| ZorthASTWord String
|
|
| ZorthASTWordDecl [ZorthExpr]
|
|
deriving Show
|
|
|
|
word1 :: Parser String
|
|
word1 = do
|
|
x <- sat (\x -> x /= '\n' && x /= ' ')
|
|
xs <- word
|
|
return $ x:xs
|
|
|
|
nonsenseSymbol :: Parser Char
|
|
nonsenseSymbol = char ' ' <|> char '\n'
|
|
|
|
skipNonsenseSymbols :: Parser [Char]
|
|
skipNonsenseSymbols = many nonsenseSymbol
|
|
|
|
digit :: Parser Int
|
|
digit = digitToInt <$> sat isDigit
|
|
|
|
pZorthUnsignedInteger :: Parser ZorthExpr
|
|
pZorthUnsignedInteger = ZorthASTInteger . foldr (\n t -> n + t*10) 0 . reverse <$> some digit
|
|
|
|
pZorthSignedInteger :: Parser ZorthExpr
|
|
pZorthSignedInteger = do
|
|
char '-'
|
|
(ZorthASTInteger i) <- pZorthUnsignedInteger
|
|
return $ ZorthASTInteger $ negate i
|
|
|
|
pZorthInteger :: Parser ZorthExpr
|
|
pZorthInteger = do
|
|
skipNonsenseSymbols
|
|
i <- pZorthSignedInteger <|> pZorthUnsignedInteger
|
|
eof <|> void nonsenseSymbol
|
|
return i
|
|
|
|
pZorthWord :: Parser ZorthExpr
|
|
pZorthWord = do
|
|
skipNonsenseSymbols
|
|
ZorthASTWord <$> word1
|
|
|
|
pZorth :: Parser ZorthAST
|
|
pZorth = some (pZorthInteger <++ pZorthWord)
|
|
|
|
parseZorth :: String -> ZorthAST
|
|
parseZorth = fst . head . runParser pZorth
|