You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.3 KiB
147 lines
3.3 KiB
#ifndef INC_InputBuffer_h__
|
|
#define INC_InputBuffer_h__
|
|
|
|
/* ANTLR Translator Generator
|
|
* Project led by Terence Parr at http://www.jGuru.com
|
|
* Software rights: http://www.antlr.org/license.html
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include <antlr/config.h>
|
|
#include <antlr/CircularQueue.h>
|
|
#include <string>
|
|
|
|
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
|
|
namespace antlr {
|
|
#endif
|
|
|
|
/** A Stream of characters fed to the lexer from a InputStream that can
|
|
* be rewound via mark()/rewind() methods.
|
|
* <p>
|
|
* A dynamic array is used to buffer up all the input characters. Normally,
|
|
* "k" characters are stored in the buffer. More characters may be stored during
|
|
* guess mode (testing syntactic predicate), or when LT(i>k) is referenced.
|
|
* Consumption of characters is deferred. In other words, reading the next
|
|
* character is not done by conume(), but deferred until needed by LA or LT.
|
|
* <p>
|
|
*
|
|
* @see antlr.CharQueue
|
|
*/
|
|
class ANTLR_API InputBuffer {
|
|
public:
|
|
/** Create a character buffer */
|
|
InputBuffer()
|
|
: nMarkers(0)
|
|
, markerOffset(0)
|
|
, numToConsume(0)
|
|
{
|
|
}
|
|
|
|
virtual ~InputBuffer()
|
|
{
|
|
}
|
|
|
|
/// Reset the input buffer to empty state
|
|
virtual inline void reset( void )
|
|
{
|
|
nMarkers = 0;
|
|
markerOffset = 0;
|
|
numToConsume = 0;
|
|
queue.clear();
|
|
}
|
|
|
|
/** This method updates the state of the input buffer so that
|
|
* the text matched since the most recent mark() is no longer
|
|
* held by the buffer. So, you either do a mark/rewind for
|
|
* failed predicate or mark/commit to keep on parsing without
|
|
* rewinding the input.
|
|
*/
|
|
inline void commit( void )
|
|
{
|
|
nMarkers--;
|
|
}
|
|
|
|
/** Mark another character for deferred consumption */
|
|
virtual inline void consume()
|
|
{
|
|
numToConsume++;
|
|
}
|
|
|
|
/** Ensure that the character buffer is sufficiently full */
|
|
virtual void fill(unsigned int amount);
|
|
|
|
/** Override this in subclasses to get the next character */
|
|
virtual int getChar()=0;
|
|
|
|
/** Get a lookahead character */
|
|
virtual inline int LA(unsigned int i)
|
|
{
|
|
fill(i);
|
|
return queue.elementAt(markerOffset + i - 1);
|
|
}
|
|
|
|
/** Return an integer marker that can be used to rewind the buffer to
|
|
* its current state.
|
|
*/
|
|
virtual unsigned int mark();
|
|
/// Are there any marks active in the InputBuffer
|
|
virtual inline bool isMarked() const
|
|
{
|
|
return (nMarkers != 0);
|
|
}
|
|
/** Rewind the character buffer to a marker.
|
|
* @param mark Marker returned previously from mark()
|
|
*/
|
|
virtual void rewind(unsigned int mark);
|
|
|
|
/** Get the number of non-consumed characters
|
|
*/
|
|
virtual unsigned int entries() const;
|
|
|
|
ANTLR_USE_NAMESPACE(std)string getLAChars() const;
|
|
|
|
ANTLR_USE_NAMESPACE(std)string getMarkedChars() const;
|
|
|
|
protected:
|
|
// char source
|
|
// leave to subclasses
|
|
|
|
// Number of active markers
|
|
unsigned int nMarkers; // = 0;
|
|
|
|
// Additional offset used when markers are active
|
|
unsigned int markerOffset; // = 0;
|
|
|
|
// Number of calls to consume() since last LA() or LT() call
|
|
unsigned int numToConsume; // = 0;
|
|
|
|
// Circular queue
|
|
CircularQueue<int> queue;
|
|
|
|
/** Sync up deferred consumption */
|
|
void syncConsume();
|
|
|
|
private:
|
|
InputBuffer(const InputBuffer& other);
|
|
InputBuffer& operator=(const InputBuffer& other);
|
|
};
|
|
|
|
/** Sync up deferred consumption */
|
|
inline void InputBuffer::syncConsume() {
|
|
if (numToConsume > 0)
|
|
{
|
|
if (nMarkers > 0)
|
|
markerOffset += numToConsume;
|
|
else
|
|
queue.removeItems( numToConsume );
|
|
numToConsume = 0;
|
|
}
|
|
}
|
|
|
|
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
|
|
}
|
|
#endif
|
|
|
|
#endif //INC_InputBuffer_h__
|