Datalog Parser annotates SrcLoc
This commit is contained in:
parent
f87a3b72dd
commit
a967a8e532
@ -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
|
parseRule :: Parser Rule
|
||||||
parseFact = do
|
parseRule = parseThingWithSub (\loc (a, as) -> Rule loc a as) $
|
||||||
|
try rule1 <|> rule2
|
||||||
|
where
|
||||||
|
rule1 = do
|
||||||
headAtom <- parseAtom
|
headAtom <- parseAtom
|
||||||
period
|
period
|
||||||
return (Rule () headAtom [])
|
return (headAtom, [])
|
||||||
|
rule2 = do
|
||||||
parseRule :: Parser Rule
|
|
||||||
parseRule =
|
|
||||||
try parseFact <|> 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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user