Compare commits
1 Commits
d28638e286
...
42655b90f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42655b90f5 |
@ -1,18 +1,18 @@
|
|||||||
{-# LANGUAGE MultilineStrings #-}
|
{-# LANGUAGE MultilineStrings #-}
|
||||||
|
|
||||||
module Datalog.Parser (
|
module Datalog.Parser
|
||||||
parseTerm,
|
( parseTerm
|
||||||
parseAtom,
|
, parseAtom
|
||||||
parseRule,
|
, parseRule
|
||||||
parseQuery,
|
, parseQuery
|
||||||
parseProgram,
|
, parseProgram
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
import Datalog.Syntax
|
||||||
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 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
|
||||||
@ -27,11 +27,10 @@ symbol :: (MonadParsec e Text m) => Text -> m Text
|
|||||||
symbol = L.symbol whitespace
|
symbol = L.symbol whitespace
|
||||||
|
|
||||||
whitespace :: (MonadParsec e Text m) => m ()
|
whitespace :: (MonadParsec e Text m) => m ()
|
||||||
whitespace =
|
whitespace = L.space
|
||||||
L.space
|
space1
|
||||||
space1
|
(L.skipLineComment "--")
|
||||||
(L.skipLineComment "--")
|
(L.skipBlockComment "{-" "-}")
|
||||||
(L.skipBlockComment "{-" "-}")
|
|
||||||
|
|
||||||
parens :: (MonadParsec e Text m) => m a -> m a
|
parens :: (MonadParsec e Text m) => m a -> m a
|
||||||
parens = between (symbol "(") (symbol ")")
|
parens = between (symbol "(") (symbol ")")
|
||||||
@ -40,72 +39,63 @@ comma, period :: (MonadParsec e Text m) => m ()
|
|||||||
comma = () <$ symbol ","
|
comma = () <$ symbol ","
|
||||||
period = () <$ symbol "."
|
period = () <$ symbol "."
|
||||||
|
|
||||||
parseCon :: (MonadParsec e Text m) => m Term
|
parseCon :: (MonadParsec e Text m) => m (Term' SrcLoc)
|
||||||
parseCon = Con () . ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar))
|
parseCon = Con dummy . ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar))
|
||||||
|
|
||||||
parseVar :: (MonadParsec e Text m) => m Term
|
parseVar :: (MonadParsec e Text m) => m (Term' SrcLoc)
|
||||||
parseVar = Var () . VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar))
|
parseVar = Var dummy . VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar))
|
||||||
|
|
||||||
parseTerm :: Parser Term
|
parseTerm :: Parser (Term' SrcLoc)
|
||||||
parseTerm = parseVar <|> parseCon
|
parseTerm = parseVar <|> parseCon
|
||||||
|
|
||||||
parseAtom :: Parser (Atom' SrcLoc)
|
parseAtom :: Parser (Atom' SrcLoc)
|
||||||
parseAtom = annotateSrcLoc $ do
|
parseAtom = do
|
||||||
rel <- RelId . T.pack <$> lexeme (liftA2 (:) lowerChar (many alphaNumChar))
|
p <- getSourcePos
|
||||||
args <- parens (parseTerm `sepBy` comma)
|
rel <- RelId . T.pack <$> lexeme (liftA2 (:) lowerChar (many alphaNumChar))
|
||||||
return (Atom () rel args)
|
args <- parens (parseTerm `sepBy` comma)
|
||||||
|
return (Atom SrcLoc{start = p} rel args)
|
||||||
|
|
||||||
parseQuery :: Parser [Atom' SrcLoc]
|
parseQuery :: Parser [Atom' SrcLoc]
|
||||||
parseQuery = parseAtom `sepBy` comma
|
parseQuery = parseAtom `sepBy` comma
|
||||||
|
|
||||||
parseFact :: Parser (Rule' SrcLoc)
|
parseFact :: Parser (Rule' SrcLoc)
|
||||||
parseFact = annotateSrcLoc $ do
|
parseFact = do
|
||||||
headAtom <- parseAtom
|
p <- getSourcePos
|
||||||
period
|
headAtom <- parseAtom
|
||||||
return (Rule NoLoc headAtom [])
|
period
|
||||||
|
return (Rule SrcLoc{start = p} headAtom [])
|
||||||
|
|
||||||
parseRule :: Parser (Rule' SrcLoc)
|
parseRule :: Parser (Rule' SrcLoc)
|
||||||
parseRule =
|
parseRule = try parseFact <|> do
|
||||||
annotateSrcLoc $
|
p <- getSourcePos
|
||||||
try parseFact <|> do
|
headAtom <- parseAtom <* symbol ":-"
|
||||||
headAtom <- parseAtom <* symbol ":-"
|
bodyAtoms <- parseQuery
|
||||||
bodyAtoms <- parseQuery
|
period
|
||||||
period
|
return (Rule SrcLoc{start = p} headAtom bodyAtoms)
|
||||||
return (Rule NoLoc headAtom bodyAtoms)
|
|
||||||
|
|
||||||
parseProgram :: Parser (Program' SrcLoc)
|
parseProgram :: Parser (Program' SrcLoc)
|
||||||
parseProgram = annotateSrcLoc $ Program NoLoc <$> many parseRule
|
parseProgram = Program dummy <$> many parseRule
|
||||||
|
|
||||||
annotateSrcLoc :: (Functor f) => Parser (f a) -> Parser (f SrcLoc)
|
data SrcLoc = SrcLoc
|
||||||
annotateSrcLoc p = do
|
{ start :: SourcePos
|
||||||
s <- getSourcePos
|
-- , end :: (Word, Word)
|
||||||
res <- p
|
} deriving Show
|
||||||
f <- getSourcePos
|
dummy = SrcLoc{start = initialPos "dummy-file"}
|
||||||
pure (SrcLoc s f <$ res)
|
|
||||||
|
|
||||||
data SrcLoc
|
|
||||||
= SrcLoc
|
|
||||||
{ start :: SourcePos
|
|
||||||
, end :: SourcePos
|
|
||||||
}
|
|
||||||
| NoLoc
|
|
||||||
deriving (Show)
|
|
||||||
|
|
||||||
test = do
|
test = do
|
||||||
let r = runParser parseProgram "???" prog
|
let r = runParser parseProgram "???" prog
|
||||||
pPrint @IO r
|
pPrint @IO r
|
||||||
|
|
||||||
prog =
|
prog = """
|
||||||
"""
|
odd(X,Y) :- r(X,Y).
|
||||||
odd(X,Y) :- r(X,Y).
|
odd(X,Y) :- even(X,Z), r(Z,Y).
|
||||||
odd(X,Y) :- even(X,Z), r(Z,Y).
|
even(X,Y) :- odd(X,Z), r(Z,Y).
|
||||||
even(X,Y) :- odd(X,Z), r(Z,Y).
|
|
||||||
|
|
||||||
r(0,1).
|
r(0,1).
|
||||||
r(1,2).
|
r(1,2).
|
||||||
r(2,3).
|
r(2,3).
|
||||||
r(3,4).
|
r(3,4).
|
||||||
r(4,5).
|
r(4,5).
|
||||||
|
|
||||||
r(X,Y) :- r(Y,X).
|
r(X,Y) :- r(Y,X).
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -48,16 +48,6 @@ type Program = Program' ()
|
|||||||
data Program' a = Program a [Rule' a]
|
data Program' a = Program a [Rule' a]
|
||||||
deriving (Eq, Ord, Show)
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
class Decorable t where
|
|
||||||
decorateNode :: a -> t a -> t a
|
|
||||||
|
|
||||||
instance (Decorable Program') where decorateNode x (Program _ rs) = Program x rs
|
|
||||||
instance (Decorable Rule') where decorateNode x (Rule _ a as) = Rule x a as
|
|
||||||
instance (Decorable Atom') where decorateNode x (Atom _ relId ts) = Atom x relId ts
|
|
||||||
instance (Decorable Term') where
|
|
||||||
decorateNode x (Var _ varId) = Var x varId
|
|
||||||
decorateNode x (Con _ conId) = Con x conId
|
|
||||||
|
|
||||||
class HasConstants a where
|
class HasConstants a where
|
||||||
constants :: a -> Set ConId
|
constants :: a -> Set ConId
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user