Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/HarvardPL/AbcDatalog/llms.txt

Use this file to discover all available pages before exploring further.

AbcDatalog includes a recursive-descent parser that converts Datalog source text into the Clause-based AST described in the AST overview. The entry point is always a DatalogTokenizer wrapping a java.io.Reader, which is then passed to the static methods of DatalogParser. Parsing can throw DatalogParseException for any syntax error. Datalog text conventions: identifiers consist of letters, digits, and underscores. An identifier that starts with an uppercase letter or _ is parsed as a variable; all others are parsed as constants or predicate symbols. The % character begins a single-line comment. Clauses end with . and queries end with ?.

DatalogTokenizer

DatalogTokenizer wraps a java.io.Reader and produces a stream of string tokens consumed by DatalogParser.

Constructor

public DatalogTokenizer(Reader r)
r
Reader
required
Any java.io.Reader — typically a StringReader for in-memory text or a FileReader / BufferedReader for files.
DatalogTokenizer is stateful and advances linearly through the input. Once tokens have been consumed by a parser call, they cannot be re-read. Create a new tokenizer if you need to parse the same input again.

Token-level methods

MethodDescription
boolean hasNext()Returns true if there is at least one token remaining in the stream.
String next()Consumes and returns the next token. Throws DatalogParseException at EOF.
String peek()Returns the next token without consuming it. Throws DatalogParseException at EOF.
void consume(String s)Consumes the exact string s from the stream, throwing DatalogParseException if it does not match.

DatalogParser

DatalogParser is a non-instantiable utility class — all methods are static.

parseProgram

public static Set<Clause> parseProgram(DatalogTokenizer t) throws DatalogParseException
Parses all clauses from the token stream until EOF and returns them as a Set<Clause>. Each clause must be in the form head. or head :- body..
t
DatalogTokenizer
required
The token stream for the complete program text.
result
Set<Clause>
The full set of parsed clauses, including both facts and rules.

parseQuery

public static PositiveAtom parseQuery(DatalogTokenizer t) throws DatalogParseException
Parses a single query atom followed by ? from the token stream. For example, the text tc(X, Y)? parses to a PositiveAtom with predicate tc and variables X, Y.
t
DatalogTokenizer
required
The token stream positioned at the start of a query expression ending in ?.
result
PositiveAtom
The parsed query atom.

parseClauseAsPositiveAtom

public static PositiveAtom parseClauseAsPositiveAtom(DatalogTokenizer t)
    throws DatalogParseException
Parses a single atom followed by . from the token stream. This is convenient for reading individual ground facts from a token stream incrementally (e.g., facts arriving at runtime for a DatalogExecutor).
t
DatalogTokenizer
required
The token stream positioned at the start of an atom ending in ..
result
PositiveAtom
The parsed atom.

parsePositiveAtom

public static PositiveAtom parsePositiveAtom(DatalogTokenizer t) throws DatalogParseException
Parses a single positive atom without requiring a trailing . or ?. This lower-level method is useful when you need to read an atom embedded in a larger custom parsing context.
t
DatalogTokenizer
required
The token stream positioned at the start of an atom.
result
PositiveAtom
The parsed atom.

DatalogParseException

DatalogParseException is a checked exception thrown by all parser and tokenizer methods on any syntax error, unexpected token, or premature EOF. It extends Exception and provides four constructors covering the standard (message), (cause), (message, cause), and full (message, cause, enableSuppression, writableStackTrace) forms.

Code examples

Parse a program from a String

import edu.harvard.seas.pl.abcdatalog.ast.Clause;
import edu.harvard.seas.pl.abcdatalog.parser.DatalogParser;
import edu.harvard.seas.pl.abcdatalog.parser.DatalogTokenizer;
import java.io.StringReader;
import java.util.Set;

String src =
    "edge(a,b). edge(b,c)."
    + "tc(X,Y) :- edge(X,Y)."
    + "tc(X,Y) :- tc(X,Z), tc(Z,Y).";

DatalogTokenizer t = new DatalogTokenizer(new StringReader(src));
Set<Clause> clauses = DatalogParser.parseProgram(t);

Parse a program from a file

import java.io.BufferedReader;
import java.io.FileReader;

DatalogTokenizer t = new DatalogTokenizer(
    new BufferedReader(new FileReader("program.dl")));
Set<Clause> clauses = DatalogParser.parseProgram(t);

Parse a query

DatalogTokenizer qt = new DatalogTokenizer(new StringReader("tc(a, Y)?"));
PositiveAtom query = DatalogParser.parseQuery(qt);

Parse individual facts incrementally

This pattern is used by DatalogExecutor.addFactAsynchronously:
String facts = "edge(2,3). edge(3,4). edge(4,0).";
DatalogTokenizer ft = new DatalogTokenizer(new StringReader(facts));
while (ft.hasNext()) {
    PositiveAtom fact = DatalogParser.parseClauseAsPositiveAtom(ft);
    executor.addFactAsynchronously(fact);
}

Build docs developers (and LLMs) love