syntax-cli-prog
Version:
Syntactic analysis toolkit, language agnostic parsers generator.
210 lines (168 loc) • 6.92 kB
JavaScript
'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;