Commit 9d220f4a authored by Alexandru Dura's avatar Alexandru Dura
Browse files

Implement a visitor that pushes metavar nodes towards the root

parent c4f8d8c0
......@@ -4,7 +4,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class SPPFNode implements Cloneable {
public class SPPFNode {
static public class FamilyNode {
private SPPFNode[] child;
......@@ -42,7 +42,7 @@ public class SPPFNode implements Cloneable {
final int prime = 47;
int result = 1;
for (int i = 0; i < child.length; ++i) {
result = prime * result + ((child[0] == null) ? 0 : child[0].hashCode());
result = prime * result + ((child[i] == null) ? 0 : child[i].hashCode());
}
return result;
}
......
......@@ -32,60 +32,55 @@ public class SPPFTrivialProductionRemover implements SPPFNodeVisitor {
return;
}
Set<SPPFNode.FamilyNode> children = n.getChildren();
for (SPPFNode.FamilyNode f : n.getChildren()) {
f.accept(this);
}
HashSet<SPPFNode.FamilyNode> newChildren = new HashSet<>();
HashSet<SPPFNode.FamilyNode> childrenToRemove = new HashSet<>();
for (SPPFNode.FamilyNode f : children) {
f.accept(this);
for (SPPFNode.FamilyNode f : n.getChildren()) {
if (f.getNumChildren() == 0)
if (f.getNumChildren() != 1)
continue;
SPPFNode[] childArray = new SPPFNode[f.getNumChildren()];
boolean updatedChildren = false;
for (int i = 0; i < f.getNumChildren(); ++i) {
childArray[i] = f.getChild(i);
}
for (int i = 0; i < f.getNumChildren(); ++i) {
SPPFNode ruleNode = f.getChild(i);
assert ruleNode.getLabel() instanceof SymbolLabel;
Category head = ((SymbolLabel)ruleNode.getLabel()).getSymbol(grammar);
boolean allProductionAreTrivial = true;
for (SPPFNode.FamilyNode g : ruleNode.getChildren()) {
if (g.getNumChildren() != 1) {
allProductionAreTrivial = false;
break;
}
SPPFNode bubbleUpChild = null;
SPPFNode nn = f.getChild(i);
for (SPPFNode.FamilyNode ff : nn.getChildren()) {
if (ff.getNumChildren() != 1)
continue;
Category body = ((SymbolLabel)g.getChild(0).getLabel()).getSymbol(grammar);
if (!isTrivialProduction(head, body)) {
allProductionAreTrivial = false;
SymbolLabel label = (SymbolLabel)ff.getChild(0).getLabel();
if (isBubleUpChild(label.getSymbol(grammar))) {
bubbleUpChild = ff.getChild(0);
break;
}
}
if (!allProductionAreTrivial)
continue;
for (SPPFNode.FamilyNode g : ruleNode.getChildren()) {
SPPFNode[] childArray = new SPPFNode[f.getNumChildren()];
for (int j = 0; j < f.getNumChildren(); ++j) {
if (i == j) {
childArray[j] = g.getChild(0);
} else {
childArray[j] = f.getChild(j);
}
}
newChildren.add(new SPPFNode.FamilyNode(childArray));
childrenToRemove.add(f);
if (bubbleUpChild != null) {
childArray[i] = bubbleUpChild;
updatedChildren = true;
}
}
if (updatedChildren) {
childrenToRemove.add(f);
newChildren.add(new FamilyNode(childArray));
}
}
children.removeAll(childrenToRemove);
children.addAll(newChildren);
n.getChildren().removeAll(childrenToRemove);
n.getChildren().addAll(newChildren);
}
public boolean isTrivialProduction(Category head, Category body) {
public boolean isBubleUpChild(Category c) {
return false;
}
}
......@@ -185,13 +185,10 @@ public class EarleyParserTest {
Util.dumpParseResult("testJava1.dot", root, g);
// remove trivial productions
SPPFTrivialProductionRemover tpr = new SPPFTrivialProductionRemover(g) {
@Override public boolean isTrivialProduction(Category head, Category body) {
String sig = head.getName() + "." + body.getName();
if (body.getName().equals("METAVARID"))
@Override public boolean isBubleUpChild(Category c) {
if (c.getName().equals("METAVARID"))
return true;
if (body.getName().equals("GAP"))
return true;
if (Java14Grammar.isTrivialRule(sig))
if (c.getName().equals("GAP"))
return true;
return false;
}
......@@ -229,13 +226,10 @@ public class EarleyParserTest {
Util.dumpParseResult("testJava2.dot", root, g);
// remove trivial productions
SPPFTrivialProductionRemover tpr = new SPPFTrivialProductionRemover(g) {
@Override public boolean isTrivialProduction(Category head, Category body) {
String sig = head.getName() + "." + body.getName();
if (body.getName().equals("METAVARID"))
return true;
if (body.getName().equals("GAP"))
@Override public boolean isBubleUpChild(Category c) {
if (c.getName().equals("METAVARID"))
return true;
if (Java14Grammar.isTrivialRule(sig))
if (c.getName().equals("GAP"))
return true;
return false;
}
......@@ -275,13 +269,10 @@ public class EarleyParserTest {
Util.dumpParseResult("testJava3.dot", root, g);
// remove trivial productions
SPPFTrivialProductionRemover tpr = new SPPFTrivialProductionRemover(g) {
@Override public boolean isTrivialProduction(Category head, Category body) {
String sig = head.getName() + "." + body.getName();
if (body.getName().equals("METAVARID"))
return true;
if (body.getName().equals("GAP"))
@Override public boolean isBubleUpChild(Category c) {
if (c.getName().equals("METAVARID"))
return true;
if (Java14Grammar.isTrivialRule(sig))
if (c.getName().equals("GAP"))
return true;
return false;
}
......@@ -323,11 +314,10 @@ public class EarleyParserTest {
// remove trivial productions
SPPFTrivialProductionRemover tpr = new SPPFTrivialProductionRemover(g) {
@Override public boolean isTrivialProduction(Category head, Category body) {
String sig = head.getName() + "." + body.getName();
if (body.getName().equals("METAVARID"))
@Override public boolean isBubleUpChild(Category c) {
if (c.getName().equals("METAVARID"))
return true;
if (body.getName().equals("GAP"))
if (c.getName().equals("GAP"))
return true;
return false;
}
......
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