Fix parsing of constants (no longer allow empty string or uppercase start).

Add a parser for conjunctive queries.
Add some prettyprinters for the syntax.
This commit is contained in:
Cale Gibbard 2026-01-22 13:35:45 -05:00
parent 0730e7163d
commit c09e07042b
3 changed files with 34 additions and 3 deletions

View File

@ -4,4 +4,4 @@
* We have a basic parser and a very naive evaluator for datalog programs that can extend a database with all the facts which are immediate
consequences of the rules and the current (initially empty) relations, which can be iterated to a fixed point to produce all consequences.
* Added some prettyprinters and a separate parser for conjunctive queries which we needed for the web frontend.

View File

@ -2,10 +2,12 @@ module Datalog.Parser
( parseTerm
, parseAtom
, parseRule
, parseQuery
, parseProgram
)
where
import Control.Applicative (liftA2)
import Datalog.Syntax
import Data.Text (Text)
import Data.Text qualified as T
@ -36,7 +38,7 @@ comma = () <$ symbol ","
period = () <$ symbol "."
parseCon :: (MonadParsec e Text m) => m Term
parseCon = Con . ConId . T.pack <$> lexeme (many alphaNumChar)
parseCon = Con . ConId . T.pack <$> lexeme (liftA2 (:) (numberChar <|> lowerChar) (many alphaNumChar))
parseVar :: (MonadParsec e Text m) => m Term
parseVar = Var . VarId . T.pack <$> lexeme (liftA2 (:) upperChar (many alphaNumChar))
@ -50,6 +52,9 @@ parseAtom = do
args <- parens (parseTerm `sepBy` comma)
return (Atom rel args)
parseQuery :: Parser [Atom]
parseQuery = parseAtom `sepBy` comma
parseFact :: Parser Rule
parseFact = do
headAtom <- parseAtom
@ -59,7 +64,7 @@ parseFact = do
parseRule :: Parser Rule
parseRule = try parseFact <|> do
headAtom <- parseAtom <* symbol ":-"
bodyAtoms <- parseAtom `sepBy` comma
bodyAtoms <- parseQuery
period
return (headAtom :- bodyAtoms)

View File

@ -58,3 +58,29 @@ instance HasConstants Rule where
instance HasConstants Program where
constants (Program rs) = constants rs
class Pretty t where
pretty :: t -> Text
instance Pretty ConId where
pretty (ConId t) = t
instance Pretty VarId where
pretty (VarId t) = t
instance Pretty RelId where
pretty (RelId t) = t
instance Pretty Term where
pretty (Con conId) = pretty conId
pretty (Var varId) = pretty varId
instance Pretty Atom where
pretty (Atom relId terms) = pretty relId <> "(" <> T.intercalate "," (map pretty terms) <> ")"
instance Pretty Rule where
pretty (h :- []) = pretty h <> "."
pretty (h :- ts) = pretty h <> " :- " <> T.intercalate ", " (map pretty ts) <> "."
instance Pretty Program where
pretty (Program rs) = T.unlines (map pretty rs)