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.parser.antlr.UnifyResultBaseListener;
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.model.ParsedType;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.result.*;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import javax.json.Json;
@ -36,11 +34,13 @@ import java.util.stream.Collectors;
* -> Eigentlich nur die korrekten Namen der Typen und TPHs
*/
public class ASPParser extends UnifyResultBaseListener {
private final Collection<TypePlaceholder> originalTPHs;
private Collection<TypePlaceholder> originalTPHs;
private ResultSet resultSet;
private Map<String, ParsedType> types = new HashMap<>();
private Set<String> tphs = new HashSet<>();
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
@ -53,36 +53,74 @@ public class ASPParser extends UnifyResultBaseListener {
@Override
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
public void enterEquals(UnifyResultParser.EqualsContext ctx) {
List<String> parameterList = ctx.parameterList().value().stream().map(v -> v.getText()).collect(Collectors.toList());
if(parameterList.size()<2)throw new DebugException("Fehler in Regex");
List<String> parameterList = parseParameterList(ctx.parameterList());
if(parameterList.size()<2)throw new DebugException("Fehler in Equals-Regel");
String ls = parameterList.get(0);
String rs = parameterList.get(1);
/*
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();
*/
equalsRelations.add(new Relation(ls, rs));
}
@Override
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
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
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){
System.out.println(toParse);
this.originalTPHs = oldPlaceholders;
/*
JsonObject jsonResult = Json.createReader(new StringReader(toParse)).readObject();
JsonArray results = jsonResult.getJsonArray("Call").getJsonObject(0).
getJsonArray("Witnesses").getJsonObject(0).
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.
Dabei werden Schritt für Schritt die Felder dieser Klasse befüllt die am Schluss das ResultSet ergeben
*/
Set<ResultPair> ret = new HashSet<>();
//Zuerst die params und typeVars:
for(int i = 0; i<results.size();i++){
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);
}
//for(String paramPointer : types.values().stream().map(parsedType -> parsedType.params).collect(Collectors.toList())){ }
//Dann die Equalsdot Statements
for(int i = 0; i<results.size();i++){
String aspStatement = results.getString(i);
ResultPair p = parseEqualsDot(aspStatement);
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);
for(Relation eq : equalsRelations){
RefTypeOrTPHOrWildcardOrGeneric lsType = this.getType(eq.left);
RefTypeOrTPHOrWildcardOrGeneric rsType = this.getType(eq.right);
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)
return new PairTPHEqualTPH((TypePlaceholder)lsType, (TypePlaceholder)rsType);
ret.add(new PairTPHEqualTPH((TypePlaceholder)lsType, (TypePlaceholder)rsType));
else throw new NotImplementedException();
}
return null;
this.resultSet = new ResultSet(ret);
}
private RefTypeOrTPHOrWildcardOrGeneric getType(String name) {
@ -173,7 +195,8 @@ public class ASPParser extends UnifyResultBaseListener {
if(types.containsKey(name)){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
ParsedType t = types.get(name);
for(String param : t.params){
for(String param : getParams(t.params)){
params.add(this.getType(param));
}
return new RefType(new JavaClassName(ASPStringConverter.fromConstant(t.name)), params, new NullToken());
@ -189,49 +212,6 @@ public class ASPParser extends UnifyResultBaseListener {
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) {
List<String> params = new ArrayList<>();
@ -239,6 +219,7 @@ public class ASPParser extends UnifyResultBaseListener {
while(pointer != null){
if(!parameterLists.containsKey(pointer))
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);
pointer = param.nextNode;
params.add(param.type);

View File

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