Commit 6bee99ef authored by Clemens Pflaum's avatar Clemens Pflaum

Merge + gather method and variable bindings

Merge remote-tracking branch 'origin/konstantin2' into clemens

Conflicts:
	CupParser/src/de/in/tum/www2/cup/Demo.java
	CupParser/src/de/in/tum/www2/cup/ast/JavaCompiler.java
parents 0d6938cd 5573cba4
......@@ -775,7 +775,8 @@ production ::=
new Name(
(String) lhs_id,
Range.fromLocations(lhs_idxleft, lhs_idxright)
),
),
((symbol_part) this.symbols.get(lhs_id))._the_symbol._stack_type,
(List<ProductionRight>) rhs,
Range.fromLocations(lhs_idxleft, sxright)
)
......
......@@ -30,7 +30,7 @@ public class CupParser {
parser.init(context.getErrorManager(), context, inputStream);
}
public ParserResult parse() throws Exception {
public ParserResult parse(String[] classpathEntries) throws Exception {
if (result != null)
return result;
try {
......@@ -42,7 +42,7 @@ public class CupParser {
return null;
}
result = parser.getResult();
result.parseJava();
result.parseJava(classpathEntries);
// TODO add java parsing call
return result;
}
......
......@@ -2,78 +2,22 @@
package de.in.tum.www2.cup;
import java.io.FileInputStream;
import java.util.Enumeration;
import java_cup.runtime.*;
import de.in.tum.www2.cup.*;
import de.in.tum.www2.cup.analysis.DeclarationsExtractorVisitor;
import de.in.tum.www2.cup.analysis.LocationPatchVisitor;
import de.in.tum.www2.cup.ast.*;
import de.in.tum.www2.cup.internal.emit;
import de.in.tum.www2.cup.ast.ParserResult;
class Demo
{
class Demo {
public static void main(String[] blah) throws Exception {
IErrorReporter er = new NoopErrorReporter();
FileInputStream input = new FileInputStream("C:/workspace/testCUP/minijava/bin/cup/test.cup");
CupParser parser = new CupParser(er, input);
ParserResult res = parser.parse();
CupContext context = parser.getContext();
// System.out.println(res);
System.out.println("\nDeclarationVisitor:");
Declarations oldDecl = null;
DeclarationsExtractorVisitor declVisitor = new DeclarationsExtractorVisitor();
res.accept(declVisitor, null);
Declarations newDecl = declVisitor.getResult();
if (!newDecl.equals(oldDecl)) {
System.out.println("Declarations have changed. -> rescan whole document.");
}
if (!newDecl.isDeclared ("BLAH"))
System.out.println("BLAH is not a declared keyword! :-(");
if (!newDecl.isDeclaredTerminal("QUESTION"))
System.out.println("QUESTION is a declared terminal! :-)");
System.out.println("\nComputing tables ...");
LALRResult lalrResult = LALRResult.Compute(context, context.start_production);
FileInputStream input = new FileInputStream("C:/workspace/testCUP/minijava/bin/cup/test.cup");
for (Conflict conflict : context.getConflictManager().getConflicts()) {
System.out.println(conflict);
}
// System.out.println(lalrResult.getActionTable());
// System.out.println(lalrResult.getReduceTable());
CupParser parser = new CupParser(er, input);
/*lalr_state ordered[] = new lalr_state[lalr_state.number()];
for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
{
lalr_state st = (lalr_state)s.nextElement();
ordered[st.index()] = st;
}
String[] classpathEntries = new String[] { "lib\\java-cup-11b-runtime.jar" };
ParserResult res = parser.parse(classpathEntries);
System.err.println("===== Viable Prefix Recognizer =====");
for (int i = 0; i<lalr_state.number(); i++)
{
if (ordered[i] == start_state) System.err.print("START ");
System.err.println(ordered[i]);
System.err.println("-------------------");
}
}
*/
System.out.println(res);
System.out.println("done.");
}
}
}
......@@ -3,6 +3,7 @@ package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.ast.ActionCodeBlock;
import de.in.tum.www2.cup.ast.IProductionRightPart;
import de.in.tum.www2.cup.ast.LabeledProductionSymbolRef;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRight;
public class LabelToVariableVisitor extends Visitor<Object> {
......@@ -19,5 +20,7 @@ public class LabelToVariableVisitor extends Visitor<Object> {
block.addVariable((LabeledProductionSymbolRef) part);
}
}
Production p = (Production) node.getParent();
block.setReturnType(p.getReturnType());
}
}
......@@ -4,12 +4,17 @@ import de.in.tum.www2.cup.ast.ActionCodeBlock;
import de.in.tum.www2.cup.ast.SpecialCodeBlock;
public class ParseJavaVisitor extends Visitor<Object> {
private final String[] classpathEntries;
public ParseJavaVisitor(String[] classpathEntries) {
this.classpathEntries = classpathEntries;
}
public void postVisit(ActionCodeBlock node, Object data) {
node.parseJavaCode();
node.parseJavaCode(classpathEntries);
};
public void postVisit(SpecialCodeBlock node, Object data) {
node.parseJavaCode();
node.parseJavaCode(classpathEntries);
};
}
package de.in.tum.www2.cup.ast;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.SimpleName;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.LabelToVariableVisitor;
public class ActionCodeBlock extends CodeBlock implements IProductionRightPart {
private List<LabeledProductionSymbolRef> variables = new LinkedList<>();
private List<LabeledProductionSymbolRef> variableLabels = new LinkedList<>();
private String returnType;
public ActionCodeBlock(int debugId, BlockType bt, String blob, Range range) {
super(debugId, bt, blob, range);
......@@ -26,18 +33,32 @@ public class ActionCodeBlock extends CodeBlock implements IProductionRightPart {
}
@Override
public void parseJavaCode() {
public void parseJavaCode(String[] classpathEntries) {
//
LabelToVariableVisitor visitor = new LabelToVariableVisitor(this);
this.getParent().accept(visitor, null);
JavaCompiler.parseJava(getBlob(), this);
CompilationUnit cu = (CompilationUnit) JavaCompiler.parseJava(getBlob(), this, classpathEntries);
LocalVariableDetector variableCollector = new LocalVariableDetector();
cu.accept(variableCollector);
this.problems = cu.getProblems();
this.variableMap = variableCollector.getVariableMap();
this.methodList = variableCollector.getMethodList();
}
public void addVariable(LabeledProductionSymbolRef l) {
variables.add(l);
variableLabels.add(l);
}
public List<LabeledProductionSymbolRef> getVariables() {
return variables;
return variableLabels;
}
public void setReturnType(String returnType) {
this.returnType = returnType;
}
public String getReturnType() {
return returnType;
}
}
package de.in.tum.www2.cup.ast;
import java.util.HashMap;
import java.util.LinkedList;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.SimpleName;
import de.in.tum.www2.cup.Range;
public abstract class CodeBlock extends AbstractNode {
public enum BlockType {
Action, Parser, Init, Scan, ActionCode
}
protected IProblem[] problems;
protected HashMap<IVariableBinding, LinkedList<SimpleName>> variableMap;
protected LinkedList<SimpleName> methodList;
private CompilationUnit cu;
private int debugId;
private String blob;
private BlockType bt;
private ASTNode tree;
public CompilationUnit getCompilationUnit() {
return cu;
}
public void setCompilationUnit(CompilationUnit cu) {
this.cu = cu;
}
public IProblem[] getProblems() {
return problems;
}
public HashMap<IVariableBinding, LinkedList<SimpleName>> getVariableMap() {
return variableMap;
}
public LinkedList<SimpleName> getMethodList() {
return methodList;
}
public enum BlockType {
Action, Parser, Init, Scan, ActionCode
}
public int getDebugId() {
return debugId;
......@@ -45,5 +78,6 @@ public abstract class CodeBlock extends AbstractNode {
builder.append(bt + " " + tree);
}
public abstract void parseJavaCode();
public abstract void parseJavaCode(String[] classpathEntries);
}
package de.in.tum.www2.cup.ast;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import de.in.tum.www2.cup.ast.CodeBlock.BlockType;
public class JavaCompiler {
//private static List<Pair<ASTNode, BlockType>> nodes = new LinkedList<>();
private static ASTNode javaTree;
/*public static void doTreeMagic() {
// TODO add root node (Parser class)
// TODO add nodes -> action code in class Cup$Parser$actions
AST a = AST.newAST(AST.JLS8);
// public class Parser
TypeDeclaration td = a.newTypeDeclaration();
Modifier m = a.newModifier(ModifierKeyword.PUBLIC_KEYWORD);
td.modifiers().add(m);
td.setName(a.newSimpleName("Parser"));
// public void user_init() throws java.lang.Exception
MethodDeclaration userInit = a.newMethodDeclaration();
userInit.modifiers().add(a.newModifier(ModifierKeyword.PUBLIC_KEYWORD));
userInit.setName(a.newSimpleName("user_init"));
// class CUP$Parser$actions
TypeDeclaration parserActions = a.newTypeDeclaration();
parserActions.setName(a.newSimpleName("CUP$Parser$actions"));
// public java_cup.runtime.Symbol scan() throws java.lang.Exception
MethodDeclaration scanWith = a.newMethodDeclaration();
scanWith.setName(a.newSimpleName("scan"));
scanWith.modifiers().add(a.newModifier(ModifierKeyword.PUBLIC_KEYWORD));
scanWith.setReturnType2(a.newSimpleType(a.newQualifiedName(
a.newQualifiedName(a.newName("java_cup"), a.newSimpleName("runtime")), a.newSimpleName("Symbol"))));
// add stuff to Parser class body
td.bodyDeclarations().add(userInit);
for (Pair<ASTNode, BlockType> p : nodes) {
if (p.right == BlockType.Parser) {
TypeDeclaration td2 = (TypeDeclaration) p.left;
td2.delete();
System.out.println(td2.bodyDeclarations().toString());
td.bodyDeclarations().addAll(td2.bodyDeclarations());
// TODO fix this
}
}
td.bodyDeclarations().add(parserActions);
td.bodyDeclarations().add(scanWith);
int i;
}*/
public static ASTNode parseJava(String blob, CodeBlock codeblock) {
/**
*
* @param userCode
* the codeblock's java code
* @param codeblock
* @param classpathEntries
* String-array containing a path to java-cup-runtime.jar
* @return the parsed ASTNode(CompilationUnit)
*/
public static ASTNode parseJava(String userCode, CodeBlock codeblock, String[] classpathEntries) {
ASTParser parser = ASTParser.newParser(AST.JLS8);
ASTNode node;
parser.setUnitName("TODO: Edit name");
switch (codeblock.getBt()) {
case Action:
case Parser:
blob="public class DummyClass{"+blob+"}";
parser.setEnvironment(new String[] {""}, new String[] {""}, new String[] { "UTF-8"}, true);
parser.setResolveBindings(true);
parser.setSource(blob.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
node = parser.createAST(null);
node.accept(new LocalVariableDetector());
break;
case Init:
case Scan:
blob="public class DummyClass{\n\tpublic void dummymethod()\n\t{"+blob+"\n\t}\n}";
parser.setEnvironment(new String[] {""}, new String[] {""}, new String[] { "UTF-8"}, true);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(blob.toCharArray());
parser.setResolveBindings(true);
node = parser.createAST(null);
node.accept(new LocalVariableDetector());
break;
case ActionCode:
blob="public class DummyClass{\n\tpublic void dummymethod("+"Integer e, Integer f"+")\n\t{"+blob+"\n\t}\n}";
parser.setEnvironment(new String[] {""}, new String[] {""}, new String[] { "UTF-8"}, true);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(blob.toCharArray());
parser.setResolveBindings(true);
node = parser.createAST(null);
ASTVisitor visitor = new LocalVariableDetector();
node.accept(visitor);
break;
default:
throw new UnsupportedOperationException("java parsing not implemented: unknown blocktype");
}
return node;
}
private static String getVars() {
// TODO Auto-generated method stub
return null;
}
// String[] classpathEntries = new String[] { "lib\\java-cup-11b-runtime.jar" };// jars
String[] sourcepathEntries = new String[] { "" };
parser.setEnvironment(classpathEntries, sourcepathEntries, new String[] { "UTF-8" }, true);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setUnitName("DummyClass");
parser.setResolveBindings(true);
public static class Pair<L, R> {
private final L left;
private final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
String dummyClass = "";
public L getLeft() {
return left;
}
// File f = new File("");
// System.out.println(f.getAbsolutePath());
// C:\Users\Konstantin\git\cup-eclipse-plugin\CupParser
public R getRight() {
return right;
}
final String IMPORTS = "import java_cup.runtime.ComplexSymbolFactory.Location;\n";
final String DUMMY_CLASS_DEF = "public class DummyClass\n{";
final String RWING = "}";
final String DUMMY_METHOD_DEF = "\n\tpublic void dummymethod(";
final String DUMMY_METHOD_ARGS_END = ")\n\t{";
final String DUMMY_CLASS_DEF_END = "\n" + RWING;
final String DUMMY_METHOD_END = "\n\t" + RWING;
@Override
public boolean equals(Object o) {
if (!(o instanceof Pair))
return false;
Pair pairo = (Pair) o;
return this.left.equals(pairo.getLeft()) && this.right.equals(pairo.getRight());
switch (codeblock.getBt()) {
case Action:
case Parser:
dummyClass = DUMMY_CLASS_DEF + userCode + RWING;
break;
case Init:
case Scan:
dummyClass = DUMMY_CLASS_DEF + DUMMY_METHOD_DEF + DUMMY_METHOD_ARGS_END + userCode + DUMMY_METHOD_END
+ DUMMY_CLASS_DEF_END;
break;
case ActionCode:
ActionCodeBlock block = (ActionCodeBlock) codeblock;
dummyClass = IMPORTS + DUMMY_CLASS_DEF + DUMMY_METHOD_DEF;
// TODO return type
dummyClass += block.getReturnType() + " RESULT";
for (LabeledProductionSymbolRef l : block.getVariables()) {
dummyClass += ", " + l.getDatatype() + " " + l.label;
dummyClass += ", " + "Location" + " " + l.label + "xleft"; // TODO Object should really be a Location
dummyClass += ", " + "Location" + " " + l.label + "xright"; // TODO Object should really be a Location
dummyClass += ", " + "int" + " " + l.label + "left";
dummyClass += ", " + "int" + " " + l.label + "right";
}
dummyClass += DUMMY_METHOD_ARGS_END + "\n\t\t";
dummyClass += userCode;
dummyClass += DUMMY_METHOD_END + DUMMY_CLASS_DEF_END;
break;
default:
throw new UnsupportedOperationException("java parsing not implemented: unknown blocktype");
}
parser.setSource(dummyClass.toCharArray());
node = parser.createAST(null);
return node;
}
}
......@@ -8,15 +8,24 @@ import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jface.text.Position;
public class LocalVariableDetector extends ASTVisitor {
HashMap<IVariableBinding, LinkedList<Position>> variableMap = new HashMap<IVariableBinding, LinkedList<Position>>();
private HashMap<IVariableBinding, LinkedList<SimpleName>> variableMap = new HashMap<IVariableBinding, LinkedList<SimpleName>>();
private LinkedList<SimpleName> methodList = new LinkedList<SimpleName>();
public LinkedList<SimpleName> getMethodList() {
return methodList;
}
public HashMap<IVariableBinding, LinkedList<SimpleName>> getVariableMap() {
return variableMap;
}
@Override
public boolean visit(FieldDeclaration node) {
......@@ -24,7 +33,7 @@ public class LocalVariableDetector extends ASTVisitor {
for (Iterator iter = node.fragments().iterator(); iter.hasNext();) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next();
IVariableBinding binding= (IVariableBinding) fragment.resolveBinding();
variableMap.put( binding, new LinkedList<Position>());
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found FieldDeclaration " + fragment.getName().getIdentifier());
}
......@@ -37,7 +46,7 @@ public class LocalVariableDetector extends ASTVisitor {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next();
IVariableBinding binding= (IVariableBinding) fragment.resolveBinding();
variableMap.put( binding, new LinkedList<Position>());
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found VariableDeclarationStatement " + fragment.getName().getIdentifier());
}
return false;
......@@ -46,11 +55,11 @@ public class LocalVariableDetector extends ASTVisitor {
@Override
public boolean visit(SingleVariableDeclaration node) {
IVariableBinding binding = (IVariableBinding) node.resolveBinding();
variableMap.put( binding, new LinkedList<Position>());
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found SingleVariableDeclaration " + binding.getName());
return true;
return false;
}
@Override
......@@ -60,10 +69,12 @@ public class LocalVariableDetector extends ASTVisitor {
IVariableBinding binding = (IVariableBinding) nodeBinding;
if(variableMap.containsKey(binding)){
variableMap.get(binding).add(new Position(node.getStartPosition(), node.getLength()));
variableMap.get(binding).add(node);
}
System.out.println("found variableBinding " + nodeBinding.getName());
}else if(nodeBinding instanceof IMethodBinding) {
methodList.add(node);
}else{
System.out.println("found SimpleName " + node.getIdentifier());
}
......@@ -71,5 +82,4 @@ public class LocalVariableDetector extends ASTVisitor {
return false;
}
}
......@@ -109,8 +109,8 @@ public class ParserResult extends AbstractNode {
throw new RuntimeException("not yet implemented.");
}
public void parseJava() {
ParseJavaVisitor visitor = new ParseJavaVisitor();
public void parseJava(String[] classpathEntries) {
ParseJavaVisitor visitor = new ParseJavaVisitor(classpathEntries);
this.accept(visitor, null);
}
......
......@@ -2,16 +2,19 @@ package de.in.tum.www2.cup.ast;
import java.util.List;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
public class Production extends AbstractNode
implements IWithName, IHasDeclarationReference
{
public class Production extends AbstractNode implements IWithName, IHasDeclarationReference {
private NonTerminal declarationRef;
private Name lhs; // TODO: This should really be a NonTerminal class
private List<ProductionRight> rhs;
private String returnType;
public String getReturnType() {