Skip to content

Commit

Permalink
Converted ATNState.stateType back to in an instance member.
Browse files Browse the repository at this point in the history
Querying the static member if you only have an instance leads to ugly code.

Signed-off-by: Mike Lischke <[email protected]>
  • Loading branch information
mike-lischke committed Mar 2, 2024
1 parent a03c278 commit 78cfeb6
Show file tree
Hide file tree
Showing 23 changed files with 88 additions and 72 deletions.
4 changes: 4 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@
],
"runtimeArgs": [
"--no-warnings=ExperimentalWarning",
"--enable-source-maps",
"--loader",
"ts-node/esm",
"tests/benchmarks/run-benchmarks.ts",
],
"sourceMaps": true,
"outFiles": [
"dist/*.?js"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
Expand Down
2 changes: 1 addition & 1 deletion src/DefaultErrorStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export class DefaultErrorStrategy {
return;
}

switch ((s.constructor as typeof ATNState).stateType) {
switch (s.stateType) {

Check failure on line 224 in src/DefaultErrorStrategy.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 224 in src/DefaultErrorStrategy.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
case ATNState.BLOCK_START:
case ATNState.STAR_BLOCK_START:
case ATNState.PLUS_BLOCK_START:
Expand Down
7 changes: 6 additions & 1 deletion src/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,12 @@ export abstract class Parser extends Recognizer<ParserATNSimulator> {
return this.#bypassAltsAtnCache;
}

const deserializationOptions = { readOnly: false, verifyATN: true, generateRuleBypassTransitions: true };
const deserializationOptions = {
readOnly: false,
verifyATN: true,
generateRuleBypassTransitions: true,
optimize: true,
};
this.#bypassAltsAtnCache = new ATNDeserializer(deserializationOptions).deserialize(serializedAtn);

return this.#bypassAltsAtnCache;
Expand Down
6 changes: 3 additions & 3 deletions src/ParserInterpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class ParserInterpreter extends Parser {

while (true) {
const p = this.atnState;
switch ((p.constructor as typeof ATNState).stateType) {
switch (p.stateType) {

Check failure on line 119 in src/ParserInterpreter.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 119 in src/ParserInterpreter.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
case ATNState.RULE_STOP:
// pop; return from rule
if (this.context?.isEmpty) {
Expand Down Expand Up @@ -180,8 +180,8 @@ export class ParserInterpreter extends Parser {
const transition = p.transitions[predictedAlt - 1];
switch (transition.transitionType) {
case Transition.EPSILON:
if (this.#pushRecursionContextStates.get(p.stateNumber) &&
!((transition.target.constructor as typeof ATNState).stateType === ATNState.LOOP_END)) {
if (this.#pushRecursionContextStates.get(p.stateNumber)
&& !(transition.target.stateType === ATNState.LOOP_END)) {

Check failure on line 184 in src/ParserInterpreter.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 184 in src/ParserInterpreter.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
// We are at the start of a left recursive rule's (...)* loop
// and we're not taking the exit branch of loop.
const parentContext = this.#parentContextStack[this.#parentContextStack.length - 1];
Expand Down
54 changes: 22 additions & 32 deletions src/atn/ATNConfigSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,16 @@ class KeyTypeEqualityComparer implements EqualityComparator<ATNConfig> {
export class ATNConfigSet {
/**
* The reason that we need this is because we don't want the hash map to use
* the standard hash code and equals. We need all configurations with the
* same
* `(s,i,_,semctx)` to be equal. Unfortunately, this key effectively
* doubles
* the number of objects associated with ATNConfigs. The other solution is
* to
* the standard hash code and equals. We need all configurations with the same
* `(s,i,_,semctx)` to be equal. Unfortunately, this key effectively doubles
* the number of objects associated with ATNConfigs. The other solution is to
* use a hash table that lets us specify the equals/hashCode operation.
* All configs but hashed by (s, i, _, pi) not including context. Wiped out
* when we go readonly as this set becomes a DFA state
*/
public configLookup: HashSet<ATNConfig> | null =
new HashSet<ATNConfig>(KeyTypeEqualityComparer.instance);
public configLookup: HashSet<ATNConfig> | null = new HashSet<ATNConfig>(KeyTypeEqualityComparer.instance);

// Track the elements as they are added to the set; supports get(i).
/** Track the elements as they are added to the set; supports get(i). */
public configs: ATNConfig[] = [];

public uniqueAlt = 0;
Expand Down Expand Up @@ -103,20 +99,20 @@ export class ATNConfigSet {

#cachedHashCode = -1;

public constructor(fullCtxOrOldSet?: boolean | ATNConfigSet) {
if (fullCtxOrOldSet !== undefined) {
if (typeof fullCtxOrOldSet === "boolean") {
this.fullCtx = fullCtxOrOldSet ?? true;
} else {
const old = fullCtxOrOldSet;

this.addAll(old.configs);
this.uniqueAlt = old.uniqueAlt;
this.conflictingAlts = old.conflictingAlts;
this.hasSemanticContext = old.hasSemanticContext;
this.dipsIntoOuterContext = old.dipsIntoOuterContext;
}
}
public constructor(fullCtx: boolean = true) {
this.fullCtx = fullCtx;
}

public static duplicate(set: ATNConfigSet): ATNConfigSet {
const result = new ATNConfigSet(true);

result.addAll(set.configs);
result.uniqueAlt = set.uniqueAlt;
result.conflictingAlts = set.conflictingAlts;
result.hasSemanticContext = set.hasSemanticContext;
result.dipsIntoOuterContext = set.dipsIntoOuterContext;

return result;
}

public [Symbol.iterator](): IterableIterator<ATNConfig> {
Expand All @@ -137,7 +133,7 @@ export class ATNConfigSet {
throw new Error("This set is readonly");
}

if (!this.firstStopState && (config.state.constructor as typeof ATNState).stateType === ATNState.RULE_STOP) {
if (!this.firstStopState && config.state.stateType === ATNState.RULE_STOP) {

Check failure on line 136 in src/atn/ATNConfigSet.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 136 in src/atn/ATNConfigSet.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
this.firstStopState = config;
}

Expand Down Expand Up @@ -189,14 +185,8 @@ export class ATNConfigSet {
}

public getPredicates(): SemanticContext[] {
const preds = [];
for (const config of this.configs) {
if (config.semanticContext !== SemanticContext.NONE) {
preds.push(config.semanticContext);
}
}

return preds;
return this.configs.filter((config) => { return config.semanticContext !== SemanticContext.NONE; })
.map((config) => { return config.semanticContext; });
}

public getStates(): HashSet<ATNState> {
Expand Down
8 changes: 4 additions & 4 deletions src/atn/ATNSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export class ATNSerializer {
continue;
}

const stateType = (s.constructor as typeof ATNState).stateType;
const stateType = s.stateType;

Check failure on line 228 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 228 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
if (s instanceof DecisionState && s.nonGreedy) {
this.nonGreedyStates.push(s.stateNumber);
}
Expand All @@ -238,15 +238,15 @@ export class ATNSerializer {

this.data.push(s.ruleIndex);

if ((s.constructor as typeof ATNState).stateType === ATNState.LOOP_END) {
if (s.stateType === ATNState.LOOP_END) {

Check failure on line 241 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 241 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
this.data.push((s as LoopEndState).loopBackState!.stateNumber);
} else {
if (s instanceof BlockStartState) {
this.data.push(s.endState!.stateNumber);
}
}

if ((s.constructor as typeof ATNState).stateType !== ATNState.RULE_STOP) {
if (s.stateType !== ATNState.RULE_STOP) {

Check failure on line 249 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 249 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
// the deserializer can trivially derive these edges, so there's no need to serialize them
edgeCount += s.transitions.length;
}
Expand All @@ -273,7 +273,7 @@ export class ATNSerializer {
continue;
}

if ((s.constructor as typeof ATNState).stateType === ATNState.RULE_STOP) {
if (s.stateType === ATNState.RULE_STOP) {

Check failure on line 276 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?

Check failure on line 276 in src/atn/ATNSerializer.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

Property 'stateType' does not exist on type 'ATNState'. Did you mean to access the static member 'ATNState.stateType' instead?
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion src/atn/BasicBlockStartState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import { ATNState } from "./ATNState.js";
import { BlockStartState } from "./BlockStartState.js";

export class BasicBlockStartState extends BlockStartState {
public static override readonly stateType = ATNState.BLOCK_START;
public override get stateType(): number { return ATNState.BLOCK_START; }

Check failure on line 11 in src/atn/BasicBlockStartState.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

This member cannot have an 'override' modifier because it is not declared in the base class 'BlockStartState'.

Check failure on line 11 in src/atn/BasicBlockStartState.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

This member cannot have an 'override' modifier because it is not declared in the base class 'BlockStartState'.
}
2 changes: 1 addition & 1 deletion src/atn/BasicState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
import { ATNState } from "./ATNState.js";

export class BasicState extends ATNState {
public static override readonly stateType = ATNState.BASIC;
public override get stateType(): number { return ATNState.BASIC; }

Check failure on line 10 in src/atn/BasicState.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

This member cannot have an 'override' modifier because it is not declared in the base class 'ATNState'.

Check failure on line 10 in src/atn/BasicState.ts

View workflow job for this annotation

GitHub Actions / build (21.x)

This member cannot have an 'override' modifier because it is not declared in the base class 'ATNState'.
}
2 changes: 1 addition & 1 deletion src/atn/BlockEndState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { BlockStartState } from "./BlockStartState.js";
* Terminal node of a simple `(a|b|c)` block.
*/
export class BlockEndState extends ATNState {
public static override readonly stateType = ATNState.BLOCK_END;
public override get stateType(): number { return ATNState.BLOCK_END; }

public startState?: BlockStartState;
}
2 changes: 1 addition & 1 deletion src/atn/LL1Analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class LL1Analyzer {
return;
}
}
if ((s.constructor as typeof ATNState).stateType === ATNState.RULE_STOP) {
if (s.stateType === ATNState.RULE_STOP) {
if (!ctx) {
look.addOne(Token.EPSILON);

Expand Down
2 changes: 1 addition & 1 deletion src/atn/LexerATNSimulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ export class LexerATNSimulator extends ATNSimulator {
private closure(input: CharStream, config: LexerATNConfig, configs: ATNConfigSet,
currentAltReachedAcceptState: boolean, speculative: boolean, treatEofAsEpsilon: boolean): boolean {
let cfg = null;
if ((config.state.constructor as typeof ATNState).stateType === ATNState.RULE_STOP) {
if (config.state.stateType === ATNState.RULE_STOP) {
if (!config.context || config.context.hasEmptyPath()) {
if (!config.context || config.context.isEmpty()) {
configs.add(config);
Expand Down
2 changes: 1 addition & 1 deletion src/atn/LoopEndState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ATNState } from "./ATNState.js";
* Mark the end of a * or + loop
*/
export class LoopEndState extends ATNState {
public static override readonly stateType = ATNState.LOOP_END;
public override get stateType(): number { return ATNState.LOOP_END; }

public loopBackState?: ATNState;
}
2 changes: 1 addition & 1 deletion src/atn/OrderedATNConfigSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { OrderedHashSet } from "../misc/OrderedHashSet.js";

export class OrderedATNConfigSet extends ATNConfigSet {
public constructor() {
super();
super(true);
this.configLookup = new OrderedHashSet();
}
}
16 changes: 8 additions & 8 deletions src/atn/ParserATNSimulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,19 +335,19 @@ export class ParserATNSimulator extends ATNSimulator {
}

const fullCtx = false;
let s0_closure = this.computeStartState(dfa.atnStartState!, ParserRuleContext.empty, fullCtx);
let startState = this.computeStartState(dfa.atnStartState!, ParserRuleContext.empty, fullCtx);

if (dfa.isPrecedenceDfa) {
// If this is a precedence DFA, we use applyPrecedenceFilter
// to convert the computed start state to a precedence start
// state. We then use DFA.setPrecedenceStartState to set the
// appropriate start state for the precedence level rather
// than simply setting DFA.s0.
s0_closure = this.applyPrecedenceFilter(s0_closure);
s0 = this.addDFAState(dfa, DFAState.fromConfigs(s0_closure));
startState = this.applyPrecedenceFilter(startState);
s0 = this.addDFAState(dfa, DFAState.fromConfigs(startState));
dfa.setPrecedenceStartState(this.parser.getPrecedence(), s0);
} else {
s0 = this.addDFAState(dfa, DFAState.fromConfigs(s0_closure));
s0 = this.addDFAState(dfa, DFAState.fromConfigs(startState));
dfa.s0 = s0;
}
}
Expand Down Expand Up @@ -1274,7 +1274,7 @@ export class ParserATNSimulator extends ATNSimulator {
const c = this.getEpsilonTarget(config, t, continueCollecting, depth === 0, fullCtx, treatEofAsEpsilon);
if (c) {
let newDepth = depth;
if ((config.state.constructor as typeof ATNState).stateType === ATNState.RULE_STOP) {
if (config.state.stateType === ATNState.RULE_STOP) {
// target fell off end of rule; mark resulting c as having dipped into outer context
// We can't get here if incoming config was rule stop and we had context
// track how far we dip into outer context. Might
Expand Down Expand Up @@ -1322,7 +1322,7 @@ export class ParserATNSimulator extends ATNSimulator {
// the context has an empty stack case. If so, it would mean
// global FOLLOW so we can't perform optimization
// Are we the special loop entry/exit state? or SLL wildcard
if ((p.constructor as typeof ATNState).stateType !== ATNState.STAR_LOOP_ENTRY || !config.context) {
if (p.stateType !== ATNState.STAR_LOOP_ENTRY || !config.context) {
return false;
}

Expand Down Expand Up @@ -1356,7 +1356,7 @@ export class ParserATNSimulator extends ATNSimulator {

// Look for prefix op case like 'not expr', (' type ')' expr
const returnStateTarget = returnState.transitions[0].target;
if ((returnState.constructor as typeof ATNState).stateType === ATNState.BLOCK_END
if (returnState.stateType === ATNState.BLOCK_END
&& returnStateTarget === p) {
continue;
}
Expand All @@ -1376,7 +1376,7 @@ export class ParserATNSimulator extends ATNSimulator {

// Look for complex prefix 'between expr and expr' case where 2nd expr's
// return state points at block end state of (...)* internal block
if ((returnStateTarget.constructor as typeof ATNState).stateType === ATNState.BLOCK_END
if (returnStateTarget.stateType === ATNState.BLOCK_END
&& returnStateTarget.transitions.length === 1
&& returnStateTarget.transitions[0].isEpsilon && returnStateTarget.transitions[0].target === p) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/atn/PlusBlockStartState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { PlusLoopbackState } from "./PlusLoopbackState.js";
* real decision-making note for `A+`
*/
export class PlusBlockStartState extends BlockStartState {
public static override readonly stateType = ATNState.PLUS_BLOCK_START;
public override get stateType(): number { return ATNState.PLUS_BLOCK_START; }

public loopBackState: PlusLoopbackState;
}
2 changes: 1 addition & 1 deletion src/atn/PlusLoopbackState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ import { DecisionState } from "./DecisionState.js";
* one to the loop back to start of the block and one to exit.
*/
export class PlusLoopbackState extends DecisionState {
public static override readonly stateType = ATNState.PLUS_LOOP_BACK;
public override get stateType(): number { return ATNState.PLUS_LOOP_BACK; }
}
2 changes: 1 addition & 1 deletion src/atn/RuleStartState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ATNState } from "./ATNState.js";
import { RuleStopState } from "./RuleStopState.js";

export class RuleStartState extends ATNState {
public static override readonly stateType = ATNState.RULE_START;
public override get stateType(): number { return ATNState.RULE_START; }

public stopState?: RuleStopState;
public isLeftRecursiveRule: boolean = false;
Expand Down
2 changes: 1 addition & 1 deletion src/atn/RuleStopState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ import { ATNState } from "./ATNState.js";
* error handling
*/
export class RuleStopState extends ATNState {
public static override readonly stateType = ATNState.RULE_STOP;
public override get stateType(): number { return ATNState.RULE_STOP; }

}
2 changes: 1 addition & 1 deletion src/atn/StarBlockStartState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ import { BlockStartState } from "./BlockStartState.js";
* The block that begins a closure loop
*/
export class StarBlockStartState extends BlockStartState {
public static override readonly stateType = ATNState.STAR_BLOCK_START;
public override get stateType(): number { return ATNState.STAR_BLOCK_START; }
}
2 changes: 1 addition & 1 deletion src/atn/StarLoopEntryState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DecisionState } from "./DecisionState.js";
import { StarLoopbackState } from "./StarLoopbackState.js";

export class StarLoopEntryState extends DecisionState {
public static override readonly stateType = ATNState.STAR_LOOP_ENTRY;
public override get stateType(): number { return ATNState.STAR_LOOP_ENTRY; }

// This is always set during ATN deserialization
public loopBackState!: StarLoopbackState;
Expand Down
2 changes: 1 addition & 1 deletion src/atn/StarLoopbackState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
import { ATNState } from "./ATNState.js";

export class StarLoopbackState extends ATNState {
public static override readonly stateType = ATNState.STAR_LOOP_BACK;
public override get stateType(): number { return ATNState.STAR_LOOP_BACK; }
}
2 changes: 1 addition & 1 deletion src/atn/TokensStartState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ import { DecisionState } from "./DecisionState.js";
* The Tokens rule start state linking to each lexer rule start state
*/
export class TokensStartState extends DecisionState {
public static override readonly stateType = ATNState.TOKEN_START;
public override get stateType(): number { return ATNState.TOKEN_START; }
}
Loading

0 comments on commit 78cfeb6

Please sign in to comment.