UNPKG

@ayanaware/bentocord

Version:

Bentocord is a Bento plugin designed to rapidly build fully functional Discord Bots.

101 lines 3.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Parser = void 0; const Tokenizer_1 = require("./Tokenizer"); class Parser { constructor(tokens) { this.output = { all: [], options: [], phrases: [] }; this.postion = 0; this.tokens = tokens; } parse() { while (this.postion < this.tokens.length - 1) this.parseNext(); return this.output; } expectToken(tokens, lookahead = 0) { const token = this.tokens[this.postion + lookahead]; if (token == null) return false; return tokens.includes(token.type); } match(tokens, advance = false) { const result = this.expectToken(tokens); if (!result) return false; const token = this.tokens[this.postion]; if (advance) this.postion++; return token; } parseNext() { for (const fn of [this.parseWhitespace.bind(this), this.parseOption.bind(this), this.parsePhrase.bind(this)]) fn(); } parseWhitespace() { // Consume whitespace this.match([Tokenizer_1.TokenType.WHITESPACE], true); } parseOption() { const optionToken = this.match([Tokenizer_1.TokenType.OPTION], true); if (!optionToken) return; const optionKey = optionToken.value.replace(/[:= ]/g, ''); const option = { value: '', key: optionKey, raw: `${optionToken.value}` }; const collector = []; let token = null; // eslint-disable-next-line no-cond-assign while (token = this.match([Tokenizer_1.TokenType.WORD, Tokenizer_1.TokenType.WHITESPACE, Tokenizer_1.TokenType.QUOTE_OPEN, Tokenizer_1.TokenType.QUOTE_CLOSE], true)) { if (typeof token !== 'object') continue; option.raw += token.value; if (token.type === Tokenizer_1.TokenType.WORD) collector.push(token.value); } option.value = collector.join(' '); this.output.all.push(option); this.output.options.push(option); } parsePhrase(returnMode = false) { // handle quotes const quoteOpenToken = this.match([Tokenizer_1.TokenType.QUOTE_OPEN], true); if (quoteOpenToken) { // this is the start of a quoted phrase let raw = quoteOpenToken.value; const collector = []; let token = null; // eslint-disable-next-line no-cond-assign while (token = this.match([Tokenizer_1.TokenType.WORD, Tokenizer_1.TokenType.WHITESPACE], true)) { if (typeof token !== 'object') continue; // make typescript happy raw = `${raw}${token.value}`; if (token.type === Tokenizer_1.TokenType.WORD) collector.push(token.value); } let quoteCloseToken = this.match([Tokenizer_1.TokenType.QUOTE_CLOSE], true); if (!quoteCloseToken) { // Quoted Phrase was not closed :AWAUGERYY: // Just close it ourself quoteCloseToken = { type: Tokenizer_1.TokenType.QUOTE_CLOSE, value: '"' }; } raw = `${raw}${quoteCloseToken.value}`; const quotePhrase = { value: collector.join(' '), raw }; if (returnMode) return quotePhrase; this.output.all.push(quotePhrase); this.output.phrases.push(quotePhrase); return; } // word const wordToken = this.match([Tokenizer_1.TokenType.WORD], true); if (!wordToken) return; const phrase = { value: wordToken.value, raw: wordToken.value }; if (returnMode) return phrase; this.output.all.push(phrase); this.output.phrases.push(phrase); } } exports.Parser = Parser; //# sourceMappingURL=Parser.js.map