Commit b9e750f0 authored by Alexander Weigl's avatar Alexander Weigl

Context Menu for ProofTree, Formatting,

* Menu entries for debugging
parent 393fdf26
Pipeline #15146 passed with stages
in 6 minutes and 47 seconds
...@@ -45,6 +45,12 @@ deploy: ...@@ -45,6 +45,12 @@ deploy:
- "*/target/*.jar" - "*/target/*.jar"
allow_failure: true allow_failure: true
sonar:
stage: deploy
script:
- ""
allow_failure: true
site: site:
stage: deploy stage: deploy
script: script:
......
...@@ -9,16 +9,16 @@ start ...@@ -9,16 +9,16 @@ start
; ;
script script
: SCRIPT name=ID '(' signature=argList? ')' INDENT body=stmtList DEDENT : SCRIPT name=ID LPAREN signature=argList? RPAREN INDENT body=stmtList DEDENT
; ;
argList argList
: varDecl (',' varDecl)* : varDecl (COMMA varDecl)*
; ;
varDecl varDecl
: name=ID ':' type=ID : name=ID COLON type=ID
; ;
stmtList stmtList
...@@ -59,18 +59,18 @@ expression ...@@ -59,18 +59,18 @@ expression
| expression IMP expression #exprIMP | expression IMP expression #exprIMP
//| expression EQUIV expression already covered by EQ/NEQ //| expression EQUIV expression already covered by EQ/NEQ
| expression LBRACKET substExpressionList RBRACKET #exprSubst | expression LBRACKET substExpressionList RBRACKET #exprSubst
| MINUS expression #exprNegate | MINUS expression #exprNegate
| NOT expression #exprNot | NOT expression #exprNot
| '(' expression ')' #exprParen | LPAREN expression RPAREN #exprParen
| literals #exprLiterals | literals #exprLiterals
| matchPattern #exprMatch | matchPattern #exprMatch
; ;
substExpressionList substExpressionList
: :
(scriptVar '\\' expression (scriptVar SUBST_TO expression
(',' scriptVar '\\' expression)* (COMMA scriptVar SUBST_TO expression)*
)? )?
; ;
...@@ -97,9 +97,10 @@ matchPattern ...@@ -97,9 +97,10 @@ matchPattern
; ;
scriptVar scriptVar
: '?' ID : QUESTION_MARK ID
; ;
repeatStmt repeatStmt
: REPEAT INDENT stmtList DEDENT : REPEAT INDENT stmtList DEDENT
; ;
...@@ -138,7 +139,7 @@ scriptCommand ...@@ -138,7 +139,7 @@ scriptCommand
; ;
parameters: parameter+; parameters: parameter+;
parameter : ((pname=ID '=')? expr=expression); parameter : ((pname=ID EQ)? expr=expression);
/* /*
callStmt callStmt
...@@ -179,6 +180,7 @@ DEDENT : '}' ; ...@@ -179,6 +180,7 @@ DEDENT : '}' ;
SEMICOLON : ';' ; SEMICOLON : ';' ;
COLON : ':' ; COLON : ':' ;
HEAPSIMP:'heap-simp'; HEAPSIMP:'heap-simp';
SUBST_TO: '\\';
STRING_LITERAL STRING_LITERAL
...@@ -204,8 +206,11 @@ OR: '|' ; ...@@ -204,8 +206,11 @@ OR: '|' ;
IMP : '==>' ; IMP : '==>' ;
EQUIV : '<=>' ; EQUIV : '<=>' ;
NOT: 'not'; NOT: 'not';
COMMA: ',';
LPAREN: '(';
RPAREN: ')';
EXE_MARKER: '\u2316' -> channel(HIDDEN); EXE_MARKER: '\u2316' -> channel(HIDDEN);
QUESTION_MARK: '?';
DIGITS : DIGIT+ ; DIGITS : DIGIT+ ;
fragment DIGIT : [0-9] ; fragment DIGIT : [0-9] ;
......
...@@ -44,6 +44,19 @@ ...@@ -44,6 +44,19 @@
<version>0.9.5</version> <version>0.9.5</version>
</dependency> </dependency>
<dependency>
<groupId>it.unibo.alice.tuprolog</groupId>
<artifactId>tuprolog</artifactId>
<version>3.2.1</version>
</dependency>
<!--
<dependency>
<groupId>com.thesett</groupId>
<artifactId>prolog</artifactId>
<version>0.9.117</version>
</dependency>-->
<dependency> <dependency>
<groupId>edu.kit.iti.formal.psdbg</groupId> <groupId>edu.kit.iti.formal.psdbg</groupId>
<artifactId>lang</artifactId> <artifactId>lang</artifactId>
...@@ -52,7 +65,7 @@ ...@@ -52,7 +65,7 @@
<dependency> <dependency>
<groupId>edu.kit.iti.formal.psdbg</groupId> <groupId>edu.kit.iti.formal.psdbg</groupId>
<artifactId>runtime</artifactId> <artifactId>rt</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
</dependency> </dependency>
......
package edu.kit.iti.formal.psdbg.fmt;
import alice.tuprolog.*;
import com.google.common.base.Strings;
import edu.kit.iti.formal.psdbg.parser.ScriptLanguageLexer;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Token;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class DefaultFormatter implements Formatter {
private final Prolog prolog;
private final Theory formattingTheory;
private boolean inExpression = false;
private List<? extends Token> tokens;
private int nested;
private int pos;
private List<String> types;
public DefaultFormatter() throws InvalidLibraryException, IOException, InvalidTheoryException {
this.prolog = new Prolog();
//formattingTheory = new Theory(getClass().getResourceAsStream("fmt.pl"));
formattingTheory = new Theory(new FileInputStream("C:/Users/weigl/IdeaProjects/ProofScriptParser/lint/src/main/resources/fmt.pl"));
prolog.addTheory(formattingTheory);
//prolog.loadLibrary();
//new String[]{"lint/src/main/resources/fmt.pl"}
}
@Override
public String format(String code) {
ScriptLanguageLexer lexer = new ScriptLanguageLexer(CharStreams.fromString(code));
StringBuilder sb = new StringBuilder();
tokens = lexer.getAllTokens().stream()
.filter(t -> t.getChannel() != Lexer.HIDDEN)
.collect(Collectors.toList());
types = tokens.stream()
.map(Token::getType)
.map(lexer.getVocabulary()::getSymbolicName)
//.map(String::toLowerCase)
.map(s -> String.valueOf(s).toLowerCase())
.collect(Collectors.toList());
//System.out.println(types);
for (pos = 0; pos < tokens.size() - 1; pos++) {
Token token = tokens.get(pos);
nested += askForNumber("level", 2);
int nlCount = 0;
if ((nlCount = clearLinesBefore()) > 0)
clearLine(sb, nlCount);
else {
int numSpace = 0;
if ((numSpace = spaceBefore()) > 0)
whitespaces(sb, numSpace);
}
sb.append(token.getText());
int numSpace = 0;
if ((numSpace = spaceAfter()) > 0)
whitespaces(sb, numSpace);
else {
int nlAfter = 0;
if ((nlAfter = newlineAfter()) > 0) {
sb.append(Strings.repeat("\n", nlAfter))
.append(Strings.repeat(" ", nested * 4));
}
}
}
sb.append(tokens.get(pos).getText());
sb.append("\n");
return sb.toString();
}
private void whitespaces(StringBuilder sb, int numSpace) {
int i = 0;
for (i = 0; i < sb.length(); i++) {
if (sb.charAt(sb.length() - 1 - i) != ' ') {
break;
}
}
if (i < numSpace)
sb.append(Strings.repeat(" ", numSpace - i));
}
private void clearLine(StringBuilder sb, int nlCount) {
int i = 0;
for (i = sb.length() - 1; i >= 0; i--) {
if (!Character.isWhitespace(sb.charAt(i))) {
break;
}
}
sb.setLength(i + 1);
sb.append(Strings.repeat("\n", nlCount))
.append(Strings.repeat(" ", 4 * nested));
}
private int newlineAfter() {
return askForNumber("nlafter", 2);
}
private int spaceBefore() {
return askForNumber("wsbefore", 2);
}
private int spaceAfter() {
return askForNumber("wsafter", 2);
}
private int askForNumber(String name, int numContext) {
try {
SolveInfo si = callProlog(name, numContext, 1);
Term x = si.getVarValue("X");
if (x instanceof Int)
return ((Int) x).intValue();
else
return 0;
} catch (MalformedGoalException | NoSolutionException e) {
// e.printStackTrace();
return 0;
}
}
private int clearLinesBefore() {
return askForNumber("onclearline", 5);
}
private SolveInfo callProlog(String name, int numContext, int retArgs) throws MalformedGoalException {
String pctx = getContext(numContext, i -> pos - i - 1);
String nctx = getContext(numContext, i -> pos + i + 1);
String query = String.format(
"%s( [%s], %s, [%s] ,X ).", name, pctx, this.types.get(pos), nctx);
System.err.format("q: %s%n", query);
SolveInfo si = prolog.solve(query);
System.err.format("got %s%n", si);
return si;
}
private String getContext(int numContext, Function<Integer, Integer> access) {
String[] next = new String[numContext];
Arrays.fill(next, "empty");
for (int i = 0; i < numContext; i++) {
int val = access.apply(i);
if (0 <= val && val < types.size())
next[i] = this.types.get(val);
else break;
}
return Arrays.stream(next).reduce((a, b) -> a + ',' + b).orElse("");
}
}
package edu.kit.iti.formal.psdbg.fmt;
public interface Formatter {
public String format(String code);
}
package edu.kit.iti.formal.psdbg.fmt;
import alice.tuprolog.InvalidLibraryException;
import alice.tuprolog.InvalidTheoryException;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
public class FormatterMain {
public static final void main(String[] args) throws InvalidLibraryException, IOException, InvalidTheoryException {
DefaultFormatter df = new DefaultFormatter();
String code = FileUtils.readFileToString(new File(args[0]), Charset.defaultCharset());
String newCode = df.format(code);
System.out.flush();
System.err.flush();
System.out.println(newCode);
}
}
level(dedent,-1).
level(indent,1).
level(X,0).
level(Prev, colon, [indent,T],0).
level(colon,1).
level(Prev, Cur, Next, X) :- level(Cur,X).
onclearline(dedent,1).
onclearline(script, 2).
onclearline(cases, 1).
onclearline(foreach, 1).
onclearline(repeat, 2).
onclearline(comment, 1).
onclearline(Prev, Cur, Next, X) :- onclearline(Cur,X).
nlafter(Prev, colon, [H | T], 1) :- H \= indent .
nlafter(indent,1).
nlafter(dedent,1).
nlafter(semicolon,1).
nlafter(Prev, Cur, Next, X) :- nlafter(Cur,X).
wsbefore(Prev, Cur, Next, X) :- wsafter(Cur,X).
wsbefore(id,1).
wsafter(Prev, id, [semicolon | T], 0).
wsafter(id,1).
wsafter(cases,1).
wsafter(case,1).
wsafter(default,1).
wsafter(Prev, Cur, Next, X) :- wsafter(Cur,X).
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>edu.kit.iti.formal.psdbg</groupId> <groupId>edu.kit.iti.formal.psdbg</groupId>
<artifactId>runtime</artifactId> <artifactId>rt</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
......
package edu.kit.iti.formal.psdbg;
import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.proof.Node;
import de.uka.ilkd.key.proof.Proof;
import org.apache.commons.lang.ArrayUtils;
import org.key_project.util.collection.ImmutableList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Utillities for producing labels of KeY proof nodes
*
* @author Alexander Weigl
* @see edu.kit.iti.formal.psdbg.interpreter.data.KeyData
* @see Node
*/
public class LabelFactory {
public static String SEPARATOR = " // ";
public static String RANGE_SEPARATOR = " -- ";
/**
* Create Label for goalview according to function that is passed.
* The following functions can be given:
* <ul>
* <li>@see #Method getRuleLabel()</li>
* <li>@see #Method getBranchingLabel()</li>
* <li>@see #Method getNameLabel()</li>
* <li>@see #Method getProgramLinesLabel()</li>
* <li>@see #Method getProgramStatementsLabel()</li>
* </ul>
*
* @param projection function determining which kind of label to construct
* @return Label from this node to parent
*/
private static String constructLabel(Node cur, Function<Node, String> projection) {
StringBuilder sb = new StringBuilder();
do {
try {
String section = projection.apply(cur);
//filter null elements and -1 elements
if (section != null && !(section.equals(Integer.toString(-1)))) {
sb.append(section);
sb.append(SEPARATOR);
}
} catch (Exception e) {
}
cur = cur.parent();
} while (cur != null);
sb.append("$$");
return sb.toString();
}
public static String getBranchingLabel(Node node) {
return constructLabel(node, n -> n.getNodeInfo().getBranchLabel());
}
public static String getNameLabel(Node node) {
return constructLabel(node, Node::name);
}
public static String getRuleLabel(Node node) {
return constructLabel(node, (n) -> n.getAppliedRuleApp().rule().name().toString());
}
public static String getProgramLines(Node node) {
return constructLabel(node, n -> {
int startPos = n.getNodeInfo().getActiveStatement().getPositionInfo().getStartPosition().getLine();
int endPos = n.getNodeInfo().getActiveStatement().getPositionInfo().getEndPosition().getLine();
if (startPos == endPos) {
return Integer.toString(startPos);
} else {
String start = Integer.toString(startPos);
String end = Integer.toString(endPos);
return start + RANGE_SEPARATOR + end;
}
});
}
public static String getProgramStatmentLabel(Node node) {
return constructLabel(node, n ->
n.getNodeInfo().getFirstStatementString());
}
public static List<String[]> getLabelOfOpenGoals(Proof root, Function<Node, String> func) {
if (root.closed())
return Collections.emptyList();
ImmutableList<Goal> open = root.getSubtreeGoals(root.root());
return open.stream()
.map(Goal::node)
.map(func)
.map(s -> s.split(SEPARATOR))
.map(a -> {
ArrayUtils.reverse(a);
return a;
})
.collect(Collectors.toList());
}
}
package edu.kit.iti.formal.psdbg.interpreter.data; package edu.kit.iti.formal.psdbg.interpreter.data;
import de.uka.ilkd.key.control.KeYEnvironment; import de.uka.ilkd.key.control.KeYEnvironment;
import de.uka.ilkd.key.java.Label;
import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.SourceElement;
import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Node;
import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.Proof;
import edu.kit.iti.formal.psdbg.LabelFactory;
import lombok.*; import lombok.*;
import java.util.HashSet; import java.util.HashSet;
...@@ -22,8 +24,6 @@ import java.util.function.Function; ...@@ -22,8 +24,6 @@ import java.util.function.Function;
@EqualsAndHashCode @EqualsAndHashCode
@RequiredArgsConstructor @RequiredArgsConstructor
public class KeyData { public class KeyData {
private static final String SEPARATOR = " // ";
private static final String RANGE_SEPARATOR = " -- ";
private final KeYEnvironment env; private final KeYEnvironment env;
private final Proof proof; private final Proof proof;
private Node node; private Node node;
...@@ -71,43 +71,12 @@ public class KeyData { ...@@ -71,43 +71,12 @@ public class KeyData {
*/ */
public String getRuleLabel() { public String getRuleLabel() {
if (ruleLabel == null) { if (ruleLabel == null) {
ruleLabel = constructLabel((Node n) -> n.getAppliedRuleApp().rule().name().toString()); ruleLabel = LabelFactory.getRuleLabel(getNode());
} }
return ruleLabel; return ruleLabel;
} }
/**
* Create Label for goalview according to function that is passed.
* The following functions can be given:
* <ul>
* <li>@see #Method getRuleLabel()</li>
* <li>@see #Method getBranchingLabel()</li>
* <li>@see #Method getNameLabel()</li>
* <li>@see #Method getProgramLinesLabel()</li>
* <li>@see #Method getProgramStatementsLabel()</li>
* </ul>
* @param projection function determining which kind of label to construct
* @return Label from this node to parent
*/
private String constructLabel(Function<Node, String> projection) {
StringBuilder sb = new StringBuilder();
Node cur = getNode();
do {
try {
String section = projection.apply(cur);
//filter null elements and -1 elements
if (section != null && !(section.equals(Integer.toString(-1)))) {
sb.append(section);
sb.append(SEPARATOR);
}
} catch (Exception e) {
}
cur = cur.parent();
} while (cur != null);
sb.append("$$");
return sb.toString();
}
/** /**
* Get branching label of node from KeY * Get branching label of node from KeY
...@@ -115,7 +84,7 @@ public class KeyData { ...@@ -115,7 +84,7 @@ public class KeyData {
*/ */
public String getBranchingLabel() { public String getBranchingLabel() {
if (branchingLabel == null) { if (branchingLabel == null) {
branchingLabel = constructLabel(n -> n.getNodeInfo().getBranchLabel()); branchingLabel = LabelFactory.getBranchingLabel(getNode());
} }
return branchingLabel; return branchingLabel;
} }
...@@ -126,7 +95,7 @@ public class KeyData { ...@@ -126,7 +95,7 @@ public class KeyData {
*/ */
public String getNameLabel() { public String getNameLabel() {
if (nameLabel == null) { if (nameLabel == null) {
nameLabel = constructLabel(Node::name); nameLabel = LabelFactory.getNameLabel(getNode());
} }
return nameLabel; return nameLabel;
} }
...@@ -137,17 +106,7 @@ public class KeyData { ...@@ -137,17 +106,7 @@ public class KeyData {
*/ */
public String getProgramLinesLabel() { public String getProgramLinesLabel() {
if (programLinesLabel == null) { if (programLinesLabel == null) {
programLinesLabel = constructLabel(n -> { programLinesLabel = LabelFactory.getProgramLines(getNode());
int startPos = n.getNodeInfo().getActiveStatement().getPositionInfo().getStartPosition().getLine();
int endPos = n.getNodeInfo().getActiveStatement().getPositionInfo().getEndPosition().getLine();
if (startPos == endPos) {
return Integer.toString(startPos);
} else {
String start = Integer.toString(startPos);
String end = Integer.toString(endPos);
return start + RANGE_SEPARATOR + end;
}
});
} }
return programLinesLabel; return programLinesLabel;
} }
...@@ -158,10 +117,8 @@ public class KeyData { ...@@ -158,10 +117,8 @@ public class KeyData {
*/ */
public String getProgramStatementsLabel() { public String getProgramStatementsLabel() {
if (programStatementsLabel == null) { if (programStatementsLabel == null) {
programStatementsLabel = constructLabel(n -> programStatementsLabel = LabelFactory.getProgramStatmentLabel(getNode());
n.getNodeInfo().getFirstStatementString());
} }
return programStatementsLabel; return programStatementsLabel;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<relativePath>..</relativePath> <relativePath>..</relativePath>
</parent> </parent>
<artifactId>runtime</artifactId> <artifactId>rt</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>
......