Commit e2d72aa0 authored by Johannes Roith's avatar Johannes Roith

Add better reference resolution support.

parent dd0c10e1
......@@ -664,18 +664,18 @@ preced_type ::=
terminal_list ::= terminal_list:lst COMMA terminal_id:trm
{:
((List<Terminal>) lst).add(new Terminal(trm,
new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright)))); // jrTODO: positions
Range range = new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright));
((List<Terminal>) lst).add(new Terminal(new Name (trm, range), range));
RESULT = lst;
:}
|
terminal_id:trm
{:
Range range = new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright));
List<Terminal> lst = new ArrayList<Terminal>();
lst.add(new Terminal(trm,
new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright)))); // jrTODO: positions
lst.add(new Terminal(new Name (trm, range), range));
RESULT = lst;
:}
;
......@@ -732,11 +732,12 @@ start_spec ::=
new_rhs();
//jrTODO: position, start symbol?, side effects?
parserResult.startWith = new StartWith(
new NonTerminal (start_name, null),
new Range(Position.fromComplexSymbolLeft(head_tokens.pop()),
Position.fromComplexSymbolRight((ComplexSymbol) stack.peek())));
Range range = new Range(Position.fromComplexSymbolLeft(head_tokens.pop()),
Position.fromComplexSymbolRight((ComplexSymbol) stack.peek()));
Range innerRange = new Range(Position.fromLocation(start_namexleft),
Position.fromLocation(start_namexright));
parserResult.startWith = new StartWith(new NonTerminal (new Name (start_name, innerRange), innerRange), range);
}
:}
SEMI
......@@ -945,13 +946,13 @@ prod_part ::=
/* add a labeled production part */
add_rhs_part(add_lab(symb, labid));
ProductionRef ref = null;
ProductionSymbolRef ref = null;
Range range = new Range (Position.fromLocation(symidxleft),
Position.fromLocation(symidxright));
if (labid == null)
ref = new LabeledProductionRef(new Name(symid, range), labid, range);
ref = new LabeledProductionSymbolRef(new Name(symid, range), labid, range);
else
ref = new ProductionRef(new Name(symid, range), range);
ref = new ProductionSymbolRef(new Name(symid, range), range);
ast_add_rhs_part(ref);
}
:}
......@@ -1065,7 +1066,9 @@ new_term_id ::=
symbols.put(term_id,
new symbol_part(new terminal(context, term_id, multipart_name)));
RESULT = new Terminal(term_id, null);
Range range = new Range(Position.fromLocation(term_idxleft),
Position.fromLocation(term_idxright));
RESULT = new Terminal(new Name(term_id, range), range);
}
:}
......@@ -1100,9 +1103,9 @@ new_non_term_id ::=
// jrTODO: positions!
// jrTODO: non_term_id vs. multipart_name
RESULT = new NonTerminal(non_term_id,
new Range(Position.fromLocation(non_term_idxleft),
Position.fromLocation(non_term_idxright)));
Range range = new Range(Position.fromLocation(non_term_idxleft),
Position.fromLocation(non_term_idxright));
RESULT = new NonTerminal(new Name(non_term_id, range), range);
}
:}
;
......
......@@ -113,7 +113,8 @@ public class CupSymbol {
sym.PRECEDENCE,
sym.INIT,
sym.CODE,
sym.EXTENDS
sym.EXTENDS,
sym.START
};
keywordStrings = new String[keywords.length];
......
......@@ -28,7 +28,7 @@ public abstract class AbstractVisitor<T>
public abstract T preVisit (ParserResult node, T data);
public abstract T preVisit (Precedence node, T data);
public abstract T preVisit (Production node, T data);
public abstract T preVisit (ProductionRef node, T data);
public abstract T preVisit (ProductionSymbolRef node, T data);
public abstract T preVisit (ProductionRight node, T data);
public abstract T preVisit (StartWith node, T data);
public abstract T preVisit (Terminal node, T data);
......@@ -47,7 +47,7 @@ public abstract class AbstractVisitor<T>
public abstract void postVisit (ParserResult node, T data);
public abstract void postVisit (Precedence node, T data);
public abstract void postVisit (Production node, T data);
public abstract void postVisit (ProductionRef node, T data);
public abstract void postVisit (ProductionSymbolRef node, T data);
public abstract void postVisit (ProductionRight node, T data);
public abstract void postVisit (StartWith node, T data);
public abstract void postVisit (Terminal node, T data);
......
......@@ -21,7 +21,7 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
public void postVisit (TerminalDeclaration node, Object data) {
if (node != null && node.getTerminals() != null) {
for (Terminal t : node.getTerminals())
result.getTerminals().add(t.getName());
result.getTerminals().add(t.getName().name);
}
}
......@@ -29,7 +29,7 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
public void postVisit (NonTerminalDeclaration node, Object data) {
if (node != null && node.getNonTerminals() != null) {
for (NonTerminal nt : node.getNonTerminals())
result.getNonTerminals().add(nt.getName());
result.getNonTerminals().add(nt.getName().name);
}
}
......@@ -38,7 +38,7 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
// TODO: OAOO!
if (node != null && node.getNonTerminals() != null) {
for (NonTerminal nt : node.getNonTerminals())
result.getNonTerminals().add(nt.getName());
result.getNonTerminals().add(nt.getName().name);
}
}
......@@ -47,7 +47,7 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
// TODO: OAOO!
if (node != null && node.getTerminals() != null) {
for (Terminal nt : node.getTerminals())
result.getNonTerminals().add(nt.getName());
result.getNonTerminals().add(nt.getName().name);
}
}
......
......@@ -6,7 +6,7 @@ import java.util.List;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRef;
import de.in.tum.www2.cup.ast.ProductionSymbolRef;
import de.in.tum.www2.cup.ast.Terminal;
import de.in.tum.www2.cup.ast.NonTerminal;
import de.in.tum.www2.cup.ast.NonTerminalDeclaration;
......@@ -18,7 +18,7 @@ public class RefResolutionVisitor extends Visitor<Object>
{
private HashMap<String, AbstractNode> declarations = new HashMap<String, AbstractNode> ();
private HashMap<String, AbstractNode> definitions = new HashMap<String, AbstractNode> ();
private HashMap<String, List<ProductionRef>> forwardRefs = new HashMap<String, List<ProductionRef>> ();
private HashMap<String, List<ProductionSymbolRef>> forwardRefs = new HashMap<String, List<ProductionSymbolRef>> ();
// should resolve:
// 1. declarations
......@@ -29,25 +29,25 @@ public class RefResolutionVisitor extends Visitor<Object>
@Override public Object preVisit (NonTerminalDeclaration node, Object data) {
for(NonTerminal nt : node.getNonTerminals())
declarations.put(nt.getName(), nt);
declarations.put(nt.getName().name, nt);
return data;
}
@Override public Object preVisit (TerminalDeclaration node, Object data) {
for(Terminal t : node.getTerminals())
declarations.put(t.getName(), t);
declarations.put(t.getName().name, t);
return data;
}
@Override public Object preVisit (TypedNonTerminalDeclaration node, Object data) {
for(NonTerminal nt : node.getNonTerminals())
declarations.put(nt.getName(), nt);
declarations.put(nt.getName().name, nt);
return data;
}
@Override public Object preVisit (TypedTerminalDeclaration node, Object data) {
for(Terminal t : node.getTerminals())
declarations.put(t.getName(), t);
declarations.put(t.getName().name, t);
return data;
}
......@@ -57,13 +57,13 @@ public class RefResolutionVisitor extends Visitor<Object>
// update any forward references.
if (forwardRefs.containsKey(name)) {
for (ProductionRef pr : forwardRefs.get(name))
for (ProductionSymbolRef pr : forwardRefs.get(name))
pr.setDefinition(node);
}
return data;
}
@Override public Object preVisit (ProductionRef node, Object data) {
@Override public Object preVisit (ProductionSymbolRef node, Object data) {
String name = node.getName().name;
if (definitions.containsKey(name)) {
AbstractNode def = definitions.get(name);
......@@ -72,7 +72,7 @@ public class RefResolutionVisitor extends Visitor<Object>
} else {
// the production might still be defined, below, accumulate.
if (!forwardRefs.containsKey(name))
forwardRefs.put(name, new ArrayList<ProductionRef>());
forwardRefs.put(name, new ArrayList<ProductionSymbolRef>());
forwardRefs.get(name).add(node);
}
return data;
......
......@@ -28,7 +28,7 @@ public abstract class Visitor<T> extends AbstractVisitor<T>
@Override public T preVisit (ParserResult node, T data) { return data; }
@Override public T preVisit (Precedence node, T data) { return data; }
@Override public T preVisit (Production node, T data) { return data; }
@Override public T preVisit (ProductionRef node, T data) { return data; }
@Override public T preVisit (ProductionSymbolRef node, T data) { return data; }
@Override public T preVisit (ProductionRight node, T data) { return data; }
@Override public T preVisit (StartWith node, T data) { return data; }
@Override public T preVisit (Terminal node, T data) { return data; }
......@@ -47,7 +47,7 @@ public abstract class Visitor<T> extends AbstractVisitor<T>
@Override public void postVisit (ParserResult node, T data) { }
@Override public void postVisit (Precedence node, T data) { }
@Override public void postVisit (Production node, T data) { }
@Override public void postVisit (ProductionRef node, T data) { }
@Override public void postVisit (ProductionSymbolRef node, T data) { }
@Override public void postVisit (ProductionRight node, T data) { }
@Override public void postVisit (StartWith node, T data) { }
@Override public void postVisit (Terminal node, T data) { }
......
......@@ -24,7 +24,7 @@ public abstract class WildcardVisitor<T> extends AbstractVisitor<T>
public T preVisit (ClassName node, T data) { return preVisitWildcard(node, data); }
public T preVisit (SpecialCodeBlock node, T data) { return preVisitWildcard(node, data); }
public T preVisit (Import node, T data) { return preVisitWildcard(node, data); }
public T preVisit (LabeledProductionRef node, T data) { return preVisitWildcard(node, data); }
public T preVisit (LabeledProductionSymbolRef node, T data) { return preVisitWildcard(node, data); }
public T preVisit (Name node, T data) { return preVisitWildcard(node, data); }
public T preVisit (NonTerminal node, T data) { return preVisitWildcard(node, data); }
public T preVisit (NonTerminalDeclaration node, T data) { return preVisitWildcard(node, data); }
......@@ -32,7 +32,7 @@ public abstract class WildcardVisitor<T> extends AbstractVisitor<T>
public T preVisit (ParserResult node, T data) { return preVisitWildcard(node, data); }
public T preVisit (Precedence node, T data) { return preVisitWildcard(node, data); }
public T preVisit (Production node, T data){ return preVisitWildcard(node, data); }
public T preVisit (ProductionRef node, T data) { return preVisitWildcard(node, data); }
public T preVisit (ProductionSymbolRef node, T data) { return preVisitWildcard(node, data); }
public T preVisit (ProductionRight node, T data) { return preVisitWildcard(node, data); }
public T preVisit (StartWith node, T data) { return preVisitWildcard(node, data); }
public T preVisit (Terminal node, T data) { return preVisitWildcard(node, data); }
......@@ -44,7 +44,7 @@ public abstract class WildcardVisitor<T> extends AbstractVisitor<T>
public void postVisit (ClassName node, T data) { postVisitWildcard(node, data); }
public void postVisit (SpecialCodeBlock node, T data) { postVisitWildcard(node, data); }
public void postVisit (Import node, T data) { postVisitWildcard(node, data); }
public void postVisit (LabeledProductionRef node, T data) { postVisitWildcard(node, data); }
public void postVisit (LabeledProductionSymbolRef node, T data) { postVisitWildcard(node, data); }
public void postVisit (Name node, T data) { postVisitWildcard(node, data); }
public void postVisit (NonTerminal node, T data) { postVisitWildcard(node, data); }
public void postVisit (NonTerminalDeclaration node, T data) { postVisitWildcard(node, data); }
......@@ -52,7 +52,7 @@ public abstract class WildcardVisitor<T> extends AbstractVisitor<T>
public void postVisit (ParserResult node, T data) { postVisitWildcard(node, data); }
public void postVisit (Precedence node, T data) { postVisitWildcard(node, data); }
public void postVisit (Production node, T data) { postVisitWildcard(node, data); }
public void postVisit (ProductionRef node, T data) { postVisitWildcard(node, data); }
public void postVisit (ProductionSymbolRef node, T data) { postVisitWildcard(node, data); }
public void postVisit (ProductionRight node, T data) { postVisitWildcard(node, data); }
public void postVisit (StartWith node, T data) { postVisitWildcard(node, data); }
public void postVisit (Terminal node, T data) { postVisitWildcard(node, data); }
......
......@@ -3,9 +3,14 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
public class ClassName extends AbstractNode {
public class ClassName extends AbstractNode implements IWithName {
public Name name;
private Name name;
@Override
public Name getName () {
return name;
}
public ClassName(Name name, Range range) {
super(range);
......
package de.in.tum.www2.cup.ast;
public interface IHasDeclarationReference {
AbstractNode getDeclaration();
void setDeclaration(AbstractNode node);
}
package de.in.tum.www2.cup.ast;
public interface IHasDefinitionReference {
AbstractNode getDefinition();
void setDefinition(AbstractNode node);
}
package de.in.tum.www2.cup.ast;
public interface IWithName {
Name getName();
}
......@@ -3,9 +3,14 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class Import extends AbstractNode {
public class Import extends AbstractNode implements IWithName {
public Name name;
private Name name;
@Override
public Name getName() {
return name;
}
public Import(Name name, Range range) {
super(range);
......
......@@ -3,14 +3,14 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class LabeledProductionRef extends ProductionRef
public class LabeledProductionSymbolRef extends ProductionSymbolRef
{
public String label; // TODO: Name class?
// TODO: this should point to the declaration, after being resolved by a visitor.
public Production declaration;
public LabeledProductionRef(Name name, String label, Range range) {
public LabeledProductionSymbolRef(Name name, String label, Range range) {
super(name, range);
this.label = label;
}
......
......@@ -3,17 +3,43 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class NonTerminal extends AbstractNode {
public class NonTerminal extends AbstractNode
implements IWithName, IHasDeclarationReference, IHasDefinitionReference {
private String name;
public String getName() {
private Name name;
private Production definitionRef; // has to be resolved first.
private NonTerminal declarationRef; // has to be resolved first.
@Override
public Name getName () {
return name;
}
public NonTerminal(String name, Range range) {
public AbstractNode getDeclaration() {
return declarationRef;
}
public AbstractNode getDefinition() {
return definitionRef;
}
public void setDeclaration(AbstractNode node) {
if (node instanceof NonTerminal)
throw new RuntimeException("Declaration must be a NonTerminal");
this.declarationRef = (NonTerminal) node;
}
public void setDefinition(AbstractNode node) {
if (node instanceof NonTerminal)
throw new RuntimeException("Definition must be a Production");
this.definitionRef = (Production) node;
}
public NonTerminal(Name name, Range range) {
super(range);
this.name = name;
if (this.name != null)
name.setParent(this);
}
@Override protected String getNodeName() { return "NonTerminal"; }
......
......@@ -3,10 +3,15 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class Package extends AbstractNode {
public class Package extends AbstractNode implements IWithName {
public Name name;
private Name name;
@Override
public Name getName() {
return name;
}
public Package(Name name, Range range) {
super(range);
this.name = name;
......
......@@ -33,8 +33,8 @@ public class ProductionRight extends AbstractNode {
public String getDescribingString() {
StringBuilder builder = new StringBuilder ();
for (IProductionRightPart part : lst) {
if (part instanceof ProductionRef) {
ProductionRef ref = (ProductionRef) part;
if (part instanceof ProductionSymbolRef) {
ProductionSymbolRef ref = (ProductionSymbolRef) part;
if (ref.getName() != null && ref.getName().name != null)
builder.append(ref.getName().name);
builder.append(" ");
......
......@@ -3,35 +3,47 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class ProductionRef extends AbstractNode
implements IProductionRightPart
public class ProductionSymbolRef extends AbstractNode
implements IProductionRightPart,
IWithName, IHasDeclarationReference, IHasDefinitionReference
{
private Name name;
private Production definitionRef; // has to be resolved first.
private NonTerminal declarationRef; // has to be resolved first.
@Override
public Name getName () {
return name;
}
public NonTerminal getDeclaration() {
public AbstractNode getDeclaration() {
return declarationRef;
}
public Production getDefinition() {
public AbstractNode getDefinition() {
return definitionRef;
}
public void setDeclaration(NonTerminal nt) {
this.declarationRef = nt;
public void setDeclaration(AbstractNode node) {
// TODO: this might be wrong, since the reference could also be a terminal.
if (node instanceof NonTerminal)
throw new RuntimeException("Declaration must be a NonTerminal");
this.declarationRef = (NonTerminal) node;
}
public void setDefinition(Production production) {
this.definitionRef = production;
public void setDefinition(AbstractNode node) {
// TODO: this might be wrong, since the reference could also be a terminal.
if (node instanceof NonTerminal)
throw new RuntimeException("Definition must be a Production");
this.definitionRef = (Production) node;
}
public ProductionRef(Name name, Range range) {
public ProductionSymbolRef(Name name, Range range) {
super(range);
this.name = name;
if (name != null)
......
......@@ -3,17 +3,20 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class Terminal extends AbstractNode {
public class Terminal extends AbstractNode implements IWithName {
private String name;
public String getName() {
private Name name;
@Override
public Name getName () {
return name;
}
public Terminal(String name, Range range) {
public Terminal(Name name, Range range) {
super(range);
this.name = name;
if (this.name != null)
name.setParent(this);
}
@Override protected String getNodeName() { return "Terminal"; }
......
......@@ -12,7 +12,7 @@ import de.in.tum.www2.cup.analysis.FindAtPositionVisitor;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRef;
import de.in.tum.www2.cup.ast.ProductionSymbolRef;
import de.tum.in.www2.cupplugin.controller.PluginUtility;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.MultiPageEditor;
......@@ -42,7 +42,7 @@ public class OpenDeclarationHandler extends AbstractHandler {
AbstractNode node = pf.getResult();
if (node != null) {
AbstractNode parent = node.getParent();
if (parent != null && parent instanceof ProductionRef) {
if (parent != null && parent instanceof ProductionSymbolRef) {
// TODO!
......
......@@ -17,7 +17,7 @@ import de.in.tum.www2.cup.ast.Name;
import de.in.tum.www2.cup.ast.NonTerminalDeclaration;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRef;
import de.in.tum.www2.cup.ast.ProductionSymbolRef;
import de.tum.in.www2.cupplugin.controller.PluginUtility;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.MultiPageEditor;
......@@ -47,11 +47,11 @@ public class OpenDefinitionHandler extends AbstractHandler {
if (node != null) {
AbstractNode parent = node.getParent();
// TODO: we should also support this operation if we click on a definition
//
// TODO: we should also support this operation if we click on a declaration.
//
if (parent != null && parent instanceof ProductionRef) {
ProductionRef prodRef = (ProductionRef) parent;
if (parent != null && parent instanceof ProductionSymbolRef) {
ProductionSymbolRef prodRef = (ProductionSymbolRef) parent;
Production definition = prodRef.getDefinition();
if (definition != null) {
......
......@@ -289,14 +289,14 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
@Override
public void postVisit(Import node, OutlineEntry data) {
// TODO: name range not yet supported.
addImport(OutlineEntry.fromNode("import " + node.name.name, node));
addImport(OutlineEntry.fromNode("import " + node.getName().name, node));
}
@Override
public void postVisit(Package node, OutlineEntry data) {
root.children.add(OutlineEntry.fromNode(
"package " + node.name.name, node));
"package " + node.getName().name, node));
}
@Override
......@@ -306,7 +306,7 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
if (node.terminals != null) {
builder.append(" ");
builder.append(Utility.shortenedList(node.terminals,
t -> t.getName(), this.shortenListsTo));
t -> t.getName().name, this.shortenListsTo));
}
addDeclOrPrec(OutlineEntry.fromNode(builder.toString(), node));
}
......@@ -343,8 +343,8 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
public void postVisit(ClassName node, OutlineEntry data) {
StringBuilder builder = new StringBuilder();
builder.append("class name ");
if (node.name != null && node.name.name != null)
builder.append(node.name.name);
if (node.getName() != null && node.getName().name != null)
builder.append(node.getName().name);
root.children.add(OutlineEntry.fromNode(builder.toString(), node));
}
......@@ -352,7 +352,7 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
if (lst == null)
return "Terminals";
StringBuilder builder = new StringBuilder();
builder.append(Utility.shortenedList(lst, nt -> nt.getName(),
builder.append(Utility.shortenedList(lst, nt -> nt.getName().name,
this.shortenListsTo));
return builder.toString();
}
......@@ -361,7 +361,7 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
if (lst == null)
return "Non-Terminals";
StringBuilder builder = new StringBuilder();
builder.append(Utility.shortenedList(lst, nt -> nt.getName(),
builder.append(Utility.shortenedList(lst, nt -> nt.getName().name,
this.shortenListsTo));
return builder.toString();
}
......
Markdown is supported
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