Commit 6c2c218f authored by Alexandru Dura's avatar Alexandru Dura
Browse files

WIP: build the SPPF

parent b00ca94e
......@@ -46,4 +46,21 @@ public class DottedRule {
return false;
return true;
}
public String prettyPrint(PrettyPrintingInfo info) {
String s = info.getCategory(r.head).toString() + " -> ";
for (int j = 0; j < r.body.length; ++j) {
if (j == dot) {
s += "\u2022 ";
}
int symbol = r.body[j];
s += info.getCategory(symbol).toString() + " ";
}
if (dot == r.body.length) {
s += "\u2022";
}
return s;
}
}
......@@ -49,4 +49,23 @@ public class EarleyItem {
@Override public int hashCode() {
return (rule.hashCode() * 31 + start) * 31 + (sppf == null ? 0 : sppf.hashCode());
}
public String prettyPrint(PrettyPrintingInfo info) {
String s = info.getCategory(rule.r.head).toString() + " -> ";
for (int j = 0; j < rule.r.body.length; ++j) {
if (j == rule.dot) {
s += "\u2022 ";
}
int symbol = rule.r.body[j];
s += info.getCategory(symbol).toString() + " ";
}
if (rule.dot == rule.r.body.length) {
s += "\u2022";
}
s += "(" + start + ")";
return s;
}
}
......@@ -8,7 +8,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
public class EarleyParser {
public class EarleyParser implements PrettyPrintingInfo {
private boolean DEBUG = true;
private HashMap<Category, Integer> cat2int;
......@@ -28,6 +28,10 @@ public class EarleyParser {
grammarRules = new HashMap<>();
}
@Override public Category getCategory(int i) {
return int2cat.get(i);
}
// Interface to the higher level gramar
public void addCategory(Category t) {
if (t.isTerminal()) {
......@@ -72,39 +76,13 @@ public class EarleyParser {
}
}
private String asString(EarleyRule rule) {
String s = int2cat.get(rule.head).toString() + " -> ";
for (int j : rule.body) {
s += int2cat.get(j).toString() + " ";
}
return s;
}
private String asString(EarleyItem item) {
String s = int2cat.get(item.rule.r.head).toString() + " -> ";
for (int j = 0; j < item.rule.r.body.length; ++j) {
if (j == item.rule.dot) {
s += "\u2022 ";
}
int symbol = item.rule.r.body[j];
s += int2cat.get(symbol).toString() + " ";
}
if (item.rule.dot == item.rule.r.body.length) {
s += "\u2022";
}
s += "(" + item.start + ")";
return s;
}
public String toString() {
String s = "";
for (int i = 1; i < rules.size(); ++i) {
TreeSet<EarleyRule> rs = rules.get(i);
for (EarleyRule r : rs) {
assert r.head == i;
s += asString(r);
s += r.prettyPrint(this);
s += "\n";
}
}
......@@ -204,7 +182,7 @@ public class EarleyParser {
System.out.println("=== Item set at position " + i + " ===");
for (EarleyItem item : state[i]) {
if (item.isComplete())
System.out.println(asString(item));
System.out.println(item.prettyPrint(this));
}
}
}
......@@ -294,7 +272,7 @@ public class EarleyParser {
V.put(vLabel, v);
}
Lambda.setSPPF(v);
// TODO: if w does not have family (eps) add one? 2.1.2
v.addEpsilon(); // 2.1.2
}
if (Lambda.start == i) { // 2.2
H.put(Lambda.rule.r.head, Lambda.getSPPF());
......@@ -339,10 +317,31 @@ public class EarleyParser {
return state;
}
private SPPFNode makeNode(DottedRule dottedRule, int start, int i, SPPFNode sppf, SPPFNode sppf2,
HashMap<NodeLabel, SPPFNode> v) {
return null;
}
private SPPFNode makeNode(DottedRule dottedRule, int j, int i, SPPFNode w, SPPFNode v,
HashMap<NodeLabel, SPPFNode> V) {
NodeLabel s;
if (dottedRule.isComplete()) {
s = new SymbolLabel(dottedRule.r.head, j, i);
} else {
s = new ItemLabel(dottedRule, j, i);
}
if (!dottedRule.isComplete() && dottedRule.dot == 1) {
return v;
} else {
SPPFNode y = V.get(s);
if (y == null) {
y = new SPPFNode(s);
V.put(s, y);
}
if (w == null) {
y.addChild(v);
} else {
y.addChildren(w, v);
}
return y;
}
}
}
......@@ -31,4 +31,12 @@ public class EarleyRule implements Comparable<EarleyRule> {
return 0;
}
}
public String prettyPrint(PrettyPrintingInfo info) {
String s = info.getCategory(head).toString() + " -> ";
for (int j : body) {
s += info.getCategory(j).toString() + " ";
}
return s;
}
}
public class NodeLabel {
public abstract class NodeLabel {
int start, end;
protected NodeLabel(int start, int end) {
this.start = start;
......@@ -15,6 +15,8 @@ public class NodeLabel {
@Override public int hashCode() {
return 31 * start + end;
}
public abstract String prettyPrint(PrettyPrintingInfo info);
}
class ItemLabel extends NodeLabel {
......@@ -34,6 +36,10 @@ class ItemLabel extends NodeLabel {
@Override public int hashCode() {
return super.hashCode() * 31 + item.hashCode();
}
public String prettyPrint(PrettyPrintingInfo info) {
return item.prettyPrint(info) + ", " + super.start + ", " + super.end;
}
}
class SymbolLabel extends NodeLabel {
......@@ -53,4 +59,8 @@ class SymbolLabel extends NodeLabel {
@Override public int hashCode() {
return super.hashCode() * 31 + symbol;
}
public String prettyPrint(PrettyPrintingInfo info) {
return info.getCategory(symbol).toString() + ", " + super.start + ", " + super.end;
}
}
interface PrettyPrintingInfo {
Category getCategory(int i);
}
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class SPPFNode {
private List<SPPFNode> children = new ArrayList<SPPFNode>();
static class FamilyNode {
SPPFNode child1;
SPPFNode child2;
FamilyNode(SPPFNode child1, SPPFNode child2) {
this.child1 = child1;
this.child2 = child2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((child1 == null) ? 0 : child1.hashCode());
result = prime * result + ((child2 == null) ? 0 : child2.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FamilyNode other = (FamilyNode) obj;
if (child1 == null) {
if (other.child1 != null)
return false;
} else if (!child1.equals(other.child1))
return false;
if (child2 == null) {
if (other.child2 != null)
return false;
} else if (!child2.equals(other.child2))
return false;
return true;
}
}
private HashSet<FamilyNode> children = new HashSet<>();
private NodeLabel label;
public SPPFNode() {
......@@ -12,4 +54,24 @@ public class SPPFNode {
public SPPFNode(NodeLabel label) {
this.label = label;
}
public void addChild(SPPFNode child) {
children.add(new FamilyNode(child, null));
}
public void addChildren(SPPFNode child1, SPPFNode child2) {
children.add(new FamilyNode(child1, child2));
}
public void addEpsilon() {
children.add(new FamilyNode(null, null));
}
public String prettyPrint(PrettyPrintingInfo info) {
return label.prettyPrint(info);
}
}
interface SPPFNodeVisitor {
}
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