ANTLR Parsetreewalker für ASP Result implementieren

This commit is contained in:
JanUlrich 2018-03-14 14:32:36 +01:00
parent 4a2b901465
commit 6a5ababa51
2 changed files with 83 additions and 102 deletions

View File

@ -8,14 +8,12 @@ import de.dhbwstuttgart.sat.asp.ASPStringConverter;
import de.dhbwstuttgart.sat.asp.model.ASPRule; import de.dhbwstuttgart.sat.asp.model.ASPRule;
import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultBaseListener; import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultBaseListener;
import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultLexer; import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultLexer;
import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultListener;
import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultParser; import de.dhbwstuttgart.sat.asp.parser.antlr.UnifyResultParser;
import de.dhbwstuttgart.sat.asp.parser.model.ParsedType; import de.dhbwstuttgart.sat.asp.parser.model.ParsedType;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.result.*; import de.dhbwstuttgart.typeinference.result.*;
import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.antlr.v4.runtime.tree.ParseTreeWalker;
import javax.json.Json; import javax.json.Json;
@ -36,11 +34,13 @@ import java.util.stream.Collectors;
* -> Eigentlich nur die korrekten Namen der Typen und TPHs * -> Eigentlich nur die korrekten Namen der Typen und TPHs
*/ */
public class ASPParser extends UnifyResultBaseListener { public class ASPParser extends UnifyResultBaseListener {
private final Collection<TypePlaceholder> originalTPHs; private Collection<TypePlaceholder> originalTPHs;
private ResultSet resultSet; private ResultSet resultSet;
private Map<String, ParsedType> types = new HashMap<>(); private Map<String, ParsedType> types = new HashMap<>();
private Set<String> tphs = new HashSet<>(); private Set<String> tphs = new HashSet<>();
private Map<String, ParameterListNode> parameterLists = new HashMap<>(); private Map<String, ParameterListNode> parameterLists = new HashMap<>();
private Set<Relation> equalsRelations = new HashSet<>();
private Set<Relation> smallerRelations = new HashSet<>();
/** /**
* Parst clingo output welcher als JSON (option --outf=2) ausgibt * Parst clingo output welcher als JSON (option --outf=2) ausgibt
@ -53,36 +53,74 @@ public class ASPParser extends UnifyResultBaseListener {
@Override @Override
public void enterParameter(UnifyResultParser.ParameterContext ctx) { public void enterParameter(UnifyResultParser.ParameterContext ctx) {
//Linked List (pointer, Type, nextPointer)
List<String> params = parseParameterList(ctx.parameterList());
parameterLists.put(params.get(0), new ParameterListNode(params.get(1), params.get(2)));
}
private static class Relation {
public final String right;
public final String left;
Relation(String leftType, String rightType){
this.left = leftType;
this.right = rightType;
}
@Override
public int hashCode() {
return (left+right).hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Relation)
return (right+left).equals(((Relation) obj).left+((Relation) obj).right);
return super.equals(obj);
}
}
private List<String> parseParameterList(UnifyResultParser.ParameterListContext ctx){
return ctx.value().stream().map(v ->
//ASPStringConverter.fromConstant(v.getText())
v.getText()
).collect(Collectors.toList());
} }
@Override @Override
public void enterEquals(UnifyResultParser.EqualsContext ctx) { public void enterEquals(UnifyResultParser.EqualsContext ctx) {
List<String> parameterList = ctx.parameterList().value().stream().map(v -> v.getText()).collect(Collectors.toList()); List<String> parameterList = parseParameterList(ctx.parameterList());
if(parameterList.size()<2)throw new DebugException("Fehler in Regex"); if(parameterList.size()<2)throw new DebugException("Fehler in Equals-Regel");
String ls = parameterList.get(0); String ls = parameterList.get(0);
String rs = parameterList.get(1); String rs = parameterList.get(1);
/* equalsRelations.add(new Relation(ls, rs));
RefTypeOrTPHOrWildcardOrGeneric lsType = this.getType(ls);
RefTypeOrTPHOrWildcardOrGeneric rsType = this.getType(rs);
if(lsType instanceof TypePlaceholder && rsType instanceof RefType)
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) lsType, rsType);
else if(lsType instanceof TypePlaceholder && rsType instanceof TypePlaceholder)
return new PairTPHEqualTPH((TypePlaceholder)lsType, (TypePlaceholder)rsType);
else throw new NotImplementedException();
*/
} }
@Override @Override
public void enterSmaller(UnifyResultParser.SmallerContext ctx) { public void enterSmaller(UnifyResultParser.SmallerContext ctx) {
List<String> parameterList = parseParameterList(ctx.parameterList());
if(parameterList.size()<2)throw new DebugException("Fehler in Smaller-Regel");
String ls = parameterList.get(0);
String rs = parameterList.get(1);
smallerRelations.add(new Relation(ls, rs));
} }
@Override @Override
public void enterTypeVar(UnifyResultParser.TypeVarContext ctx) { public void enterTypeVar(UnifyResultParser.TypeVarContext ctx) {
List<String> parameterList = parseParameterList(ctx.parameterList());
if(parameterList.size()<1)throw new DebugException("Fehler in typeVar-Regel");
tphs.add(parameterList.get(0));
} }
@Override @Override
public void enterType(UnifyResultParser.TypeContext ctx) { public void enterType(UnifyResultParser.TypeContext ctx){
super.enterType(ctx); List<String> parameterList = parseParameterList(ctx.parameterList());
if(parameterList.size()<3)throw new DebugException("Fehler in Type-Regel");
String name = parameterList.get(0);
String typeName = parameterList.get(1);
String paramPointer = parameterList.get(2);
types.put(name, new ParsedType(typeName, paramPointer));
} }
/* /*
@ -104,62 +142,46 @@ public class ASPParser extends UnifyResultBaseListener {
} }
*/ */
private ASPParser(String toParse, Collection<TypePlaceholder> oldPlaceholders){ private ASPParser(String toParse, Collection<TypePlaceholder> oldPlaceholders){
System.out.println(toParse);
this.originalTPHs = oldPlaceholders; this.originalTPHs = oldPlaceholders;
/*
JsonObject jsonResult = Json.createReader(new StringReader(toParse)).readObject(); JsonObject jsonResult = Json.createReader(new StringReader(toParse)).readObject();
JsonArray results = jsonResult.getJsonArray("Call").getJsonObject(0). JsonArray results = jsonResult.getJsonArray("Call").getJsonObject(0).
getJsonArray("Witnesses").getJsonObject(0). getJsonArray("Witnesses").getJsonObject(0).
getJsonArray("Value"); getJsonArray("Value");
//Im ersten Schritt werden alle Regeln geparst
String completeResult = "";
for(int i = 0; i<results.size();i++){
String aspStatement = results.getString(i);
completeResult += aspStatement + " ";
}
System.out.println(completeResult);
*/
UnifyResultLexer lexer = new UnifyResultLexer(CharStreams.fromString(toParse));
UnifyResultParser.AnswerContext parseTree = new UnifyResultParser(new CommonTokenStream(lexer)).answer();
new ParseTreeWalker().walk(this, parseTree);
/* /*
Diese Funktion läuft im folgenden mehrmals über das Result aus dem ASP Programm. Diese Funktion läuft im folgenden mehrmals über das Result aus dem ASP Programm.
Dabei werden Schritt für Schritt die Felder dieser Klasse befüllt die am Schluss das ResultSet ergeben Dabei werden Schritt für Schritt die Felder dieser Klasse befüllt die am Schluss das ResultSet ergeben
*/ */
Set<ResultPair> ret = new HashSet<>(); Set<ResultPair> ret = new HashSet<>();
//Zuerst die params und typeVars: //Zuerst die params und typeVars:
for(int i = 0; i<results.size();i++){ //for(String paramPointer : types.values().stream().map(parsedType -> parsedType.params).collect(Collectors.toList())){ }
String aspStatement = results.getString(i);
parseParameter(aspStatement);
parseTypeVar(aspStatement);
}
//Dann die Typen, das ist wichtig, da die Typen auf die Parameter referenzieren:
for(int i = 0; i<results.size();i++){
String aspStatement = results.getString(i);
parseType(aspStatement);
}
//Dann die Equalsdot Statements //Dann die Equalsdot Statements
for(int i = 0; i<results.size();i++){ for(Relation eq : equalsRelations){
String aspStatement = results.getString(i); RefTypeOrTPHOrWildcardOrGeneric lsType = this.getType(eq.left);
ResultPair p = parseEqualsDot(aspStatement); RefTypeOrTPHOrWildcardOrGeneric rsType = this.getType(eq.right);
if(p != null)ret.add(p);
p = parseSmallerDot(aspStatement);
if(p != null)ret.add(p);
}
this.resultSet = new ResultSet(ret);
}
private ResultPair parseSmallerDot(String statement) {
//TODO
return null;
}
private ResultPair parseEqualsDot(String statement){
Pattern p = Pattern.compile(ASPRule.ASP_PAIR_EQUALS_NAME+"\\(([^,]+),([^,]+)\\)");
Matcher m = p.matcher(statement);
boolean b = m.matches();
if(b){
if(m.groupCount()<2)throw new DebugException("Fehler in Regex");
String ls = m.group(1);
String rs = m.group(2);
RefTypeOrTPHOrWildcardOrGeneric lsType = this.getType(ls);
RefTypeOrTPHOrWildcardOrGeneric rsType = this.getType(rs);
if(lsType instanceof TypePlaceholder && rsType instanceof RefType) if(lsType instanceof TypePlaceholder && rsType instanceof RefType)
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) lsType, rsType); ret.add(new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) lsType, rsType));
else if(lsType instanceof TypePlaceholder && rsType instanceof TypePlaceholder) else if(lsType instanceof TypePlaceholder && rsType instanceof TypePlaceholder)
return new PairTPHEqualTPH((TypePlaceholder)lsType, (TypePlaceholder)rsType); ret.add(new PairTPHEqualTPH((TypePlaceholder)lsType, (TypePlaceholder)rsType));
else throw new NotImplementedException(); else throw new NotImplementedException();
} }
return null; this.resultSet = new ResultSet(ret);
} }
private RefTypeOrTPHOrWildcardOrGeneric getType(String name) { private RefTypeOrTPHOrWildcardOrGeneric getType(String name) {
@ -173,7 +195,8 @@ public class ASPParser extends UnifyResultBaseListener {
if(types.containsKey(name)){ if(types.containsKey(name)){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
ParsedType t = types.get(name); ParsedType t = types.get(name);
for(String param : t.params){
for(String param : getParams(t.params)){
params.add(this.getType(param)); params.add(this.getType(param));
} }
return new RefType(new JavaClassName(ASPStringConverter.fromConstant(t.name)), params, new NullToken()); return new RefType(new JavaClassName(ASPStringConverter.fromConstant(t.name)), params, new NullToken());
@ -189,49 +212,6 @@ public class ASPParser extends UnifyResultBaseListener {
this.nextNode = next; this.nextNode = next;
} }
} }
private void parseParameter(String statement){
//param(pointer, typ, nextPointer
Pattern p = Pattern.compile(ASPRule.ASP_PARAMLIST_NAME+"\\(([^,]+),([^,]+),([^,]+)\\)");
Matcher m = p.matcher(statement);
boolean b = m.matches();
if(b){
if(m.groupCount()<3)throw new DebugException("Fehler in Regex");
String pointer = m.group(1);
String type = m.group(2);
String next = m.group(3);
if(next.equals(ASPRule.ASP_PARAMLIST_END_POINTER.toString()))next = null;
if(this.parameterLists.containsKey(pointer)){
throw new DebugException("Fehler in Ergebnisparsen");
}
this.parameterLists.put(pointer,new ParameterListNode(type, next));
}
}
private void parseTypeVar(String statement){
Pattern p = Pattern.compile(ASPRule.ASP_TYPE_VAR+"\\(([^,]+)\\)");
Matcher m = p.matcher(statement);
boolean b = m.matches();
if(b){
if(m.groupCount()<1)throw new DebugException("Fehler in Regex");
String name = m.group(1);
this.tphs.add(name);
}
}
private void parseType(String statement){
//Diese Regel muss 3 Parameter parsen (TypPointer, TypName, ParameterlistenPointer)
Pattern p = Pattern.compile(ASPRule.ASP_TYPE+"\\(([^,]+),([^,]+),([^,]+)\\)");
Matcher m = p.matcher(statement);
boolean b = m.matches();
if(b){
if(m.groupCount()<3)throw new DebugException("Fehler in Regex");
String pointer = m.group(1);
String name = m.group(2);
String paraList = m.group(3);
List<String> params = this.getParams(paraList);
this.types.put(pointer,new ParsedType(name, params));
}
}
private List<String> getParams(String pointer) { private List<String> getParams(String pointer) {
List<String> params = new ArrayList<>(); List<String> params = new ArrayList<>();
@ -239,6 +219,7 @@ public class ASPParser extends UnifyResultBaseListener {
while(pointer != null){ while(pointer != null){
if(!parameterLists.containsKey(pointer)) if(!parameterLists.containsKey(pointer))
throw new DebugException("Fehler in Ergebnisparsen"); throw new DebugException("Fehler in Ergebnisparsen");
//TODO: Fehler in ASP. Die adapt Regel muss erkennen, wenn die Parameterliste auf der linken Seite kürzer ist und diese Rechtzeitig beenden
ParameterListNode param = parameterLists.get(pointer); ParameterListNode param = parameterLists.get(pointer);
pointer = param.nextNode; pointer = param.nextNode;
params.add(param.type); params.add(param.type);

View File

@ -4,8 +4,8 @@ import java.util.List;
public class ParsedType { public class ParsedType {
public final String name; public final String name;
public final List<String> params; public final String params;
public ParsedType(String name, List<String> params){ public ParsedType(String name, String params){
this.name = name; this.name = name;
this.params = params; this.params = params;
} }