Le support aux utilisateurs et les demandes de création de comptes externes doivent être faites depuis les issues du projet GitLab HEFR (https://gitlab.forge.hefr.ch/forge-hefr/gitlab-hefr)

Commit 6622d1b8 authored by Tony Licata's avatar Tony Licata
Browse files

ProloGraal doesn't use clauses to store prolog queries anymore, prolog queries...

ProloGraal doesn't use clauses to store prolog queries anymore, prolog queries are now stocked into ProloGraalQuery instances. Modified parser to handle two behaviour, parsing queries or parsing clauses
parent 1e6a869c
......@@ -66,11 +66,11 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
@Override
protected CallTarget parse(ParsingRequest request) {
Source source = request.getSource();
List<ProloGraalClause> requestedClauses = new ArrayList<>();
List<ProloGraalQuery> queries = new ArrayList<>();
if (request.getArgumentNames().isEmpty()) {
long time = System.currentTimeMillis();
requestedClauses = ProloGraalParserImpl.parseProloGraal(source);
queries = ProloGraalParserImpl.parseProloGraal(source);
long time2 = System.currentTimeMillis();
if (DEBUG_MODE) {
System.out.println("Parsing time : " + (time2 - time) + "ms");
......@@ -79,7 +79,7 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
ProloGraalRuntime runtime = new ProloGraalRuntime(this.getContextReference().get());
RootNode eval = new ProloGraalEvalRootNode(this, runtime,requestedClauses);
RootNode eval = new ProloGraalEvalRootNode(this, runtime, queries);
return Truffle.getRuntime().createCallTarget(eval);
}
......
......@@ -57,7 +57,7 @@ public final class ProloGraalConsultBuiltin extends ProloGraalBuiltinClause {
}
Source source = Source.newBuilder(ProloGraalLanguage.ID, fileContent, null).build();
//we filter clauses to remove goal lists from returned clauses
List<ProloGraalClause> clauses = ProloGraalParserImpl.parseProloGraal(source).stream().filter(proloGraalClause -> proloGraalClause.getHead() != null).collect(Collectors.toList());
List<ProloGraalClause> clauses = ProloGraalParserImpl.parseClauses(source).stream().filter(proloGraalClause -> proloGraalClause.getHead() != null).collect(Collectors.toList());
context.getRuntime().addProloGraalClauses(clauses);
return new ProloGraalSuccess(getVariables());
......
......@@ -45,7 +45,7 @@ public final class ProloGraalConsultStringBuiltin extends ProloGraalBuiltinClaus
consultContentString = consultContentString.substring(1,consultContentString.length()-1);
Source source = Source.newBuilder(ProloGraalLanguage.ID, consultContentString, null).build();
//we filter clauses to remove goal lists from returned clauses
List<ProloGraalClause> clauses = ProloGraalParserImpl.parseProloGraal(source).stream().filter(proloGraalClause -> proloGraalClause.getHead()!=null).collect(Collectors.toList());
List<ProloGraalClause> clauses = ProloGraalParserImpl.parseClauses(source);
context.getRuntime().addProloGraalClauses(clauses);
return new ProloGraalSuccess(getVariables());
}else{
......
......@@ -26,15 +26,15 @@ public final class ProloGraalEvalRootNode extends RootNode {
@CompilationFinal
private boolean registered;
private final List<ProloGraalClause> requests;
private final List<ProloGraalQuery> queries;
private final ContextReference<ProloGraalContext> reference;
public ProloGraalEvalRootNode(ProloGraalLanguage language, ProloGraalRuntime runtime, List<ProloGraalClause> requests) {
public ProloGraalEvalRootNode(ProloGraalLanguage language, ProloGraalRuntime runtime, List<ProloGraalQuery> queries) {
super(null); // internal frame
this.runtime = runtime;
this.language = language;
this.reference = language.getContextReference();
this.requests = requests;
this.queries = queries;
}
@Override
......@@ -66,17 +66,19 @@ public final class ProloGraalEvalRootNode extends RootNode {
ArrayList<ProloGraalBoolean> answers = new ArrayList<>();
for(ProloGraalClause request : requests){
for(ProloGraalQuery request : queries){
Deque<Integer> currentBranches = new ArrayDeque<>();
ProloGraalClause goal = new ProloGraalClause();
goal.setHead(new ProloGraalAtom(request.getVariables(),"goals"));
/*
if(request.getGoals().size()==0){
goal.addGoal(request.getHead());
}else if(request.getGoals().size()>0 && request.getHead() == null){
request.getGoals().forEach(proloGraalTerm -> goal.addGoal(proloGraalTerm));
} else{
continue;
}
} */
request.getGoals().forEach(proloGraalTerm -> goal.addGoal(proloGraalTerm));
ProloGraalRuntime runtime;
runtime = new ProloGraalRuntime(language.getContextReference().get());
runtime.addProloGraalClause(goal);
......
......@@ -125,7 +125,7 @@ public class ProloGraalInterpreterNode extends RootNode {
if (!skipParsing) {
// parse the source to get a runtime
runtime = new ProloGraalRuntime(language.getContextReference().get());
runtime.addProloGraalClauses(ProloGraalParserImpl.parseProloGraal(source));
runtime.addProloGraalClauses(ProloGraalParserImpl.parseClauses(source));
lastRuntime = runtime;
} else {
runtime = lastRuntime;
......
......@@ -8,7 +8,7 @@ grammar ProloGraal;
// parser
prolograal :
clause* EOF // zero or more clauses and the EOF
(clause | query)* EOF // zero or more clauses or queries and the EOF
;
// an atom can be the lexical definition of an atom or an empty list
......@@ -66,10 +66,14 @@ composedClause :
head CLAUSE_MARKER goalList
;
// a query is a goalList.
query :
goalList
;
// a clause is either a fact, a goal list or a composed clause
clause :
fact |
goalList | //TODO clause can temporary be a goalList
composedClause
;
......
......@@ -155,6 +155,18 @@ public class ProloGraalBaseListener implements ProloGraalListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitComposedClause(ProloGraalParser.ComposedClauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterQuery(ProloGraalParser.QueryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitQuery(ProloGraalParser.QueryContext ctx) { }
/**
* {@inheritDoc}
*
......
......@@ -127,6 +127,16 @@ public interface ProloGraalListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitComposedClause(ProloGraalParser.ComposedClauseContext ctx);
/**
* Enter a parse tree produced by {@link ProloGraalParser#query}.
* @param ctx the parse tree
*/
void enterQuery(ProloGraalParser.QueryContext ctx);
/**
* Exit a parse tree produced by {@link ProloGraalParser#query}.
* @param ctx the parse tree
*/
void exitQuery(ProloGraalParser.QueryContext ctx);
/**
* Enter a parse tree produced by {@link ProloGraalParser#clause}.
* @param ctx the parse tree
......
......@@ -26,10 +26,39 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
private Deque<ProloGraalTerm<?>> elements = new ArrayDeque<>();
// stack of final clauses
private Deque<ProloGraalClause> clauses = new ArrayDeque<>();
// stack of final queries
private Deque<ProloGraalQuery> queries = new ArrayDeque<>();
private boolean parsingClauses = false;
// provides temporary storage for the tail of a list since it needs special handling
private ProloGraalTerm<?> tail;
public void setParsingClauses(boolean parsingClauses){
this.parsingClauses = parsingClauses;
}
/**
* Returns the queries parsed from the file. Must be called after walking through the tree using the default
* {@link org.antlr.v4.runtime.tree.ParseTreeWalker}.
* @return The list of parsed clauses, in order of encounter in the source file
*/
public List<ProloGraalQuery> getQueries() {
List<ProloGraalQuery> r = new ArrayList<>();
// we use a descending iterator to reverse the order of the clauses
// since a stack is LIFO and we need to read FIFO to get the correct order
Iterator<ProloGraalQuery> it = queries.descendingIterator();
it.forEachRemaining(r::add);
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println(r);
}
return r;
}
/**
* Returns the clauses parsed from the file. Must be called after walking through the tree using the default
* {@link org.antlr.v4.runtime.tree.ParseTreeWalker}.
......@@ -52,7 +81,8 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
}
public void debug() {
System.out.println(clauses.stream().map(x -> x.toString() + "\n").collect(Collectors.joining()));
System.out.println("Clauses:\n"+clauses.stream().map(x -> x.toString() + "\n").collect(Collectors.joining()));
System.out.println("Queries:\n"+queries.stream().map(x -> x.toString() + "\n").collect(Collectors.joining()));
}
private void throwParseError(ParserRuleContext ctx, String message) {
......@@ -60,29 +90,67 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
message);
}
private Map<ProloGraalVariable, ProloGraalVariable> getVariables(){
if(parsingClauses)
return clauses.peek().getVariables();
return queries.peek().getVariables();
}
private void addGoal(ProloGraalTerm<?> goal){
if(parsingClauses){
clauses.peek().addGoal(goal);
}else{
queries.peek().addGoal(goal);
}
}
@Override
public void enterQuery(ProloGraalParser.QueryContext ctx) {
// when we enter a query, we need to create a new "context" for it.
// Queries amd clauses are the "top-level" of Prolog.
if(!parsingClauses) {
queries.push(new ProloGraalQuery());
}else{
clauses.push(new ProloGraalClause());
}
}
//TODO: some prolog texts, could both be parsed into a clause (fact) or query having only one goal.
// this fix using the parsingClausesBoolean works for the moment,
// but could have side effects like
// could throw an exception if it parses a real clause (head + goalList) while parsing queries.
@Override
public void enterClause(ProloGraalParser.ClauseContext ctx) {
// when we enter a clause, we need to create a new "context" for it.
// Clauses are the "top-level" of Prolog.
clauses.push(new ProloGraalClause());
// Clauses and queries are the "top-level" of Prolog.
if(parsingClauses) {
clauses.push(new ProloGraalClause());
}else{
queries.push(new ProloGraalQuery());
}
}
@Override
public void exitGoal(ProloGraalParser.GoalContext ctx) {
// add the goal to the current clause
clauses.peek().addGoal(elements.pop());
addGoal(elements.pop());
}
@Override
public void exitHead(ProloGraalParser.HeadContext ctx) {
// set the head of the current clause
clauses.peek().setHead(elements.pop());
if(parsingClauses){
clauses.peek().setHead(elements.pop());
}else{
addGoal(elements.pop());
}
}
@Override
public void enterAtom(ProloGraalParser.AtomContext ctx) {
// create an atom an push it to the element stack
ProloGraalAtom atom = new ProloGraalAtom(clauses.peek().getVariables(), ctx.getText());
ProloGraalAtom atom = new ProloGraalAtom(getVariables(), ctx.getText());
elements.push(atom);
}
......@@ -91,32 +159,32 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
// create a number according to its type (Integer or Double) and push it to the element stack
String n = ctx.getText();
try {
elements.push(new ProloGraalIntegerNumber(clauses.peek().getVariables(), Integer.parseInt(n)));
elements.push(new ProloGraalIntegerNumber(getVariables(), Integer.parseInt(n)));
} catch (NumberFormatException ex) {
elements.push(new ProloGraalDoubleNumber(clauses.peek().getVariables(), Double.parseDouble(n)));
elements.push(new ProloGraalDoubleNumber(getVariables(), Double.parseDouble(n)));
}
}
@Override
public void enterVariable(ProloGraalParser.VariableContext ctx) {
// create a new variable
ProloGraalVariable variable = new ProloGraalVariable(clauses.peek().getVariables(), ctx.getText());
ProloGraalVariable variable = new ProloGraalVariable(getVariables(), ctx.getText());
// check if the current clause's variables list already contains a reference to this new variable (using its name to compare)
if (clauses.peek().getVariables().containsKey(variable)) {
if (getVariables().containsKey(variable)) {
// if the variable already exists in the clause, we must not add a new one but use a reference instead
elements.push(clauses.peek().getVariables().get(variable));
elements.push(getVariables().get(variable));
} else {
// else we can just add the variable to the element stack
elements.push(variable);
// and we must directly add it to the current clause's variables list as well
clauses.peek().getVariables().put(variable, variable);
getVariables().put(variable, variable);
}
}
@Override
public void enterComposedTerm(ProloGraalParser.ComposedTermContext ctx) {
// when we enter a composed term, we push a new structure immediately to "mark" its beginning
elements.push(new ProloGraalStructure(clauses.peek().getVariables()));
elements.push(new ProloGraalStructure(getVariables()));
}
@Override
......@@ -175,7 +243,7 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
@Override
public void enterList(ProloGraalParser.ListContext ctx) {
// similar to structures, add a new list to the stack when we enter one
elements.push(new ProloGraalList(clauses.peek().getVariables()));
elements.push(new ProloGraalList(getVariables()));
}
@Override
......
......@@ -24,11 +24,11 @@ public class ProloGraalParser extends Parser {
RULE_prolograal = 0, RULE_atom = 1, RULE_number = 2, RULE_variable = 3,
RULE_functor = 4, RULE_composedTerm = 5, RULE_term = 6, RULE_head = 7,
RULE_fact = 8, RULE_goal = 9, RULE_goalList = 10, RULE_composedClause = 11,
RULE_clause = 12, RULE_tail = 13, RULE_list = 14;
RULE_query = 12, RULE_clause = 13, RULE_tail = 14, RULE_list = 15;
public static final String[] ruleNames = {
"prolograal", "atom", "number", "variable", "functor", "composedTerm",
"term", "head", "fact", "goal", "goalList", "composedClause", "clause",
"tail", "list"
"term", "head", "fact", "goal", "goalList", "composedClause", "query",
"clause", "tail", "list"
};
private static final String[] _LITERAL_NAMES = {
......@@ -96,6 +96,12 @@ public class ProloGraalParser extends Parser {
public ClauseContext clause(int i) {
return getRuleContext(ClauseContext.class,i);
}
public List<QueryContext> query() {
return getRuleContexts(QueryContext.class);
}
public QueryContext query(int i) {
return getRuleContext(QueryContext.class,i);
}
public ProlograalContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
......@@ -117,21 +123,33 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(33);
setState(36);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==LIST_START || _la==ATOM) {
{
{
setState(30);
clause();
setState(34);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) {
case 1:
{
setState(32);
clause();
}
break;
case 2:
{
setState(33);
query();
}
break;
}
}
setState(35);
setState(38);
_errHandler.sync(this);
_la = _input.LA(1);
}
setState(36);
setState(39);
match(EOF);
}
}
......@@ -168,22 +186,22 @@ public class ProloGraalParser extends Parser {
AtomContext _localctx = new AtomContext(_ctx, getState());
enterRule(_localctx, 2, RULE_atom);
try {
setState(41);
setState(44);
_errHandler.sync(this);
switch (_input.LA(1)) {
case ATOM:
enterOuterAlt(_localctx, 1);
{
setState(38);
setState(41);
match(ATOM);
}
break;
case LIST_START:
enterOuterAlt(_localctx, 2);
{
setState(39);
setState(42);
match(LIST_START);
setState(40);
setState(43);
match(LIST_END);
}
break;
......@@ -224,7 +242,7 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(43);
setState(46);
match(NUMBER);
}
}
......@@ -261,7 +279,7 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(45);
setState(48);
match(VARIABLE);
}
}
......@@ -300,7 +318,7 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(47);
setState(50);
atom();
}
}
......@@ -346,30 +364,30 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(49);
setState(52);
functor();
{
setState(50);
setState(53);
match(T__0);
setState(51);
setState(54);
term();
setState(56);
setState(59);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==SEPARATOR) {
{
{
setState(52);
setState(55);
match(SEPARATOR);
setState(53);
setState(56);
term();
}
}
setState(58);
setState(61);
_errHandler.sync(this);
_la = _input.LA(1);
}
setState(59);
setState(62);
match(T__1);
}
}
......@@ -419,41 +437,41 @@ public class ProloGraalParser extends Parser {
TermContext _localctx = new TermContext(_ctx, getState());
enterRule(_localctx, 12, RULE_term);
try {
setState(66);
setState(69);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(61);
setState(64);
composedTerm();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(62);
setState(65);
atom();
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
setState(63);
setState(66);
number();
}
break;
case 4:
enterOuterAlt(_localctx, 4);
{
setState(64);
setState(67);
variable();
}
break;
case 5:
enterOuterAlt(_localctx, 5);
{
setState(65);
setState(68);
list();
}
break;
......@@ -495,20 +513,20 @@ public class ProloGraalParser extends Parser {
HeadContext _localctx = new HeadContext(_ctx, getState());
enterRule(_localctx, 14, RULE_head);
try {
setState(70);
setState(73);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
setState(68);
setState(71);
atom();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
setState(69);
setState(72);
composedTerm();
}
break;
......@@ -550,9 +568,9 @@ public class ProloGraalParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(72);
setState(75);
head();
setState(73);
setState(76);
match(TERMINATOR);
}
}
......@@ -592,20 +610,20 @@ public class ProloGraalParser extends Parser {
GoalContext _localctx = new GoalContext