UNPKG

@bacons/xcode

Version:

pbxproj parser

120 lines 4.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = exports.BaseVisitor = exports.PbxprojParser = exports.CommentCstParser = void 0; const chevrotain_1 = require("./chevrotain"); const identifiers_1 = require("./identifiers"); const lexer_1 = require("./lexer"); class CommentCstParser extends chevrotain_1.CstParser { RULE(name, implementation, config) { return super.RULE(name, () => { const start = this.LA(1).startOffset; const ruleResult = implementation(); const end = this.LA(0); if (ruleResult !== undefined) { // @ts-ignore ruleResult.position = { start: start, end: end, }; } return ruleResult; }, config); } LA(howMuch) { // Skip Comments during regular parsing as we wish to auto-magically insert them // into our CST while ((0, chevrotain_1.tokenMatcher)(super.LA(howMuch), identifiers_1.Comment)) { // @ts-expect-error super.consumeToken(); } return super.LA(howMuch); } cstPostTerminal(key, consumedToken) { // @ts-expect-error super.cstPostTerminal(key, consumedToken); let lookBehindIdx = -1; let prevToken = super.LA(lookBehindIdx); // After every Token (terminal) is successfully consumed // We will add all the comment that appeared before it to the CST (Parse Tree) while ((0, chevrotain_1.tokenMatcher)(prevToken, identifiers_1.Comment)) { // @ts-expect-error super.cstPostTerminal(identifiers_1.Comment.name, prevToken); lookBehindIdx--; prevToken = super.LA(lookBehindIdx); } } } exports.CommentCstParser = CommentCstParser; class PbxprojParser extends CommentCstParser { constructor() { super(lexer_1.tokens, { recoveryEnabled: false, }); this.head = this.RULE("head", () => { this.OR([ { ALT: () => this.SUBRULE(this.array) }, { ALT: () => this.SUBRULE(this.object) }, ]); }); this.array = this.RULE("array", () => { this.CONSUME(identifiers_1.ArrayStart); this.OPTION(() => { this.MANY(() => { this.SUBRULE(this.value); this.OPTION2(() => this.CONSUME(identifiers_1.Separator)); }); }); this.CONSUME(identifiers_1.ArrayEnd); }); this.object = this.RULE("object", () => { this.CONSUME(identifiers_1.ObjectStart); this.OPTION(() => { this.MANY(() => { this.SUBRULE(this.objectItem); }); }); this.CONSUME(identifiers_1.ObjectEnd); }); this.objectItem = this.RULE("objectItem", () => { this.SUBRULE(this.identifier); this.CONSUME(identifiers_1.Colon); this.SUBRULE(this.value); this.CONSUME(identifiers_1.Terminator); }); this.identifier = this.RULE("identifier", () => { this.OR([ { ALT: () => this.CONSUME(identifiers_1.QuotedString) }, { ALT: () => this.CONSUME(identifiers_1.StringLiteral) }, ]); }); this.value = this.RULE("value", () => { this.OR([ { ALT: () => this.SUBRULE(this.object) }, { ALT: () => this.SUBRULE(this.array) }, { ALT: () => this.CONSUME(identifiers_1.DataLiteral) }, { ALT: () => this.SUBRULE(this.identifier) }, ]); }); // very important to call this after all the rules have been setup. // otherwise the parser may not work correctly as it will lack information // derived from the self analysis. this.performSelfAnalysis(); } } exports.PbxprojParser = PbxprojParser; const parser = new PbxprojParser(); exports.BaseVisitor = parser.getBaseCstVisitorConstructorWithDefaults(); function parse(text) { const lexingResult = lexer_1.lexer.tokenize(text); if (lexingResult.errors.length) { throw new Error(`Parsing errors: ${lexingResult.errors[0].message}`); } parser.input = lexingResult.tokens; const parsingResult = parser.head(); if (parser.errors.length) { throw new Error(`Parsing errors: ${parser.errors[0].message}`); } return parsingResult; } exports.parse = parse; //# sourceMappingURL=parser.js.map