bitmark-grammar
Version:
207 lines (206 loc) • 9.36 kB
JavaScript
;
/*!
* Copyright 2016 The ANTLR Project. All rights reserved.
* Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information.
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
exports.__esModule = true;
exports.LexerActionExecutor = void 0;
// ConvertTo-TS run at 2016-10-04T11:26:28.8810453-07:00
var ArrayEqualityComparator_1 = require("../misc/ArrayEqualityComparator");
var LexerIndexedCustomAction_1 = require("./LexerIndexedCustomAction");
var MurmurHash_1 = require("../misc/MurmurHash");
var Decorators_1 = require("../Decorators");
/**
* Represents an executor for a sequence of lexer actions which traversed during
* the matching operation of a lexer rule (token).
*
* The executor tracks position information for position-dependent lexer actions
* efficiently, ensuring that actions appearing only at the end of the rule do
* not cause bloating of the {@link DFA} created for the lexer.
*
* @author Sam Harwell
* @since 4.2
*/
var LexerActionExecutor = /** @class */ (function () {
/**
* Constructs an executor for a sequence of {@link LexerAction} actions.
* @param lexerActions The lexer actions to execute.
*/
function LexerActionExecutor(lexerActions) {
this._lexerActions = lexerActions;
var hash = MurmurHash_1.MurmurHash.initialize();
for (var _i = 0, lexerActions_1 = lexerActions; _i < lexerActions_1.length; _i++) {
var lexerAction = lexerActions_1[_i];
hash = MurmurHash_1.MurmurHash.update(hash, lexerAction);
}
this.cachedHashCode = MurmurHash_1.MurmurHash.finish(hash, lexerActions.length);
}
/**
* Creates a {@link LexerActionExecutor} which executes the actions for
* the input `lexerActionExecutor` followed by a specified
* `lexerAction`.
*
* @param lexerActionExecutor The executor for actions already traversed by
* the lexer while matching a token within a particular
* {@link ATNConfig}. If this is `undefined`, the method behaves as though
* it were an empty executor.
* @param lexerAction The lexer action to execute after the actions
* specified in `lexerActionExecutor`.
*
* @returns A {@link LexerActionExecutor} for executing the combine actions
* of `lexerActionExecutor` and `lexerAction`.
*/
LexerActionExecutor.append = function (lexerActionExecutor, lexerAction) {
if (!lexerActionExecutor) {
return new LexerActionExecutor([lexerAction]);
}
var lexerActions = lexerActionExecutor._lexerActions.slice(0);
lexerActions.push(lexerAction);
return new LexerActionExecutor(lexerActions);
};
/**
* Creates a {@link LexerActionExecutor} which encodes the current offset
* for position-dependent lexer actions.
*
* Normally, when the executor encounters lexer actions where
* {@link LexerAction#isPositionDependent} returns `true`, it calls
* {@link IntStream#seek} on the input {@link CharStream} to set the input
* position to the *end* of the current token. This behavior provides
* for efficient DFA representation of lexer actions which appear at the end
* of a lexer rule, even when the lexer rule matches a variable number of
* characters.
*
* Prior to traversing a match transition in the ATN, the current offset
* from the token start index is assigned to all position-dependent lexer
* actions which have not already been assigned a fixed offset. By storing
* the offsets relative to the token start index, the DFA representation of
* lexer actions which appear in the middle of tokens remains efficient due
* to sharing among tokens of the same length, regardless of their absolute
* position in the input stream.
*
* If the current executor already has offsets assigned to all
* position-dependent lexer actions, the method returns `this`.
*
* @param offset The current offset to assign to all position-dependent
* lexer actions which do not already have offsets assigned.
*
* @returns A {@link LexerActionExecutor} which stores input stream offsets
* for all position-dependent lexer actions.
*/
LexerActionExecutor.prototype.fixOffsetBeforeMatch = function (offset) {
var updatedLexerActions;
for (var i = 0; i < this._lexerActions.length; i++) {
if (this._lexerActions[i].isPositionDependent && !(this._lexerActions[i] instanceof LexerIndexedCustomAction_1.LexerIndexedCustomAction)) {
if (!updatedLexerActions) {
updatedLexerActions = this._lexerActions.slice(0);
}
updatedLexerActions[i] = new LexerIndexedCustomAction_1.LexerIndexedCustomAction(offset, this._lexerActions[i]);
}
}
if (!updatedLexerActions) {
return this;
}
return new LexerActionExecutor(updatedLexerActions);
};
Object.defineProperty(LexerActionExecutor.prototype, "lexerActions", {
/**
* Gets the lexer actions to be executed by this executor.
* @returns The lexer actions to be executed by this executor.
*/
get: function () {
return this._lexerActions;
},
enumerable: false,
configurable: true
});
/**
* Execute the actions encapsulated by this executor within the context of a
* particular {@link Lexer}.
*
* This method calls {@link IntStream#seek} to set the position of the
* `input` {@link CharStream} prior to calling
* {@link LexerAction#execute} on a position-dependent action. Before the
* method returns, the input position will be restored to the same position
* it was in when the method was invoked.
*
* @param lexer The lexer instance.
* @param input The input stream which is the source for the current token.
* When this method is called, the current {@link IntStream#index} for
* `input` should be the start of the following token, i.e. 1
* character past the end of the current token.
* @param startIndex The token start index. This value may be passed to
* {@link IntStream#seek} to set the `input` position to the beginning
* of the token.
*/
LexerActionExecutor.prototype.execute = function (lexer, input, startIndex) {
var requiresSeek = false;
var stopIndex = input.index;
try {
for (var _i = 0, _a = this._lexerActions; _i < _a.length; _i++) {
var lexerAction = _a[_i];
if (lexerAction instanceof LexerIndexedCustomAction_1.LexerIndexedCustomAction) {
var offset = lexerAction.offset;
input.seek(startIndex + offset);
lexerAction = lexerAction.action;
requiresSeek = (startIndex + offset) !== stopIndex;
}
else if (lexerAction.isPositionDependent) {
input.seek(stopIndex);
requiresSeek = false;
}
lexerAction.execute(lexer);
}
}
finally {
if (requiresSeek) {
input.seek(stopIndex);
}
}
};
LexerActionExecutor.prototype.hashCode = function () {
return this.cachedHashCode;
};
LexerActionExecutor.prototype.equals = function (obj) {
if (obj === this) {
return true;
}
else if (!(obj instanceof LexerActionExecutor)) {
return false;
}
return this.cachedHashCode === obj.cachedHashCode
&& ArrayEqualityComparator_1.ArrayEqualityComparator.INSTANCE.equals(this._lexerActions, obj._lexerActions);
};
__decorate([
Decorators_1.NotNull
], LexerActionExecutor.prototype, "_lexerActions");
__decorate([
Decorators_1.NotNull
], LexerActionExecutor.prototype, "lexerActions");
__decorate([
__param(0, Decorators_1.NotNull)
], LexerActionExecutor.prototype, "execute");
__decorate([
Decorators_1.Override
], LexerActionExecutor.prototype, "hashCode");
__decorate([
Decorators_1.Override
], LexerActionExecutor.prototype, "equals");
__decorate([
Decorators_1.NotNull,
__param(1, Decorators_1.NotNull)
], LexerActionExecutor, "append");
LexerActionExecutor = __decorate([
__param(0, Decorators_1.NotNull)
], LexerActionExecutor);
return LexerActionExecutor;
}());
exports.LexerActionExecutor = LexerActionExecutor;