Datalog Parser annotates SrcLoc

This commit is contained in:
Patrick Aldis 2026-03-03 14:26:31 +00:00
parent f87a3b72dd
commit a967a8e532

View File

@ -1,11 +1,9 @@
{-# LANGUAGE MultilineStrings #-}
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments #-}
{-# LANGUAGE MultilineStrings #-}
module Datalog.Parser ( module Datalog.Parser (
parseTerm, parseTerm,
parseAtom,
parseRule, parseRule,
parseQuery,
parseProgram, parseProgram,
) )
where where
@ -13,7 +11,8 @@ where
import Data.Text (Text) import Data.Text (Text)
import Data.Text qualified as T import Data.Text qualified as T
import Data.Void (Void) import Data.Void (Void)
import Datalog.Syntax import Datalog.Syntax hiding (Atom, Program, Rule, Term)
import Datalog.Syntax (Atom' (..), Program' (..), Rule' (..), Term' (..))
import Text.Megaparsec import Text.Megaparsec
import Text.Megaparsec.Char import Text.Megaparsec.Char
import Text.Megaparsec.Char.Lexer qualified as L import Text.Megaparsec.Char.Lexer qualified as L
@ -21,6 +20,11 @@ import Text.Pretty.Simple
type Parser = Parsec Void Text type Parser = Parsec Void Text
type Atom = Atom' SrcLoc
type Term = Term' SrcLoc
type Rule = Rule' SrcLoc
type Program = Program' SrcLoc
lexeme :: (MonadParsec e Text m) => m a -> m a lexeme :: (MonadParsec e Text m) => m a -> m a
lexeme = L.lexeme whitespace lexeme = L.lexeme whitespace
@ -41,61 +45,46 @@ comma, period :: (MonadParsec e Text m) => m ()
comma = () <$ symbol "," comma = () <$ symbol ","
period = () <$ symbol "." period = () <$ symbol "."
parseCon :: (MonadParsec e Text m) => m Term parseCon :: Parser Term
parseCon = Con () . ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar)) parseCon = parseThingWithSub Con $ ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar))
parseVar :: (MonadParsec e Text m) => m Term parseVar :: Parser Term
parseVar = Var () . VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar)) parseVar = parseThingWithSub Var $ VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar))
parseTerm :: Parser Term parseTerm :: Parser Term
parseTerm = parseVar <|> parseCon parseTerm = parseVar <|> parseCon
parseAtom :: Parser Atom parseAtom :: Parser Atom
parseAtom = do parseAtom = parseThingWithSub (\loc (rel, args) -> Atom loc rel args) do
rel <- RelId . T.pack <$> lexeme (liftA2 (:) lowerChar (many alphaNumChar)) rel <- RelId . T.pack <$> lexeme (liftA2 (:) lowerChar (many alphaNumChar))
args <- parens (parseTerm `sepBy` comma) args <- parens (parseTerm `sepBy` comma)
return (Atom () rel args) return (rel, args)
parseQuery :: Parser [Atom] parseQuery :: Parser [Atom]
parseQuery = parseAtom `sepBy` comma parseQuery = parseAtom `sepBy` comma
parseFact :: Parser Rule
parseFact = do
headAtom <- parseAtom
period
return (Rule () headAtom [])
parseRule :: Parser Rule parseRule :: Parser Rule
parseRule = parseRule = parseThingWithSub (\loc (a, as) -> Rule loc a as) $
try parseFact <|> do try rule1 <|> rule2
where
rule1 = do
headAtom <- parseAtom
period
return (headAtom, [])
rule2 = do
headAtom <- parseAtom <* symbol ":-" headAtom <- parseAtom <* symbol ":-"
bodyAtoms <- parseQuery bodyAtoms <- parseQuery
period period
return (Rule () headAtom bodyAtoms) return (headAtom, bodyAtoms)
parseRule' :: Parser (Rule' SrcLoc)
parseRule' = _
-- parseProgram :: Parser Program parseProgram :: Parser Program
parseProgram :: Parser (Program' SrcLoc) parseProgram = parseThingWithSub Program (many parseRule)
parseProgram = do
-- annotateSrcLoc $ parseThingWithSub :: (SrcLoc -> c -> f SrcLoc) -> Parser c -> Parser (f SrcLoc)
parseThingWithSub f parseSub = do
s <- getSourcePos s <- getSourcePos
c <- many parseRule'
e <- getSourcePos
-- Program _ <$> many parseRule
pure $ Program (SrcLoc s e) c
parseProgram' :: Parser (Program' SrcLoc)
parseProgram' = parseThingWithSub (many parseRule') Program
parseThingWithSub :: (Parser c) -> (SrcLoc -> c -> f SrcLoc) -> Parser (f SrcLoc)
parseThingWithSub parseSub f = do
-- annotateSrcLoc $
s <- getSourcePos
-- c <- many parseRule'
c <- parseSub c <- parseSub
e <- getSourcePos e <- getSourcePos
-- Program _ <$> many parseRule
pure $ f (SrcLoc s e) c pure $ f (SrcLoc s e) c
annotateSrcLoc :: (Functor f) => Parser (f a) -> Parser (f SrcLoc) annotateSrcLoc :: (Functor f) => Parser (f a) -> Parser (f SrcLoc)