Merge pull request #526 from sharwell/def-undef

defineRule and undefineRule
This commit is contained in:
Sam Harwell 2014-03-29 16:35:50 -05:00
commit 6de95c15e7
3 changed files with 69 additions and 5 deletions

View File

@ -61,7 +61,8 @@ public class OrderedHashMap<K,V> extends LinkedHashMap<K,V> {
@Override
public V remove(Object key) {
throw new UnsupportedOperationException();
elements.remove(key);
return super.remove(key);
}
@Override

View File

@ -357,11 +357,59 @@ public class Grammar implements AttributeResolver {
}
}
public void defineRule(Rule r) {
if ( rules.get(r.name)!=null ) return;
/**
* Define the specified rule in the grammar. This method assigns the rule's
* {@link Rule#index} according to the {@link #ruleNumber} field, and adds
* the {@link Rule} instance to {@link #rules} and {@link #indexToRule}.
*
* @param r The rule to define in the grammar.
* @return {@code true} if the rule was added to the {@link Grammar}
* instance; otherwise, {@code false} if a rule with this name already
* existed in the grammar instance.
*/
public boolean defineRule(@NotNull Rule r) {
if ( rules.get(r.name)!=null ) {
return false;
}
rules.put(r.name, r);
r.index = ruleNumber++;
indexToRule.add(r);
return true;
}
/**
* Undefine the specified rule from this {@link Grammar} instance. The
* instance {@code r} is removed from {@link #rules} and
* {@link #indexToRule}. This method updates the {@link Rule#index} field
* for all rules defined after {@code r}, and decrements {@link #ruleNumber}
* in preparation for adding new rules.
* <p>
* This method does nothing if the current {@link Grammar} does not contain
* the instance {@code r} at index {@code r.index} in {@link #indexToRule}.
* </p>
*
* @param r
* @return {@code true} if the rule was removed from the {@link Grammar}
* instance; otherwise, {@code false} if the specified rule was not defined
* in the grammar.
*/
public boolean undefineRule(@NotNull Rule r) {
if (r.index < 0 || r.index >= indexToRule.size() || indexToRule.get(r.index) != r) {
return false;
}
assert rules.get(r.name) == r;
rules.remove(r.name);
indexToRule.remove(r.index);
for (int i = r.index; i < indexToRule.size(); i++) {
assert indexToRule.get(i).index == i + 1;
indexToRule.get(i).index--;
}
ruleNumber--;
return true;
}
// public int getNumRules() {

View File

@ -62,9 +62,24 @@ public class LexerGrammar extends Grammar {
}
@Override
public void defineRule(Rule r) {
super.defineRule(r);
public boolean defineRule(Rule r) {
if (!super.defineRule(r)) {
return false;
}
if ( modes==null ) modes = new MultiMap<String, Rule>();
modes.map(r.mode, r);
return true;
}
@Override
public boolean undefineRule(Rule r) {
if (!super.undefineRule(r)) {
return false;
}
boolean removed = modes.get(r.mode).remove(r);
assert removed;
return true;
}
}