Initial commit
This commit is contained in:
commit
b3a51a4115
10336 changed files with 2381973 additions and 0 deletions
270
node_modules/chevrotain/src/parse/parser/traits/looksahead.ts
generated
vendored
Normal file
270
node_modules/chevrotain/src/parse/parser/traits/looksahead.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
import forEach from "lodash/forEach"
|
||||
import has from "lodash/has"
|
||||
import { DEFAULT_PARSER_CONFIG } from "../parser"
|
||||
import {
|
||||
ILookaheadStrategy,
|
||||
IParserConfig,
|
||||
OptionalProductionType
|
||||
} from "@chevrotain/types"
|
||||
import {
|
||||
AT_LEAST_ONE_IDX,
|
||||
AT_LEAST_ONE_SEP_IDX,
|
||||
getKeyForAutomaticLookahead,
|
||||
MANY_IDX,
|
||||
MANY_SEP_IDX,
|
||||
OPTION_IDX,
|
||||
OR_IDX
|
||||
} from "../../grammar/keys"
|
||||
import { MixedInParser } from "./parser_traits"
|
||||
import {
|
||||
Alternation,
|
||||
GAstVisitor,
|
||||
Option,
|
||||
Repetition,
|
||||
RepetitionMandatory,
|
||||
RepetitionMandatoryWithSeparator,
|
||||
RepetitionWithSeparator,
|
||||
Rule
|
||||
} from "@chevrotain/gast"
|
||||
import { getProductionDslName } from "@chevrotain/gast"
|
||||
import { LLkLookaheadStrategy } from "../../grammar/llk_lookahead"
|
||||
|
||||
/**
|
||||
* Trait responsible for the lookahead related utilities and optimizations.
|
||||
*/
|
||||
export class LooksAhead {
|
||||
maxLookahead: number
|
||||
lookAheadFuncsCache: any
|
||||
dynamicTokensEnabled: boolean
|
||||
lookaheadStrategy: ILookaheadStrategy
|
||||
|
||||
initLooksAhead(config: IParserConfig) {
|
||||
this.dynamicTokensEnabled = has(config, "dynamicTokensEnabled")
|
||||
? (config.dynamicTokensEnabled as boolean) // assumes end user provides the correct config value/type
|
||||
: DEFAULT_PARSER_CONFIG.dynamicTokensEnabled
|
||||
|
||||
this.maxLookahead = has(config, "maxLookahead")
|
||||
? (config.maxLookahead as number) // assumes end user provides the correct config value/type
|
||||
: DEFAULT_PARSER_CONFIG.maxLookahead
|
||||
|
||||
this.lookaheadStrategy = has(config, "lookaheadStrategy")
|
||||
? (config.lookaheadStrategy as ILookaheadStrategy) // assumes end user provides the correct config value/type
|
||||
: new LLkLookaheadStrategy({ maxLookahead: this.maxLookahead })
|
||||
|
||||
this.lookAheadFuncsCache = new Map()
|
||||
}
|
||||
|
||||
preComputeLookaheadFunctions(this: MixedInParser, rules: Rule[]): void {
|
||||
forEach(rules, (currRule) => {
|
||||
this.TRACE_INIT(`${currRule.name} Rule Lookahead`, () => {
|
||||
const {
|
||||
alternation,
|
||||
repetition,
|
||||
option,
|
||||
repetitionMandatory,
|
||||
repetitionMandatoryWithSeparator,
|
||||
repetitionWithSeparator
|
||||
} = collectMethods(currRule)
|
||||
|
||||
forEach(alternation, (currProd) => {
|
||||
const prodIdx = currProd.idx === 0 ? "" : currProd.idx
|
||||
this.TRACE_INIT(`${getProductionDslName(currProd)}${prodIdx}`, () => {
|
||||
const laFunc = this.lookaheadStrategy.buildLookaheadForAlternation({
|
||||
prodOccurrence: currProd.idx,
|
||||
rule: currRule,
|
||||
maxLookahead: currProd.maxLookahead || this.maxLookahead,
|
||||
hasPredicates: currProd.hasPredicates,
|
||||
dynamicTokensEnabled: this.dynamicTokensEnabled
|
||||
})
|
||||
|
||||
const key = getKeyForAutomaticLookahead(
|
||||
this.fullRuleNameToShort[currRule.name],
|
||||
OR_IDX,
|
||||
currProd.idx
|
||||
)
|
||||
this.setLaFuncCache(key, laFunc)
|
||||
})
|
||||
})
|
||||
|
||||
forEach(repetition, (currProd) => {
|
||||
this.computeLookaheadFunc(
|
||||
currRule,
|
||||
currProd.idx,
|
||||
MANY_IDX,
|
||||
"Repetition",
|
||||
currProd.maxLookahead,
|
||||
getProductionDslName(currProd)
|
||||
)
|
||||
})
|
||||
|
||||
forEach(option, (currProd) => {
|
||||
this.computeLookaheadFunc(
|
||||
currRule,
|
||||
currProd.idx,
|
||||
OPTION_IDX,
|
||||
"Option",
|
||||
currProd.maxLookahead,
|
||||
getProductionDslName(currProd)
|
||||
)
|
||||
})
|
||||
|
||||
forEach(repetitionMandatory, (currProd) => {
|
||||
this.computeLookaheadFunc(
|
||||
currRule,
|
||||
currProd.idx,
|
||||
AT_LEAST_ONE_IDX,
|
||||
"RepetitionMandatory",
|
||||
currProd.maxLookahead,
|
||||
getProductionDslName(currProd)
|
||||
)
|
||||
})
|
||||
|
||||
forEach(repetitionMandatoryWithSeparator, (currProd) => {
|
||||
this.computeLookaheadFunc(
|
||||
currRule,
|
||||
currProd.idx,
|
||||
AT_LEAST_ONE_SEP_IDX,
|
||||
"RepetitionMandatoryWithSeparator",
|
||||
currProd.maxLookahead,
|
||||
getProductionDslName(currProd)
|
||||
)
|
||||
})
|
||||
|
||||
forEach(repetitionWithSeparator, (currProd) => {
|
||||
this.computeLookaheadFunc(
|
||||
currRule,
|
||||
currProd.idx,
|
||||
MANY_SEP_IDX,
|
||||
"RepetitionWithSeparator",
|
||||
currProd.maxLookahead,
|
||||
getProductionDslName(currProd)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
computeLookaheadFunc(
|
||||
this: MixedInParser,
|
||||
rule: Rule,
|
||||
prodOccurrence: number,
|
||||
prodKey: number,
|
||||
prodType: OptionalProductionType,
|
||||
prodMaxLookahead: number | undefined,
|
||||
dslMethodName: string
|
||||
): void {
|
||||
this.TRACE_INIT(
|
||||
`${dslMethodName}${prodOccurrence === 0 ? "" : prodOccurrence}`,
|
||||
() => {
|
||||
const laFunc = this.lookaheadStrategy.buildLookaheadForOptional({
|
||||
prodOccurrence,
|
||||
rule,
|
||||
maxLookahead: prodMaxLookahead || this.maxLookahead,
|
||||
dynamicTokensEnabled: this.dynamicTokensEnabled,
|
||||
prodType
|
||||
})
|
||||
const key = getKeyForAutomaticLookahead(
|
||||
this.fullRuleNameToShort[rule.name],
|
||||
prodKey,
|
||||
prodOccurrence
|
||||
)
|
||||
this.setLaFuncCache(key, laFunc)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// this actually returns a number, but it is always used as a string (object prop key)
|
||||
getKeyForAutomaticLookahead(
|
||||
this: MixedInParser,
|
||||
dslMethodIdx: number,
|
||||
occurrence: number
|
||||
): number {
|
||||
const currRuleShortName: any = this.getLastExplicitRuleShortName()
|
||||
return getKeyForAutomaticLookahead(
|
||||
currRuleShortName,
|
||||
dslMethodIdx,
|
||||
occurrence
|
||||
)
|
||||
}
|
||||
|
||||
getLaFuncFromCache(this: MixedInParser, key: number): Function {
|
||||
return this.lookAheadFuncsCache.get(key)
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
setLaFuncCache(this: MixedInParser, key: number, value: Function): void {
|
||||
this.lookAheadFuncsCache.set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
class DslMethodsCollectorVisitor extends GAstVisitor {
|
||||
public dslMethods: {
|
||||
option: Option[]
|
||||
alternation: Alternation[]
|
||||
repetition: Repetition[]
|
||||
repetitionWithSeparator: RepetitionWithSeparator[]
|
||||
repetitionMandatory: RepetitionMandatory[]
|
||||
repetitionMandatoryWithSeparator: RepetitionMandatoryWithSeparator[]
|
||||
} = {
|
||||
option: [],
|
||||
alternation: [],
|
||||
repetition: [],
|
||||
repetitionWithSeparator: [],
|
||||
repetitionMandatory: [],
|
||||
repetitionMandatoryWithSeparator: []
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.dslMethods = {
|
||||
option: [],
|
||||
alternation: [],
|
||||
repetition: [],
|
||||
repetitionWithSeparator: [],
|
||||
repetitionMandatory: [],
|
||||
repetitionMandatoryWithSeparator: []
|
||||
}
|
||||
}
|
||||
|
||||
public visitOption(option: Option): void {
|
||||
this.dslMethods.option.push(option)
|
||||
}
|
||||
|
||||
public visitRepetitionWithSeparator(manySep: RepetitionWithSeparator): void {
|
||||
this.dslMethods.repetitionWithSeparator.push(manySep)
|
||||
}
|
||||
|
||||
public visitRepetitionMandatory(atLeastOne: RepetitionMandatory): void {
|
||||
this.dslMethods.repetitionMandatory.push(atLeastOne)
|
||||
}
|
||||
|
||||
public visitRepetitionMandatoryWithSeparator(
|
||||
atLeastOneSep: RepetitionMandatoryWithSeparator
|
||||
): void {
|
||||
this.dslMethods.repetitionMandatoryWithSeparator.push(atLeastOneSep)
|
||||
}
|
||||
|
||||
public visitRepetition(many: Repetition): void {
|
||||
this.dslMethods.repetition.push(many)
|
||||
}
|
||||
|
||||
public visitAlternation(or: Alternation): void {
|
||||
this.dslMethods.alternation.push(or)
|
||||
}
|
||||
}
|
||||
|
||||
const collectorVisitor = new DslMethodsCollectorVisitor()
|
||||
export function collectMethods(rule: Rule): {
|
||||
option: Option[]
|
||||
alternation: Alternation[]
|
||||
repetition: Repetition[]
|
||||
repetitionWithSeparator: RepetitionWithSeparator[]
|
||||
repetitionMandatory: RepetitionMandatory[]
|
||||
repetitionMandatoryWithSeparator: RepetitionMandatoryWithSeparator[]
|
||||
} {
|
||||
collectorVisitor.reset()
|
||||
rule.accept(collectorVisitor)
|
||||
const dslMethods = collectorVisitor.dslMethods
|
||||
// avoid uncleaned references
|
||||
collectorVisitor.reset()
|
||||
return <any>dslMethods
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue