Commit b77c0dc9 authored by Fred Eisele's avatar Fred Eisele
Browse files

added antlr4 parser and tests

parent 5326d433
......@@ -23,17 +23,31 @@ http://categoricaldata.net/fql.jar
For best results, compile using the [Eclipse IDE](https://eclipse.org/jdt/).
### Maven (may or may not work)
### Gradle
git clone https://github.com/CategoricalData/fql.git
cd fql
mvn package
gradle run --args="-p antlr"
or for the default parser
gradle run --args="-p combinator"
Editor Support
--------------
- AQL mode for Emacs https://github.com/epost/aql-mode
In order to prepare the configuration files for an editor.
gradle idea
or
gradle eclipse
The open the project from the appropriate IDE.
License
-------
......
......@@ -62,6 +62,27 @@
</execution>
</executions>
</plugin>
<!--
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-antlr4-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/gen_src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
......@@ -85,7 +106,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
......@@ -164,6 +185,9 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
......@@ -180,6 +204,12 @@
</snapshotRepository>
</distributionManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>net.sourceforge.collections</groupId>
<artifactId>collections-generic</artifactId>
......@@ -204,7 +234,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
<version>1.4.197</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
......@@ -253,14 +283,14 @@
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.7</version>
<version>4.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.opencsv/opencsv -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.1</version>
<version>4.2</version>
</dependency>
<dependency>
<!-- https://github.com/bobbylight/AutoComplete -->
......
constraints c = literal : (empty : empty) {
forall where -> exists where
}
typeside ty = literal {
types nat
functions 0 1 2 3 : -> nat s : nat -> nat p : nat, nat -> nat
}
constraints c1 = literal : (empty : ty) {
-> exists where p(0,0)=0.s
}
instance I = literal : (empty : ty) {
equations
p(0,0)=0.s
options
require_consistency=false
}
schema s = literal : ty {
entities e
attributes att : e -> nat
}
mapping m = literal : s -> s {
entity
e -> e
attributes
att -> lambda x. p(0,p(x.att, att(x)))
}
query q = literal : s -> s {
entity
e -> {from where
attributes
att -> p(0,0.s)}
}
schema s2 = literal : ty {
entities e
//foreign_keys f : e -> e
attributes att : e -> nat
observation_equations
forall x. x.att.s = 0
}
/* In Instance,
* instanceColimitNode : instanceRef RARROW instanceKind ;
instanceColimitEdge : schemaArrowId RARROW transformKind ;
should be (or possibly + instead of *)
instanceColimitNode : instanceRef* RARROW instanceKind ;
instanceColimitEdge : schemaArrowId* RARROW transformKind ;
In AQL, most places x : y is allowed so is x w z : y
*/
/*
* csv files have 'per block' options - important in practice
*
instance I0 = import_csv "/Users/ryan/Desktop/" : S0 {
Employee -> {Employee -> eId eAsP -> is eSsn -> is
options prover = auto
}
//eId -> eId can be ommitted
Person -> {Person -> pId ssn -> pId options prover = auto}
}
*/
/*
* This confused me. attribute mappings are of the form
* v -> lambda x:t. e
* where :t is optional and e is a term (e.g., f(x,y) or p.q or 3 etc)
* note it is critical that there be exactly one x (i.e., e must have 1 free var)
*
mappingAttributeTerm
: LAMBDA mappingGen (COMMA mappingGen)* DOT evalMappingFn
# MappingAttrTerm_Lambda
*/
/*
* I don't think this is implemented - colimits in the category of schemas and queries may
* be very different that colimits in the category of schemas and mappings.
*
| GET_MAPPING schemaColimitKind schemaRef
#QueryExp_Get
*/
/* aql doesn't treat true and false specially as e.g., the ANTLR grammar does */
/* does it really work to import 'sql' in a typeside? */
\ No newline at end of file
......@@ -217,9 +217,11 @@ instanceQuotientEqn : instancePath EQUAL instancePath ;
instanceChaseSection : allOptions ;
instanceRandomSection
: GENERATORS (schemaEntityId RARROW INTEGER)*
| OPTIONS (RANDOM_SEED EQUAL INTEGER)
: GENERATORS instanceRandomAction*
allOptions
;
instanceRandomAction : schemaEntityId RARROW INTEGER ;
instanceEvalSection : allOptions ;
instanceCoevalSection : allOptions ;
......
......@@ -19,7 +19,7 @@ queryExp
(LBRACE queryDeltaEvalSection RBRACE)?
#QueryExp_ToQuery
| TO_COQUERY schemaKind
| TO_COQUERY mappingKind
(LBRACE queryDeltaCoEvalSection RBRACE)?
#QueryExp_ToCoquery
......
......@@ -81,7 +81,7 @@ evalSchemaFn
| schemaGen # EvalSchemaFn_Gen
| schemaFn LPAREN evalSchemaFn (COMMA evalSchemaFn)* RPAREN
# EvalSchemaFn_Paren
| schemaFn DOT evalSchemaFn # EvalSchemaFn_Dotted
| evalSchemaFn DOT schemaFn # EvalSchemaFn_Dotted
;
schemaGen : symbol (COLON schemaGenType)? ;
......
......@@ -8,14 +8,14 @@ schemaColimitAssignment: SCHEMA_COLIMIT schemaColimitId EQUAL schemaColimitExp ;
schemaColimitExp
: QUOTIENT schemaRef (PLUS schemaRef)* COLON typesideRef
(LBRACE schemaColimitQuotientSection RBRACE)?
(LBRACE schemaColimitQuotientSection allOptions RBRACE)?
# SchemaColimitExp_Quotient
| COPRODUCT schemaRef (PLUS schemaRef)* COLON typesideRef
# SchemaColimitExp_CoProduct
| MODIFY schemaColimitRef
(LBRACE schemaColimitModifySection RBRACE)?
(LBRACE schemaColimitModifySection allOptions RBRACE)?
# SchemaColimitExp_Modify
| WRAP schemaColimitRef mappingRef mappingRef
......@@ -31,11 +31,10 @@ schemaColimitQuotientSection
: (ENTITY_EQUATIONS scQuotientEqu*)?
(PATH_EQUATIONS scQuotientFkEqu*)?
(OBSERVATION_EQUATIONS scObsEquation* )?
allOptions
;
scQuotientEqu : scTermPath EQUAL scTermPath ;
scQuotientFkEqu : scTermPath EQUAL scTermPath ;
scQuotientFkEqu : scSymPath EQUAL scSymPath ;
scObsEquation
: FORALL scGen DOT scTermPath EQUAL scTermPath
......@@ -49,10 +48,26 @@ scTermPath
| schemaTermId # ScTermPath_Singular
;
scSymPath : scAlias (DOT scAlias)* ;
scAlias : symbol ;
scEntityId : symbol ;
scEntityAlias : symbol ;
scFkId : symbol ;
scFkAlias : symbol ;
scAttrId : symbol ;
scAttrAlias : symbol ;
scArrowRenameEnt : scEntityId RARROW scEntityAlias ;
scArrowRenameFk : scEntityAlias DOT scFkId RARROW scFkAlias ;
scArrowRenameAttr : scEntityAlias DOT scAttrId RARROW scAttrAlias ;
scArrowDeleteFk : scEntityAlias DOT scFkId RARROW scFkAlias (DOT scFkAlias)* ;
scArrowDeleteAttr : scEntityAlias DOT scAttrId RARROW scAttrAlias (DOT scAttrAlias)* ;
schemaColimitModifySection
: (RENAME ENTITIES (scTermPath RARROW scTermPath)*)?
(RENAME FOREIGN_KEYS (scTermPath RARROW scTermPath)*)?
(RENAME ATTRIBUTES (scTermPath RARROW scTermPath)*)?
(REMOVE FOREIGN_KEYS (scTermPath RARROW scTermPath)*)?
(REMOVE ATTRIBUTES (scTermPath RARROW scTermPath)*)?
: ( RENAME ENTITIES scArrowRenameEnt*
| RENAME FOREIGN_KEYS scArrowRenameFk*
| RENAME ATTRIBUTES scArrowRenameAttr*
| REMOVE FOREIGN_KEYS scArrowDeleteFk*
| REMOVE ATTRIBUTES scArrowDeleteAttr* )*
;
......@@ -7,6 +7,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
// import java.util.logging.Logger;
import org.jparsec.error.Location;
import org.jparsec.error.ParseErrorDetails;
......@@ -14,6 +15,8 @@ import org.jparsec.error.ParserException;
public class Program<X> implements Prog {
// private static Logger log = Logger.getLogger(Program.class.getName());
//TODO aql
public long timeout() {
if (options.containsKey("timeout")) {
......@@ -95,6 +98,7 @@ public class Program<X> implements Prog {
Util.anomaly();
}
order.add(decl.first);
// log.info(decl.toString());
}
this.options = Util.toMapSafely(options);
this.kindOf = k;
......
......@@ -111,6 +111,7 @@ public class Anonymized<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> extends Instance<Ty
}
};
@SuppressWarnings("hiding")
private <En, Sym, Fk, Att, Gen, Sk> Object iso1(Object obj, Ty ty) {
if (I.schema().typeSide.js.java_tys.containsKey(ty)) {
String ty2 = I.schema().typeSide.js.java_tys.map.get(ty);
......
......@@ -200,23 +200,23 @@ public abstract class Instance<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> implements S
}
public final String toString(String g, String w) {
String toString;
List<String> eqs0 = eqs().stream().map(x -> x.first + " = " + x.second).collect(Collectors.toList());
toString = g;
final StringBuilder sb = new StringBuilder();
final List<String> eqs0 = eqs().stream().map(x -> x.first + " = " + x.second).collect(Collectors.toList());
sb.append(g);
if (!gens().isEmpty()) {
toString += "\n\t" + Util.sep(gens().map, " : ", "\n\t");
sb.append("\n\t" + Util.sep(gens().map, " : ", "\n\t"));
}
if (!sks().isEmpty()) {
toString += "\n\t" + Util.sep(sks().map, " : " , "\n\t");
sb.append("\n\t" + Util.sep(sks().map, " : " , "\n\t"));
}
if (eqs().size() < 1024 * 16) {
if (!eqs0.isEmpty()) {
toString += "\n\n" + w + "\n\t" + Util.sep(eqs0, "\n\t");
sb.append("\n\n" + w + "\n\t" + Util.sep(eqs0, "\n\t"));
}
} else {
toString += "\n\n too many to list \n\n";
sb.append("\n\n too many to list \n\n");
}
return toString.trim();
return sb.toString().trim();
}
@Override
......
......@@ -28,6 +28,7 @@ public class Lineage<Ty,En,Sym,Fk,Att,Gen,Sk> {
return true;
if (obj == null)
return false;
@SuppressWarnings("rawtypes")
Lineage other = (Lineage) obj;
if (i == null) {
if (other.i != null)
......@@ -42,4 +43,4 @@ public class Lineage<Ty,En,Sym,Fk,Att,Gen,Sk> {
return "[" + t + " " + i + "]";
}
}
\ No newline at end of file
}
......@@ -75,12 +75,14 @@ public final class Mapping<Ty,En1,Sym,Fk1,Att1,En2,Fk2,Att2> implements Semantic
}
for (Att1 a : src.atts.keySet()) {
En1 v = src.atts.get(a).first;
@SuppressWarnings("unused")
Ty w = src.atts.get(a).second;
//a = m_v.F(a)
Var x = atts.get(a).first;
Term<Ty, Chc<En1, En2>, Sym, Chc<Chc<Fk1,Fk2>,En1>, Chc<Att1, Att2>, Void, Void> lhs
= Term.Att(Chc.inLeft(a), Term.Var(x));
@SuppressWarnings("unused")
En2 en2 = atts.get(a).second;
Term<Ty, Chc<En1, En2>, Sym, Fk2, Att2, Void, Void> l = atts.get(a).third.mapEn();
Function<Fk2,Chc<Chc<Fk1,Fk2>,En1>> f = xx->Chc.inLeft(Chc.inRight(xx));
......@@ -109,6 +111,7 @@ public final class Mapping<Ty,En1,Sym,Fk1,Att1,En2,Fk2,Att2> implements Semantic
return ret;
}
@SuppressWarnings("hiding")
private <Att1, Att2> Map<Chc<Chc<Att1, Att2>,En1>, Pair<Chc<En1, En2>, Chc<En1,En2>>> or2(Ctx<Att1, Pair<En1, En1>> xs,
Ctx<Att2, Pair<En2, En2>> ys) {
Map<Chc<Chc<Att1, Att2>,En1>, Pair<Chc<En1, En2>, Chc<En1,En2>>> ret = new HashMap<>();
......
......@@ -33,7 +33,7 @@ public final class RawTerm {
@Override
public String toString() {
String str = (annotation == null ? "" : "@" + annotation);
final String str = (annotation == null ? "" : "@" + annotation);
if (args.isEmpty()) {
return head + str;
}
......
......@@ -45,6 +45,7 @@ import catdata.aql.exp.SchExpRaw.Fk;
import catdata.aql.exp.TransExp.TransExpCoEvalEvalCoUnit;
import catdata.aql.exp.TransExp.TransExpCoEvalEvalUnit;
import catdata.aql.exp.TransExp.TransExpId;
import catdata.aql.exp.TransExp.TransExpSigmaDeltaCounit;
import catdata.aql.exp.TransExp.TransExpSigmaDeltaUnit;
import catdata.aql.exp.TyExpRaw.Sym;
import catdata.aql.exp.TyExpRaw.Ty;
......@@ -83,6 +84,7 @@ import catdata.aql.grammar.AqlParser.InstanceKindContext;
import catdata.aql.grammar.AqlParser.InstanceLiteralSectionContext;
import catdata.aql.grammar.AqlParser.InstancePiSectionContext;
import catdata.aql.grammar.AqlParser.InstanceQuotientSectionContext;
import catdata.aql.grammar.AqlParser.InstanceRandomSectionContext;
import catdata.aql.grammar.AqlParser.InstanceRefContext;
import catdata.aql.grammar.AqlParser.InstanceSigmaSectionContext;
import catdata.aql.grammar.AqlParser.InstanceSymbolContext;
......@@ -99,7 +101,9 @@ import catdata.aql.grammar.AqlParser.QueryRefContext;
import catdata.aql.grammar.AqlParser.QuerySimpleSectionContext;
import catdata.aql.grammar.AqlParser.SchemaArrowIdContext;
import catdata.aql.grammar.AqlParser.SchemaColimitKindContext;
import catdata.aql.grammar.AqlParser.SchemaColimitModifySectionContext;
import catdata.aql.grammar.AqlParser.SchemaColimitQuotientSectionContext;
import catdata.aql.grammar.AqlParser.SchemaColimitRefContext;
import catdata.aql.grammar.AqlParser.SchemaEntityIdContext;
import catdata.aql.grammar.AqlParser.SchemaEquationSigContext;
import catdata.aql.grammar.AqlParser.SchemaGenTypeContext;
......@@ -145,39 +149,28 @@ public class AqlLoaderListener extends AqlParserBaseListener {
/**
* The location of tokens is used by the editor.
* It may be better to look up the constant id property.
*
* @param ctx
* @return
*/
private LocStr makeLocStr(ParserRuleContext ctx) {
return new LocStr(ctx.getStart().getStartIndex(), ctx.getText());
return new LocStr(ctx.getStart().getStartIndex(), unquote(ctx.getText()));
}
private Integer getLoc(ParserRuleContext ctx) {
return ctx.getStart().getStartIndex();
}
public AqlLoaderListener() {
this.decls = new LinkedList<>();
this.global_options = new LinkedList<>();
this.kind = q -> q.kind().toString();
public AqlLoaderListener() {}
this.str = new ParseTreeProperty<>();
this.exps = new ParseTreeProperty<>();
this.mapped_terms_1 = new ParseTreeProperty<>();
this.value_option = new ParseTreeProperty<>();
this.terms = new ParseTreeProperty<>();
public final List<Triple<String, Integer, Exp<?>>> decls = new LinkedList<>();
public final List<Pair<String, String>> global_options = new LinkedList<>();
public Function<Exp<?>, String> kind = q -> q.kind().toString();
this.prexps = new ParseTreeProperty<>();
this.mapped_terms_2 = new ParseTreeProperty<>();
this.aopts = new ParseTreeProperty<>();
}
public final List<Triple<String, Integer, Exp<?>>> decls;
public final List<Pair<String, String>> global_options;
public Function<Exp<?>, String> kind;
private final ParseTreeProperty<String> str;
private final ParseTreeProperty<Exp<?>> exps;
private final ParseTreeProperty<RawTerm> terms;
private final ParseTreeProperty<List<String>> path = new ParseTreeProperty<>();
private final ParseTreeProperty<String> str = new ParseTreeProperty<>();
private final ParseTreeProperty<Exp<?>> exps = new ParseTreeProperty<>();
private final ParseTreeProperty<RawTerm> terms = new ParseTreeProperty<>();
public final Map<String, Exp<?>> ns = new HashMap<>();
......@@ -212,13 +205,23 @@ public class AqlLoaderListener extends AqlParserBaseListener {
* Process all options rule
* @param options TODO
*/
private Map<String, String>
toMap(final List<Pair<String,String>> options) {
return options.stream()
.collect(Collectors.toMap(p -> p.first, p -> p.second));
}
private final ParseTreeProperty<List<Pair<String,String>>> aopts;
@SuppressWarnings("unused")
private List<Pair<String,String>>
toList(Map<String, String> opts) {
return opts.entrySet().stream()
.map(x -> new Pair<>(x.getKey(), x.getValue()))
.collect(Collectors.toList());
}
private final ParseTreeProperty<List<Pair<String,String>>>
aopts = new ParseTreeProperty<>();
@Override public void exitAllOptions(AqlParser.AllOptionsContext ctx) {
final List<Pair<String,String>>
......@@ -248,7 +251,7 @@ public class AqlLoaderListener extends AqlParserBaseListener {
* see AqlOptions.g4
*/
private final ParseTreeProperty<Pair<String,String>> value_option;
private final ParseTreeProperty<Pair<String,String>> value_option = new ParseTreeProperty<>();
@Override public void exitOptionsDeclarationSection(AqlParser.OptionsDeclarationSectionContext ctx) {
for(final ParseTree child : ctx.optionsDeclaration() ) {
......@@ -435,7 +438,7 @@ public class AqlLoaderListener extends AqlParserBaseListener {
elt.typesideTypeId().getText());
return elt.typesideConstantId().stream()
.map(id -> new Pair<LocStr, Pair<List<String>, String>>(
.map(id -> new Pair<>(
makeLocStr(id), type))
.collect(Collectors.toList());
})
......@@ -617,15 +620,15 @@ public class AqlLoaderListener extends AqlParserBaseListener {
}
@Override public void exitSchemaExp_GetSchemaColimit(AqlParser.SchemaExp_GetSchemaColimitContext ctx) {
// @SuppressWarnings("unchecked")
// final ColimSchExp<String>
// schColimRef = (ColimSchExp<String>) this.exps.get(ctx.schemaColimitRef());
// TODO review the input to this action
// this.exps.put(ctx, new SchExp.SchExpInst<Ty,En,Sym,Fk,Att>(schColimRef));
@SuppressWarnings("unchecked")
final ColimSchExp<String>
schColimRef = (ColimSchExp<String>) this.exps.get(ctx.schemaColimitRef());
this.exps.put(ctx, new SchExpColim<String>(schColimRef));
}
private final ParseTreeProperty<Quad<String,String,RawTerm,RawTerm>> mapped_terms_2;
private final ParseTreeProperty<Quad<String,String,RawTerm,RawTerm>>
mapped_terms_2 = new ParseTreeProperty<>();
@Override public void exitSchemaExp_Literal(AqlParser.SchemaExp_LiteralContext ctx) {
final SchemaLiteralSectionContext
......@@ -928,7 +931,8 @@ public class AqlLoaderListener extends AqlParserBaseListener {
this.exps.put(ctx,mapping);
}
private final ParseTreeProperty<Triple<String,String,RawTerm>> mapped_terms_1;
private final ParseTreeProperty<Triple<String,String,RawTerm>>
mapped_terms_1 = new ParseTreeProperty<>();
@Override public void exitMappingLiteralSubsection(AqlParser.MappingLiteralSubsectionContext ctx) {
final List<SchemaEntityIdContext>
......@@ -1099,11 +1103,8 @@ public class AqlLoaderListener extends AqlParserBaseListener {
final QueryDeltaCoEvalSectionContext sect = ctx.queryDeltaCoEvalSection();
@SuppressWarnings("unchecked")
final SchExp<Ty,En,Sym, Fk, Att>
schKind = (SchExp<Ty,En,Sym, Fk, Att>) this.exps.get(ctx.schemaKind());
final MapExp<Ty,En,Sym,Fk,Att,En,Fk,Att>
mapExp = new MapExp.MapExpId<Ty,En,Sym,Fk,Att>(schKind);
final MapExp<Ty,En,Sym,Fk,Att,En,Fk,Att>
mapExp = (MapExp<Ty,En,Sym,Fk,Att,En,Fk,Att>) this.exps.get(ctx.mappingKind());
final List<Pair<String,String>>
options = Optional.ofNullable(sect)
......@@ -1137,15 +1138,16 @@ public class AqlLoaderListener extends AqlParserBaseListener {
}
private final ParseTreeProperty<PreBlock> prexps;
private final ParseTreeProperty<PreBlock>
prexps = new ParseTreeProperty<>();
@Override public void exitQueryEx