All Downloads are FREE. Search and download functionalities are using the official Maven repository.

JavaScript.src.antlr4.atn.LexerActionExecutor.js Maven / Gradle / Ivy

There is a newer version: 4.13.2
Show newest version
//
// [The "BSD license"]
//  Copyright (c) 2013 Terence Parr
//  Copyright (c) 2013 Sam Harwell
//  Copyright (c) 2014 Eric Vergnaud
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions
//  are met:
//
//  1. Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in the
//     documentation and/or other materials provided with the distribution.
//  3. The name of the author may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
//  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
//  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
//  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
///

// 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.

var LexerIndexedCustomAction = require('./LexerAction').LexerIndexedCustomAction; function LexerActionExecutor(lexerActions) { this.lexerActions = lexerActions === null ? [] : lexerActions; // Caches the result of {@link //hashCode} since the hash code is an element // of the performance-critical {@link LexerATNConfig//hashCode} operation. this._hashString = lexerActions.toString(); // "".join([str(la) for la in // lexerActions])) return this; } // Creates a {@link LexerActionExecutor} which executes the actions for // the input {@code lexerActionExecutor} followed by a specified // {@code lexerAction}. // // @param lexerActionExecutor The executor for actions already traversed by // the lexer while matching a token within a particular // {@link LexerATNConfig}. If this is {@code null}, the method behaves as // though it were an empty executor. // @param lexerAction The lexer action to execute after the actions // specified in {@code lexerActionExecutor}. // // @return A {@link LexerActionExecutor} for executing the combine actions // of {@code lexerActionExecutor} and {@code lexerAction}. LexerActionExecutor.append = function(lexerActionExecutor, lexerAction) { if (lexerActionExecutor === null) { return new LexerActionExecutor([ lexerAction ]); } var lexerActions = lexerActionExecutor.lexerActions.concat([ 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 {@code 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 {@code this}.

// // @param offset The current offset to assign to all position-dependent // lexer actions which do not already have offsets assigned. // // @return A {@link LexerActionExecutor} which stores input stream offsets // for all position-dependent lexer actions. // / LexerActionExecutor.prototype.fixOffsetBeforeMatch = function(offset) { var updatedLexerActions = null; for (var i = 0; i < this.lexerActions.length; i++) { if (this.lexerActions[i].isPositionDependent && !(this.lexerActions[i] instanceof LexerIndexedCustomAction)) { if (updatedLexerActions === null) { updatedLexerActions = this.lexerActions.concat([]); } updatedLexerActions[i] = new LexerIndexedCustomAction(offset, this.lexerActions[i]); } } if (updatedLexerActions === null) { return this; } else { return new LexerActionExecutor(updatedLexerActions); } }; // 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 // {@code 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 // {@code 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 {@code 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; i < this.lexerActions.length; i++) { var lexerAction = this.lexerActions[i]; if (lexerAction instanceof 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.hashString = function() { return this._hashString; }; LexerActionExecutor.prototype.equals = function(other) { if (this === other) { return true; } else if (!(other instanceof LexerActionExecutor)) { return false; } else if (this._hashString != other._hashString) { return false; } else if (this.lexerActions.length != other.lexerActions.length) { return false; } else { var numActions = this.lexerActions.length for (var idx = 0; idx < numActions; ++idx) { if (!this.lexerActions[idx].equals(other.lexerActions[idx])) { return false; } } return true; } }; exports.LexerActionExecutor = LexerActionExecutor;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy