UNPKG

syntax-cli-prog

Version:

Syntactic analysis toolkit, language agnostic parsers generator.

210 lines (168 loc) 6.92 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** * The MIT License (MIT) * Copyright (c) 2015-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com> */ var _specialSymbols = require('../special-symbols'); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Symbols are stored in the registry, and retrieved from it * if the symbol was already created. */ var registry = {}; /** * Class encapsulates operations with one * grammar symbol (terminal or non-terminal) */ var GrammarSymbol = function () { function GrammarSymbol(symbol) { _classCallCheck(this, GrammarSymbol); this._symbol = symbol; } /** * Terminals in our grammar are quoted, * "a", " ", "var", etc. */ _createClass(GrammarSymbol, [{ key: 'isTerminal', value: function isTerminal() { var first = this._symbol[0]; var last = this._symbol[this._symbol.length - 1]; return first === '"' && last === '"' || first === "'" && last === "'"; } /** * Returns original symbol from an extended name. 1X3 => X */ }, { key: 'getOrignialSymbol', value: function getOrignialSymbol() { if (!this._originalSymbol) { this._originalSymbol = this._symbol.replace(/^\d+\|/, '').replace(/\|(?:\d+|\$)$/, ''); } return this._originalSymbol; } /** * Returns start context (in extended LALR 1X3 => 1) */ }, { key: 'getStartContext', value: function getStartContext() { if (!this._startContext) { this._startContext = Number(this._symbol.match(/^(\d+)\|/)[1]); } return this._startContext; } /** * Returns start context (in extended LALR 1X3 => 1) */ }, { key: 'getEndContext', value: function getEndContext() { if (!this._endContext) { this._endContext = Number(this._symbol.match(/\|(\d+)$/)[1]); } return this._endContext; } /** * Returns a symbol from the registry, or creates one. */ }, { key: 'getTerminalValue', /** * Returns raw terminal value (between quotes) */ value: function getTerminalValue() { this._checkTerminal(); return this._symbol.slice(1, this._symbol.length - 1); } /** * Returns a terminal quoted into single or double-quotes, * depending on which quotes it's already wrapped itself. */ }, { key: 'quotedTerminal', value: function quotedTerminal() { this._checkTerminal(); var isSingleQuoted = this._symbol[0] === "'"; var leftQuote = isSingleQuoted ? '"\'' : '\'"'; var rightQuote = isSingleQuoted ? '\'"' : '"\''; return '' + leftQuote + this.getTerminalValue() + rightQuote; } /** * Checks whether a symbol is a non-terminal. */ }, { key: 'isNonTerminal', value: function isNonTerminal() { return !this.isTerminal(); } /** * Checks whether a symbol is Epsilon (instance method). */ }, { key: 'isEpsilon', value: function isEpsilon() { return GrammarSymbol.isEpsilon(this._symbol); } /** * Checks whether a symbol is an end of file (instance method). */ }, { key: 'isEOF', value: function isEOF() { return this._symbol === _specialSymbols.EOF; } /** * Checks whether a symbol is Epsilon (static method). */ }, { key: 'getSymbol', /** * Returns raw symbol. */ value: function getSymbol() { return this._symbol; } /** * Checks whether the symbol equals to the passed one. */ }, { key: 'isSymbol', value: function isSymbol(symbol) { return this.getSymbol() === symbol; } }, { key: '_checkTerminal', value: function _checkTerminal() { if (!this.isTerminal()) { throw new TypeError('Symbol ' + this._symbol + ' is not terminal.'); } } }], [{ key: 'get', value: function get(symbol) { if (!registry.hasOwnProperty(symbol)) { registry[symbol] = new GrammarSymbol(symbol); } return registry[symbol]; } }, { key: 'isEpsilon', value: function isEpsilon(symbol) { return symbol.includes(_specialSymbols.EPSILON); } /** * Checks whether a symbol is EOF (static method). */ }, { key: 'isEOF', value: function isEOF(symbol) { return symbol === _specialSymbols.EOF; } }]); return GrammarSymbol; }(); exports.default = GrammarSymbol;