diff options
Diffstat (limited to 'lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs')
| -rw-r--r-- | lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs index 719fac2..da590ad 100644 --- a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs +++ b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs @@ -1,12 +1,53 @@ module Minilang.Lambda.Parser where -import Data.Text (Text) +import Control.Applicative (Alternative (many), (<|>)) +import Data.Bifunctor (first) +import Data.Text (Text, pack) +import Data.Void (Void) +import Text.Megaparsec (Parsec, between, empty, errorBundlePretty, manyTill, notFollowedBy, optional, parse, try) +import Text.Megaparsec.Char (alphaNumChar, char, letterChar, space1, string, symbolChar) +import qualified Text.Megaparsec.Char.Lexer as L -data ParseError = ParseError +type Parser = Parsec Void Text + +data ParseError = ParseError Text deriving (Eq, Show) data AST = Sym Text deriving (Eq, Show) parse :: Text -> Either ParseError AST -parse = undefined +parse = + first (ParseError . pack . errorBundlePretty) . Text.Megaparsec.parse symbol "" + +symbol :: Parser AST +symbol = Sym . pack <$> identifier + +identifier :: Parser String +identifier = + lexeme $ + (:) + <$> (letterChar <|> extraChars) + <*> many (alphaNumChar <|> extraChars) + +lexeme :: Parser a -> Parser a +lexeme = L.lexeme spaceConsumer + +extraChars :: Parser Char +extraChars = + foldl (\b a -> char a <|> b) symbolChar extraIdentifierChars + +initialChars :: [Char] +initialChars = + ['a' .. 'z'] <> ['A' .. 'Z'] <> extraIdentifierChars + +restChars :: [Char] +restChars = + initialChars <> ['0' .. '9'] + +extraIdentifierChars :: String +extraIdentifierChars = ['-', '_', '*', '#', '%', '&', ':', '@', '/'] + +spaceConsumer :: Parser () +spaceConsumer = + L.space space1 (L.skipLineComment ";") empty |
