You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

78 lines
2.0 KiB

/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import map from "lodash-es/map.js"
import { ATNState, DecisionState } from "./atn.js"
export interface DFA {
start?: DFAState
states: Record<string, DFAState>
decision: number
atnStartState: DecisionState
}
export interface DFAState {
configs: ATNConfigSet
edges: Record<number, DFAState>
isAcceptState: boolean
prediction: number
}
export const DFA_ERROR = {} as DFAState
export interface ATNConfig {
state: ATNState
alt: number
stack: ATNState[]
}
export class ATNConfigSet {
private map: Record<string, number> = {}
private configs: ATNConfig[] = []
uniqueAlt: number | undefined
get size(): number {
return this.configs.length
}
finalize(): void {
// Empties the map to free up memory
this.map = {}
}
add(config: ATNConfig): void {
const key = getATNConfigKey(config)
// Only add configs which don't exist in our map already
// While this does not influence the actual algorithm, adding them anyway would massively increase memory consumption
if (!(key in this.map)) {
this.map[key] = this.configs.length
this.configs.push(config)
}
}
get elements(): readonly ATNConfig[] {
return this.configs
}
get alts(): number[] {
return map(this.configs, (e) => e.alt)
}
get key(): string {
let value = ""
for (const k in this.map) {
value += k + ":"
}
return value
}
}
export function getATNConfigKey(config: ATNConfig, alt = true) {
return `${alt ? `a${config.alt}` : ""}s${
config.state.stateNumber
}:${config.stack.map((e) => e.stateNumber.toString()).join("_")}`
}