Commit 6f723b7d authored by Sebastian Pretscher's avatar Sebastian Pretscher

Merge branch 'master' of git@github.com:jroith/cup-eclipse.git

parents e62c83e2 04a0ad73
......@@ -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];
......
......@@ -10,10 +10,15 @@ import de.in.tum.www2.cup.internal.production;
public class LALRResult {
private final CupContext context;
private lalr_state start_state;
private parse_action_table action_table;
private parse_reduce_table reduce_table;
public CupContext getContext() {
return context;
}
public lalr_state getStartState() {
return start_state;
}
......@@ -26,12 +31,13 @@ public class LALRResult {
return reduce_table;
}
private LALRResult() {
private LALRResult(CupContext context) {
this.context = context;
}
public static LALRResult Compute (CupContext context, production start_production) throws internal_error {
LALRResult result = new LALRResult();
LALRResult result = new LALRResult(context);
non_terminal.compute_nullability(context);
non_terminal.compute_first_sets(context);
......
......@@ -27,7 +27,7 @@ public class Range {
if (pos == null || begin == null || end == null)
return false;
if (pos.getLine() >= begin.getLine() && pos.getLine() <= end.getLine()) {
if (pos.getLine() == begin.getLine()
&& pos.getColumn() < begin.getColumn())
return false;
......
......@@ -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);
}
}
......
......@@ -26,8 +26,9 @@ public class FindAtPositionVisitor extends Visitor<Object>
Range range = node.getRange();
if (range == null)
return;
if (range.contains(pos))
if (range.contains(pos)) {
result = node;
}
}
@Override
......
package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.ast.*;
public class FindNextCodeBlockLineVisitor extends Visitor<Object>
{
private int line;
private int result;
public int getResult() {
return result;
}
public FindNextCodeBlockLineVisitor(int line) {
this.line = line;
this.result = -1;
}
private void doCheck(AbstractNode node) {
if (node == null)
return;
int blockLine = node.getBegin().getLine();
if (result != -1)
return;
if (line >= blockLine && line <= node.getEnd().getLine()) {
result = line;
return;
}
if (blockLine > line)
result = blockLine;
}
@Override
public void postVisit (ActionCodeBlock node, Object data) {
doCheck(node);
}
@Override
public void postVisit (SpecialCodeBlock node, Object data) {
doCheck(node);
}
}
package de.in.tum.www2.cup.analysis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.IHasDeclarationReference;
import de.in.tum.www2.cup.ast.IHasDefinitionReference;
import de.in.tum.www2.cup.ast.Precedence;
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.StartWith;
import de.in.tum.www2.cup.ast.Terminal;
import de.in.tum.www2.cup.ast.NonTerminal;
import de.in.tum.www2.cup.ast.NonTerminalDeclaration;
......@@ -14,52 +20,99 @@ import de.in.tum.www2.cup.ast.TypedTerminalDeclaration;
public class RefResolutionVisitor extends Visitor<Object>
{
HashMap<String, AbstractNode> declarations = new HashMap<String, AbstractNode> ();
HashMap<String, AbstractNode> definitions = new HashMap<String, AbstractNode> ();
private HashMap<String, AbstractNode> declarations;
private HashMap<String, AbstractNode> definitions;
private HashMap<String, List<IHasDefinitionReference>> forwardDefRefs;
public RefResolutionVisitor() {
declarations = new HashMap<String, AbstractNode> ();
definitions = new HashMap<String, AbstractNode> ();
forwardDefRefs = new HashMap<String, List<IHasDefinitionReference>> ();
}
private void resolveDeclarationFrom(String name, IHasDeclarationReference node) {
if (declarations.containsKey(name)) {
AbstractNode def = declarations.get(name);
node.setDeclaration(def);
}
}
// should resolve:
// 1. declarations
// 2. matching precedences
// 3. definitions (of non-terminals)
private void resolveDefinitionFrom(String name, IHasDefinitionReference node) {
if (definitions.containsKey(name)) {
AbstractNode def = definitions.get(name);
node.setDefinition(def);
} else {
// the production might still be defined, below, accumulate.
if (!forwardDefRefs.containsKey(name))
forwardDefRefs.put(name, new ArrayList<IHasDefinitionReference>());
forwardDefRefs.get(name).add(node);
}
}
// resolve ProductionRef nodes and all identifiers.
@Override public Object preVisit (StartWith node, Object data) {
NonTerminal nt = node.getNonTerminal();
if (nt != null) {
String name = nt.getName().name;
resolveDefinitionFrom(name, nt);
resolveDeclarationFrom(name, nt);
}
return data;
}
@Override public Object preVisit (NonTerminalDeclaration node, Object data) {
for(NonTerminal nt : node.getNonTerminals())
declarations.put(nt.getName(), nt);
for(NonTerminal nt : node.getNonTerminals()) {
String name = nt.getName().name;
declarations.put(name, nt);
resolveDefinitionFrom(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);
for(NonTerminal nt : node.getNonTerminals()) {
String name = nt.getName().name;
declarations.put(name, nt);
resolveDefinitionFrom(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;
}
@Override public Object preVisit (Precedence node, Object data) {
for(Terminal t : node.getTerminals())
resolveDeclarationFrom(t.getName().name, t);
return data;
}
@Override public Object preVisit (Production node, Object data) {
definitions.put(node.getName().name, node);
String name = node.getName().name;
definitions.put(name, node);
resolveDeclarationFrom(name, node); // handles the LHS
// update any forward references.
if (forwardDefRefs.containsKey(name)) {
for (IHasDefinitionReference d : forwardDefRefs.get(name))
d.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);
if (def instanceof Production)
node.setDefinition((Production) def);
}
resolveDefinitionFrom(name, node);
resolveDeclarationFrom(name, 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,24 +3,54 @@ 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 AbstractNode getDeclaration() {
return declarationRef;
}
public NonTerminal(String name, Range range) {
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 Production))
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"; }
@Override
public <T> void accept(AbstractVisitor<T> visitor, T data) {
visitor.preVisit(this, data);
T childArg = visitor.preVisit(this, data);
if (visitor.resetDescend()) {
if (name != null)
name.accept(visitor, childArg);
}
visitor.postVisit(this, data);
}
......
......@@ -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;
......
......@@ -7,6 +7,9 @@ import de.in.tum.www2.cup.internal.assoc;
import de.in.tum.www2.cup.Range;
public class Precedence extends AbstractNode {
private Type type;
private List<Terminal> terminals;
public enum Type {
Left,
......@@ -24,9 +27,14 @@ public class Precedence extends AbstractNode {
}
throw new RuntimeException("impossible.");
}
public Type type;
public List<Terminal> terminals;
public Type getType() {
return type;
}
public List<Terminal> getTerminals() {
return terminals;
}
public Precedence(int assoc, List<Terminal> lst, Range range) {
super(range);
......
......@@ -5,15 +5,30 @@ import java.util.List;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class Production extends AbstractNode {
public class Production extends AbstractNode
implements IWithName, IHasDeclarationReference
{
private NonTerminal declarationRef;
private Name lhs;
private List<ProductionRight> rhs;
@Override
public Name getName() {
return lhs;
}
@Override
public AbstractNode getDeclaration() {
return declarationRef;
}
@Override
public void setDeclaration(AbstractNode node) {
if (!(node instanceof NonTerminal))
throw new RuntimeException("Declaration must be a NonTerminal");
this.declarationRef = (NonTerminal) node;
}
public Production(Name lhs,
List<ProductionRight> rhs, Range range) {
super(range);
......@@ -33,6 +48,8 @@ public class Production extends AbstractNode {
public <T> void accept(AbstractVisitor<T> visitor, T data) {
T childArg = visitor.preVisit(this, data);
if (visitor.resetDescend()) {
if (lhs != null)
lhs.accept(visitor, childArg);
if (rhs != null) {
for (ProductionRight pr : rhs)
pr.accept(visitor, childArg);
......@@ -54,5 +71,5 @@ public class Production extends AbstractNode {