Skip to content

Commit

Permalink
Merge branch 'antlr:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
RobEin authored Mar 17, 2024
2 parents 29a3d4e + 69cfd8e commit dbf7983
Show file tree
Hide file tree
Showing 13 changed files with 470 additions and 100 deletions.
110 changes: 110 additions & 0 deletions runtime/JavaScript/spec/BitSetSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import BitSet from "../src/antlr4/misc/BitSet.js";

describe('test BitSet', () => {

it("is empty", () => {
const bs = new BitSet();
expect(bs.length).toEqual(0);
})

it("sets 1 value", () => {
const bs = new BitSet();
bs.set(67);
expect(bs.length).toEqual(1);
expect(bs.get(67)).toBeTrue();
})

it("clears 1 value", () => {
const bs = new BitSet();
bs.set(67);
bs.clear(67)
expect(bs.length).toEqual(0);
expect(bs.get(67)).toBeFalse();
})

it("sets 2 consecutive values", () => {
const bs = new BitSet();
bs.set(67);
bs.set(68);
expect(bs.length).toEqual(2);
expect(bs.get(67)).toBeTrue();
expect(bs.get(68)).toBeTrue();
})

it("sets 2 close values", () => {
const bs = new BitSet();
bs.set(67);
bs.set(70);
expect(bs.length).toEqual(2);
expect(bs.get(67)).toBeTrue();
expect(bs.get(70)).toBeTrue();
})

it("sets 2 distant values", () => {
const bs = new BitSet();
bs.set(67);
bs.set(241);
expect(bs.length).toEqual(2);
expect(bs.get(67)).toBeTrue();
expect(bs.get(241)).toBeTrue();
})

it("combines 2 identical sets", () => {
const bs1 = new BitSet();
bs1.set(67);
const bs2 = new BitSet();
bs2.set(67);
bs1.or(bs2);
expect(bs1.length).toEqual(1);
expect(bs1.get(67)).toBeTrue();
})

it("combines 2 distinct sets", () => {
const bs1 = new BitSet();
bs1.set(67);
const bs2 = new BitSet();
bs2.set(69);
bs1.or(bs2);
expect(bs1.length).toEqual(2);
expect(bs1.get(67)).toBeTrue();
expect(bs1.get(69)).toBeTrue();
})

it("combines 2 overlapping sets", () => {
const bs1 = new BitSet();
bs1.set(67);
bs1.set(69);
const bs2 = new BitSet();
bs2.set(69);
bs2.set(71);
bs1.or(bs2);
expect(bs1.length).toEqual(3);
expect(bs1.get(67)).toBeTrue();
expect(bs1.get(69)).toBeTrue();
expect(bs1.get(71)).toBeTrue();
})

it("returns values", () => {
const bs = new BitSet();
bs.set(67);
bs.set(69);
const values = bs.values();
expect(values).toEqual([67, 69]);
})

it("counts bits", () => {
for(let i= 0; i <= 0xFF; i++) {
// count bits the slow but easy to understand way (Kernighan method)
let count1 = 0;
let value = i;
while(value) {
if(value & 1)
count1++;
value >>= 1;
}
// count bits the fast way
const count2 = BitSet._bitCount(i);
expect(count2).toEqual(count1);
}
})
})
60 changes: 60 additions & 0 deletions runtime/JavaScript/spec/HashMapSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import HashMap from "../src/antlr4/misc/HashMap.js";
import HashCode from "../src/antlr4/misc/HashCode.js";

class Thing {

value1 = Math.random();
value2 = Math.random();

hashCode() {
return HashCode.hashStuff(this.value1);
}

equals(other) {
return other instanceof Thing
&& other.value1 === this.value1
&& other.value2 === this.value2;
}
}

describe('test HashMap', () => {

it("sets a thing", () => {
const t1 = new Thing();
const map = new HashMap();
map.set("abc", t1);
expect(map.containsKey("abc")).toBeTrue();
expect(map.containsKey("def")).toBeFalse();
expect(map.length).toEqual(1);
})

it("gets a thing", () => {
const t1 = new Thing();
const map = new HashMap();
map.set("abc", t1);
const t2 = map.get("abc");
expect(t2).toEqual(t1);
})

it("replaces a thing", () => {
const t1 = new Thing();
const t2 = new Thing();
const map = new HashMap();
map.set("abc", t1);
map.set("abc", t2);
const t3 = map.get("abc");
expect(t3).toEqual(t2);
})

it("returns correct length", () => {
const t1 = new Thing();
const t2 = new Thing();
const map = new HashMap();
expect(map.length).toEqual(0);
map.set("abc", t1);
expect(map.length).toEqual(1);
map.set("def", t2);
expect(map.length).toEqual(2);
})

});
52 changes: 52 additions & 0 deletions runtime/JavaScript/spec/HashSetSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import HashSet from "../src/antlr4/misc/HashSet.js";
import HashCode from "../src/antlr4/misc/HashCode.js";

class Thing {

value1 = Math.random();
value2 = Math.random();

hashCode() {
return HashCode.hashStuff(this.value1);
}

equals(other) {
return other instanceof Thing
&& other.value1 === this.value1
&& other.value2 === this.value2;
}
}
describe('test HashSet', () => {

it("adds a thing", () => {
const t1 = new Thing();
const t2 = new Thing();
const set = new HashSet();
set.add(t1);
expect(set.has(t1)).toBeTrue();
expect(set.has(t2)).toBeFalse();
expect(set.length).toEqual(1);
})

it("adds a thing once only", () => {
const t1 = new Thing();
const set = new HashSet();
set.add(t1);
set.add(t1);
expect(set.has(t1)).toBeTrue();
expect(set.length).toEqual(1);
})

it("adds 2 things with same hash code", () => {
const t1 = new Thing();
const t2 = new Thing();
t2.value1 = t1.value1;
const set = new HashSet();
set.add(t1);
set.add(t2);
expect(set.has(t1)).toBeTrue();
expect(set.has(t2)).toBeTrue();
expect(set.length).toEqual(2);
})

})
5 changes: 2 additions & 3 deletions runtime/JavaScript/spec/IntervalSetSpec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import antlr4 from "../src/antlr4/index.node.js";
const IntervalSet = antlr4.IntervalSet;
import IntervalSet from "../src/antlr4/misc/IntervalSet.js";

describe('IntervalSet', () => {
describe('test IntervalSet', () => {
it("computes interval set length", () => {
const s1 = new IntervalSet();
s1.addOne(20);
Expand Down
2 changes: 1 addition & 1 deletion runtime/JavaScript/src/antlr4/atn/ATNConfigSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export default class ATNConfigSet {
if (config.reachesIntoOuterContext > 0) {
this.dipsIntoOuterContext = true;
}
const existing = this.configLookup.add(config);
const existing = this.configLookup.getOrAdd(config);
if (existing === config) {
this.cachedHashCode = -1;
this.configs.push(config); // track order here
Expand Down
12 changes: 6 additions & 6 deletions runtime/JavaScript/src/antlr4/atn/LL1Analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,17 @@ export default class LL1Analyzer {
return;
}
if (ctx !== PredictionContext.EMPTY) {
const removed = calledRuleStack.has(s.ruleIndex);
const removed = calledRuleStack.get(s.ruleIndex);
try {
calledRuleStack.remove(s.ruleIndex);
calledRuleStack.clear(s.ruleIndex);
// run thru all possible stack tops in ctx
for (let i = 0; i < ctx.length; i++) {
const returnState = this.atn.states[ctx.getReturnState(i)];
this._LOOK(returnState, stopState, ctx.getParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
}
}finally {
if (removed) {
calledRuleStack.add(s.ruleIndex);
calledRuleStack.set(s.ruleIndex);
}
}
return;
Expand All @@ -153,15 +153,15 @@ export default class LL1Analyzer {
for(let j=0; j<s.transitions.length; j++) {
const t = s.transitions[j];
if (t.constructor === RuleTransition) {
if (calledRuleStack.has(t.target.ruleIndex)) {
if (calledRuleStack.get(t.target.ruleIndex)) {
continue;
}
const newContext = SingletonPredictionContext.create(ctx, t.followState.stateNumber);
try {
calledRuleStack.add(t.target.ruleIndex);
calledRuleStack.set(t.target.ruleIndex);
this._LOOK(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
} finally {
calledRuleStack.remove(t.target.ruleIndex);
calledRuleStack.clear(t.target.ruleIndex);
}
} else if (t instanceof AbstractPredicateTransition ) {
if (seeThruPreds) {
Expand Down
14 changes: 7 additions & 7 deletions runtime/JavaScript/src/antlr4/atn/ParserATNSimulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ export default class ParserATNSimulator extends ATNSimulator {
let altToPred = [];
for(let i=0;i<configs.items.length;i++) {
const c = configs.items[i];
if(ambigAlts.has( c.alt )) {
if(ambigAlts.get( c.alt )) {
altToPred[c.alt] = SemanticContext.orContext(altToPred[c.alt] || null, c.semanticContext);
}
}
Expand Down Expand Up @@ -1039,7 +1039,7 @@ export default class ParserATNSimulator extends ATNSimulator {
for (let i=1; i<altToPred.length;i++) {
const pred = altToPred[i];
// unpredicated is indicated by SemanticContext.NONE
if( ambigAlts!==null && ambigAlts.has( i )) {
if( ambigAlts!==null && ambigAlts.get( i )) {
pairs.push(new PredPrediction(pred, i));
}
if (pred !== SemanticContext.NONE) {
Expand Down Expand Up @@ -1173,7 +1173,7 @@ export default class ParserATNSimulator extends ATNSimulator {
for(let i=0;i<predPredictions.length;i++) {
const pair = predPredictions[i];
if (pair.pred === SemanticContext.NONE) {
predictions.add(pair.alt);
predictions.set(pair.alt);
if (! complete) {
break;
}
Expand All @@ -1187,7 +1187,7 @@ export default class ParserATNSimulator extends ATNSimulator {
if (this.debug || this.dfa_debug) {
console.log("PREDICT " + pair.alt);
}
predictions.add(pair.alt);
predictions.set(pair.alt);
if (! complete) {
break;
}
Expand Down Expand Up @@ -1287,7 +1287,7 @@ export default class ParserATNSimulator extends ATNSimulator {
}

c.reachesIntoOuterContext += 1;
if (closureBusy.add(c)!==c) {
if (closureBusy.getOrAdd(c)!==c) {
// avoid infinite recursion for right-recursive rules
continue;
}
Expand All @@ -1297,7 +1297,7 @@ export default class ParserATNSimulator extends ATNSimulator {
console.log("dips into outer ctx: " + c);
}
} else {
if (!t.isEpsilon && closureBusy.add(c)!==c){
if (!t.isEpsilon && closureBusy.getOrAdd(c)!==c){
// avoid infinite recursion for EOF* and EOF+
continue;
}
Expand Down Expand Up @@ -1544,7 +1544,7 @@ export default class ParserATNSimulator extends ATNSimulator {
let conflictingAlts = null;
if (configs.uniqueAlt!== ATN.INVALID_ALT_NUMBER) {
conflictingAlts = new BitSet();
conflictingAlts.add(configs.uniqueAlt);
conflictingAlts.set(configs.uniqueAlt);
} else {
conflictingAlts = configs.conflictingAlts;
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/JavaScript/src/antlr4/atn/PredictionMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ const PredictionMode = {
alts = new BitSet();
configToAlts.set(cfg, alts);
}
alts.add(cfg.alt);
alts.set(cfg.alt);
});
return configToAlts.getValues();
},
Expand All @@ -532,7 +532,7 @@ const PredictionMode = {
alts = new BitSet();
m.set(c.state, alts);
}
alts.add(c.alt);
alts.set(c.alt);
});
return m;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default class DiagnosticErrorListener extends ErrorListener {
}
const result = new BitSet()
for (let i = 0; i < configs.items.length; i++) {
result.add(configs.items[i].alt);
result.set(configs.items[i].alt);
}
return `{${result.values().join(", ")}}`;
}
Expand Down
Loading

0 comments on commit dbf7983

Please sign in to comment.