Add a parser and use it for reading rules and queries

This commit is contained in:
2023-03-05 21:33:45 -08:00
parent 545416fce0
commit 930a05c951
4 changed files with 79 additions and 34 deletions

View File

@@ -0,0 +1,57 @@
module Language.Bergamot.Parser where
import Prelude
import Language.Bergamot.Syntax (Expr(..))
import Language.Bergamot.Rules (Rule(..), Metavariable)
import Control.Apply (lift2)
import Control.Lazy (defer)
import Parsing (Parser, runParser)
import Parsing.String (char, eof, string)
import Parsing.String.Basic (digit, letter, space)
import Parsing.Combinators (many, many1, sepBy, (<|>))
import Data.Array (fromFoldable)
import Data.Either (hush)
import Data.List (List(..))
import Data.List.NonEmpty (NonEmptyList)
import Data.Maybe (Maybe)
import Data.String (codePointFromChar, fromCodePointArray)
charsToString :: NonEmptyList Char -> String
charsToString = fromCodePointArray <<< fromFoldable <<< map codePointFromChar
whitespace :: Parser String Unit
whitespace = void $ many space
identifier :: Parser String String
identifier = (charsToString <$> many1 (letter <|> digit <|> char '_')) <* whitespace
expr :: Parser String (Expr Metavariable)
expr = (defer $ \_ -> atom) <|> (defer $ \_ -> metavariable)
atom :: Parser String (Expr Metavariable)
atom = lift2 Atom (identifier <* whitespace) (args <|> pure Nil)
where args = char '(' *> sepBy (defer $ \_ -> expr) (char ',' *> whitespace) <* char ')' <* whitespace
metavariable :: Parser String (Expr Metavariable)
metavariable = Var <$> (char '?' *> identifier <* whitespace)
rule :: Parser String (Rule Metavariable)
rule = map MkRule $ pure { head: _, tail: _ } <*> expr <*> (args <|> pure Nil) <* char ';' <* whitespace
where
arrow = (void (char '←') <|> void (string "<-")) <* whitespace
args = arrow *> sepBy expr (char ',' *> whitespace) <* whitespace
rules :: Parser String (List (Rule Metavariable))
rules = many rule
parseRule :: String -> Maybe (Rule Metavariable)
parseRule s = hush $ runParser s (rule <* eof)
parseRules :: String -> Maybe (List (Rule Metavariable))
parseRules s = hush $ runParser s (rules <* eof)
parseQuery :: String -> Maybe (Expr Metavariable)
parseQuery s = hush $ runParser s (expr <* eof)

View File

@@ -16,7 +16,7 @@ import Data.Tuple (fst)
import Data.Newtype (class Newtype)
import Data.Maybe (Maybe(..))
newtype Rule k = MkRule { name :: String, head :: Expr k, tail :: List (Expr k) }
newtype Rule k = MkRule { head :: Expr k, tail :: List (Expr k) }
derive instance Newtype (Rule k) _
derive instance Functor Rule
derive instance Foldable Rule
@@ -26,6 +26,7 @@ type Metavariable = String
type Metavariables k = Map Metavariable k
newtype ProofTree k = MkProofTree { claim :: Expr k, rule :: Rule Metavariable, witnesses :: List (ProofTree k) }
derive instance Functor ProofTree
metavariable :: forall k f m. MonadState (Metavariables k) m => MonadUnify k f m => Metavariable -> m k
metavariable s = do