Created
March 29, 2019 09:10
-
-
Save kristianmandrup/afbd8382e7a172aa8945b6023e3b3e8e to your computer and use it in GitHub Desktop.
Chevrotain CST with location info
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface ILocation { | |
startOffset: number | |
startLine: number | |
} | |
export interface CstNode { | |
readonly name: string | |
readonly children: CstChildrenDictionary | |
readonly recoveredNode?: boolean | |
/** | |
* Only relevant for [in-lined](http://sap.github.io/chevrotain/docs/guide/concrete_syntax_tree.html#in-lined-rules) rules. | |
* the fullName will **also** include the name of the top level rule containing this nested rule. | |
*/ | |
readonly fullName?: string | |
location?: ILocation | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
CstNode, | |
CstElement, | |
LocationInfo, | |
IParserConfig, | |
ILocation | |
} from "../../../../api" | |
import { isUndefined } from "../../../utils/utils" | |
import { MixedInParser } from "./parser_traits" | |
export class LocationInfoDecorator { | |
initLocationInfoDecorator(this: MixedInParser, config: IParserConfig) { | |
if (!config.locationInfo || config.locationInfo === LocationInfo.NONE) { | |
return | |
} | |
// initialize | |
} | |
// ... smart compute | |
// using memoized (cached) locations to achieve linear visits O(n) and thus good performance | |
public computeLocationInfo( | |
this: MixedInParser, | |
startRuleName: string | |
): void { | |
console.log("computeLocationInfo") | |
let startRuleGast = this.gastProductionsCache.get(startRuleName) | |
if (isUndefined(startRuleGast)) { | |
throw Error( | |
`Rule ->${startRuleName}<- does not exist in this grammar.` | |
) | |
} | |
// const elements: CstElement[] = this.getChildrenOf(startRuleGast) | |
// this.decorateElements(elements) | |
} | |
getChildrenOf(ruleGast): CstElement[] { | |
return [] | |
} | |
decorateElements(elements: CstElement[]) { | |
elements.map(element => this.decorateElement(element)) | |
} | |
decorateElement(element: CstElement) { | |
if (!element["children"]) { | |
return | |
} | |
this.decorateNode(element as CstNode) | |
} | |
initialLocation: ILocation = { | |
startOffset: 999999, | |
startLine: 9999 | |
} | |
decorateNode(node: CstNode) { | |
const location = this.startLocationsFor(node) | |
// node.location = location || {} | |
return node | |
} | |
startLocationsFor( | |
node: CstNode, | |
location: ILocation = this.initialLocation | |
): ILocation { | |
return { | |
startOffset: 12, | |
startLine: 0 | |
} | |
// return node.location | |
// ? node.location | |
// : this.findStartLocationsFor(node, location) | |
} | |
findStartLocationsFor(node: CstNode, location: ILocation) { | |
// return node.children.reduce(this.minLocation, location) | |
} | |
minLocation(location, node) { | |
let { startOffset, startLine } = { startOffset: 32, startLine: 1 } // this.startLocationsFor(node, location) | |
// let startoffSet = this.startOffSetFor(node) | |
// let startLine = this.startLineFor(node) | |
startOffset = Math.min(startOffset, location.startOffset) | |
startLine = Math.min(startLine, location.startLine) | |
return { | |
startOffset, | |
startLine | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment