Commit 24daf195 authored by Alexandru Dura's avatar Alexandru Dura
Browse files

Add categories implicitly when used in the rules

parent a617e894
import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeSet;
public class Grammar implements PrettyPrintingInfo {
private HashMap<Category, Integer> cat2int = new HashMap<>();
private HashMap<Integer, Category> int2cat = new HashMap<>();
private HashMap<Category, ArrayList<Rule>> grammarRules = new HashMap<>();
private int nonTermIndex = 1;
private int termIndex = -1;
ArrayList<TreeSet<EarleyRule>> rules;
public ArrayList<TreeSet<EarleyRule>> getInternalRules() {
// lazily initialize the rule table
if (rules == null)
computeInternalRules();
return rules;
}
public Grammar() {
}
private void addCategory(Category t) {
if (cat2int.containsKey(t))
return;
if (t.isTerminal()) {
cat2int.put(t, termIndex);
int2cat.put(termIndex, t);
termIndex--;
} else {
cat2int.put(t, nonTermIndex);
int2cat.put(nonTermIndex, t);
nonTermIndex++;
}
}
public void addRule(Rule r) {
addCategory(r.getHead());
for (Category c : r.getBody())
addCategory(c);
ArrayList<Rule> list = grammarRules.get(r.getHead());
if (list == null) {
list = new ArrayList<Rule>();
grammarRules.put(r.getHead(), list);
}
list.add(r);
}
private void computeInternalRules() {
rules = new ArrayList<>(grammarRules.size() + 1);
rules.add(new TreeSet<EarleyRule>());
for (int i = 1; i < grammarRules.size() + 1; ++i) {
Category head = int2cat.get(i);
ArrayList<Rule> bodies = grammarRules.get(head);
TreeSet<EarleyRule> eBodies = new TreeSet<>();
for (Rule b : bodies) {
int[] body = new int[b.getBody().size()];
for (int j = 0; j < body.length; ++j) {
body[j] = cat2int.get(b.getBody().get(j));
}
eBodies.add(new EarleyRule(i, body));
}
rules.add(eBodies);
}
}
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 += r.prettyPrint(this);
s += "\n";
}
}
return s;
}
@Override
public Category getCategory(int i) {
Category c = int2cat.get(i);
if (c == null)
throw new EarleyException("Symbol index not present in the grammar");
return c;
}
public int getInternalSymbol(Category c) {
Integer i = cat2int.get(c);
if (i == null)
throw new EarleyException("Category not present in the gramamr");
return i;
}
}
......@@ -19,14 +19,6 @@ public class EarleyParserTest {
Grammar g = new Grammar();
g.addCategory(num);
g.addCategory(var);
g.addCategory(plus);
g.addCategory(times);
g.addCategory(s);
g.addCategory(p);
g.addCategory(t);
g.addRule(new Rule(s, s, plus, p));
g.addRule(new Rule(s, p));
g.addRule(new Rule(p, p, times, t));
......@@ -60,14 +52,6 @@ public class EarleyParserTest {
EarleyParser makeAmbiguousParser() {
Grammar g = new Grammar();
g.addCategory(num);
g.addCategory(var);
g.addCategory(plus);
g.addCategory(times);
g.addCategory(metaVar);
g.addCategory(s);
g.addCategory(p);
g.addCategory(t);
g.addRule(new Rule(s, s, plus, p));
g.addRule(new Rule(s, p));
......@@ -96,8 +80,6 @@ public class EarleyParserTest {
Grammar g = new Grammar();
g.addCategory(S);
g.addCategory(b);
g.addRule(new Rule(S, S, S));
g.addRule(new Rule(S, b));
......@@ -117,13 +99,6 @@ public class EarleyParserTest {
Grammar g = new Grammar();
g.addCategory(S);
g.addCategory(A);
g.addCategory(B);
g.addCategory(T);
g.addCategory(a);
g.addCategory(b);
g.addRule(new Rule(S, A, T));
g.addRule(new Rule(S, a, T));
g.addRule(new Rule(A, a));
......@@ -154,6 +129,10 @@ public class EarleyParserTest {
Java14Grammar.t_METAVARID,
Java14Grammar.t_PLUS,
Java14Grammar.t_METAVARID,
Java14Grammar.t_PLUS,
Java14Grammar.t_METAVARID,
Java14Grammar.t_PLUS,
Java14Grammar.t_METAVARID,
Java14Grammar.t_SEMICOLON};
assertTrue(parser.recognize(str, Java14Grammar.n_statement));
......
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