Commit 0a2769f0 authored by Johannes Mey's avatar Johannes Mey
Browse files

initial version of relast with parser support (i.e., semi-automatic reference resolving)

parent 51fe0bc9
......@@ -17,6 +17,14 @@ aspect TypeAnalysis {
syn boolean TypeDecl.isAlreadyDeclared()
= lookupType(getID()) != this;
inh TypeDecl TypeDecl.lookupType(String name);
syn TypeDecl TypeDecl.mostGeneralSuperType() {
if (!hasSuper()) {
return this;
} else {
return getSuper().decl().mostGeneralSuperType();
}
}
}
aspect ComponentAnalysis {
......
aspect BackendAbstractGrammar {
public static String ASTNode.listClass = "ArrayList";
public static boolean ASTNode.resolverHelper = false;
public String Program.generateAbstractGrammar() {
StringBuilder sb = new StringBuilder();
......@@ -212,6 +213,11 @@ aspect BackendDirectedAPI {
public void RelationComponent.generateGetOne(StringBuilder sb) {
sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl());
sb.append(".get" + nameCapitalized() + "() {\n");
if (resolverHelper) {
sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null && get" + getImplAttributeName() + "().unresolved()) {\n");
sb.append(ind(3) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + "(get" + getImplAttributeName() + "().asUnresolved" + ofTypeDecl() + "().get__token()));\n");
sb.append(ind(2) + "}\n");
}
sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
sb.append(ind(1) + "}\n");
}
......@@ -511,6 +517,125 @@ aspect LowerBoundCheck {
}
}
aspect NameResolutionHelper {
syn boolean TypeDecl.isUnresolved() = false;
eq UnresolvedTypeDecl.isUnresolved() = true;
syn UnresolvedTypeDecl TypeDecl.asUnresolved() = null;
eq UnresolvedTypeDecl.asUnresolved() = this;
public String Program.generateRewriteToSuperTypeStub() {
StringBuilder sb = new StringBuilder();
generateRewriteToSuperTypeStub(sb);
return sb.toString();
}
public void Program.generateRewriteToSuperTypeStub(StringBuilder sb) {
sb.append("aspect RefResolverStubs {\n\n");
for (Relation r: getRelations()) {
r.generateContextDependentNameResolution(sb);
}
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
decl.asUnresolved().generateContextIndependentNameResolution(sb);
sb.append("\n");
}
}
sb.append("}\n\n");
sb.append("aspect ReferenceCreation {\n\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
decl.asUnresolved().createReferenceCreator(sb);
}
}
sb.append("}\n\n");
sb.append("aspect RefResolverHelpers {\n\n");
sb.append(ind(1) + "syn boolean ASTNode.unresolved() = false;\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
sb.append(ind(1) + "eq " + decl.getID() + ".unresolved() = true;\n");
}
}
sb.append("\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
sb.append(ind(1) + "syn " + decl.getID() + " " + decl.getSuper().decl().getID() + ".asUnresolved" + decl.getSuper().decl().getID() + "() = null;\n");
sb.append(ind(1) + "eq " + decl.getID() + ".asUnresolved" + decl.getSuper().decl().getID() + "() = this;\n");
}
}
sb.append("\n}\n");
}
public void UnresolvedTypeDecl.createReferenceCreator(StringBuilder sb) {
String superType = this.getSuper().getID();
sb.append(ind(1) + "public static " + superType + " " + superType + ".createRef(String ref) {\n");
sb.append(ind(2) + getID() + " unresolvedNode = new " + getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set__token(ref);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
}
public void UnresolvedTypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
String superType = this.getSuper().getID();
sb.append(ind(1) + "// context-independent name resolution\n");
sb.append(ind(1) + "syn " + superType + " ASTNode.resolve" + superType + "(String id) {\n");
sb.append(ind(2) + "// perform context independent name resolution here using the id\n");
sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for "+ superType + " not implemented.\");\n");
sb.append(ind(1) + "}\n");
}
public void Relation.generateContextDependentNameResolution(StringBuilder sb) {
sb.append(ind(1) + "// " + prettyPrint() + "\n");
getDirection().generateContextDependentNameResolution(sb);
sb.append("\n");
}
public abstract void Direction.generateContextDependentNameResolution(StringBuilder sb);
public void RightDirection.generateContextDependentNameResolution(StringBuilder sb) {
relation().getLeft().generateContextDependentNameResolution(sb);
}
public void Bidirectional.generateContextDependentNameResolution(StringBuilder sb) {
// TODO
}
public abstract void RelationComponent.generateContextDependentNameResolution(StringBuilder sb);
public void OneRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
generateDirectedContextDependentNameResolution(sb);
}
public void OptionalRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
// TODO
}
public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
// TODO
}
public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) {
// // context-dependent name resolution
// NamedElement A.resolveRel1(String id) {
// // default to context-independent name resolution
// return resolveNamedElement(id);
// }
sb.append(ind(1) + "// context-dependent name resolution\n");
sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "(String id) {\n");
sb.append(ind(2) + "// default to context-independent name resolution\n");
sb.append(ind(2) + "return resolve" + ofTypeDecl() + "(id);\n");
sb.append(ind(1) + "}\n");
}
}
aspect PrettyPrint {
public String Relation.prettyPrint() {
return "rel "
......
Program ::= TypeDecl* Relation*;
TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
UnresolvedTypeDecl:TypeDecl;
abstract Component ::= <ID>;
abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse;
......
......@@ -20,6 +20,7 @@ public class Compiler {
private FlagOption optionPrintAST;
private StringOption optionListClass;
private StringOption optionGrammarName;
private FlagOption optionResolverHelper;
private CommandLine commandLine;
public Compiler(String[] args) throws CommandLineException {
......@@ -34,8 +35,28 @@ public class Compiler {
}
List<String> filenames = commandLine.getArguments();
List<TypeDecl> unresolvedDecls = new ArrayList<>();
Program p = parseProgram(filenames);
if (optionResolverHelper.isSet()) {
// get a list of all (abstract or not) non-terminals
List<TypeDecl> nonTerminals = new ArrayList<>();
for (TypeDecl typeDecl : p.getTypeDecls()) {
nonTerminals.add(typeDecl);
}
// add a new typeDecl with a prefix "Unresolved"
for (TypeDecl typeDecl : nonTerminals) {
UnresolvedTypeDecl unresolvedDecl = new UnresolvedTypeDecl();
unresolvedDecl.setID("__unresolved" + typeDecl.getID());
unresolvedDecl.setAbstract(false);
unresolvedDecl.setSuper(new SimpleTypeUse(typeDecl.getID()));
unresolvedDecl.addComponent(new TokenComponent("__token", new SimpleTypeUse("String")));
p.addTypeDecl(unresolvedDecl);
unresolvedDecls.add(unresolvedDecl);
}
}
if (!p.errors().isEmpty()) {
if (optionPrintAST.isSet()) {
System.out.println(p.dumpTree());
......@@ -58,6 +79,12 @@ public class Compiler {
}
if (optionWriteToFile.isSet()) {
if (optionResolverHelper.isSet()) {
ASTNode.resolverHelper = true;
writeToFile(grammarName + "RefResolver.jadd", p.generateRewriteToSuperTypeStub());
}
writeToFile(grammarName + ".ast", p.generateAbstractGrammar());
writeToFile(grammarName + ".jadd", p.generateAspect());
} else if (optionPrintAST.isSet()) {
......@@ -94,6 +121,7 @@ public class Compiler {
optionPrintAST = addOption(new FlagOption("ast", "print AST"));
optionListClass = addOption(new StringOption("listClass", "determine the class name of the nonterminal reference list"));
optionGrammarName = addOption(new StringOption("grammarName", "name of the generated grammar and aspect (without file extension)"));
optionResolverHelper = addOption(new FlagOption("resolverHelper", "create a subtype for each type containing a string that can be used to resolve the type later"));
}
private <OptionType extends Option<?>> OptionType addOption(OptionType option) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment