blob: c8ccbd864c54a5f1c14a90e56c28a68dd1704c5d [file] [log] [blame]
ANTLR_BEGIN_NAMESPACE()
template<class ImplTraits>
Lexer<ImplTraits>::Lexer(ANTLR_UINT32 sizeHint, RecognizerSharedStateType* state)
:Lexer<ImplTraits>::RecognizerType(sizeHint, state)
,m_input(NULL)
{
}
template<class ImplTraits>
Lexer<ImplTraits>::Lexer(ANTLR_UINT32 sizeHint, InputStreamType* input, RecognizerSharedStateType* state)
:Lexer<ImplTraits>::RecognizerType(sizeHint, state)
{
this->setCharStream(input);
}
template<class ImplTraits>
typename Lexer<ImplTraits>::InputStreamType* Lexer<ImplTraits>::get_input() const
{
return m_input;
}
template<class ImplTraits>
typename Lexer<ImplTraits>::IntStreamType* Lexer<ImplTraits>::get_istream() const
{
return m_input;
}
template<class ImplTraits>
typename Lexer<ImplTraits>::RecognizerType* Lexer<ImplTraits>::get_rec()
{
return this;
}
template<class ImplTraits>
typename Lexer<ImplTraits>::TokenSourceType* Lexer<ImplTraits>::get_tokSource()
{
return this;
}
template<class ImplTraits>
void Lexer<ImplTraits>::displayRecognitionError( ANTLR_UINT8** , ExceptionBaseType* ex)
{
StringStreamType err_stream;
// See if there is a 'filename' we can use
//
if( ex->getName().empty() )
{
err_stream << "-unknown source-(";
}
else
{
err_stream << ex->get_streamName().c_str();
err_stream << "(";
}
err_stream << ex->get_line() << ")";
err_stream << ": lexer error " << ex->getName() << '(' << ex->getType() << ')' << " :\n\t"
<< ex->get_message() << " at position [" << ex->get_line() << ", "
<< ex->get_charPositionInLine()+1 << "], ";
{
ANTLR_UINT32 width;
width = ANTLR_UINT32_CAST(( (ANTLR_UINT8*)(m_input->get_data()) +
(m_input->size() )) - (ANTLR_UINT8*)( ex->get_index() ));
if (width >= 1)
{
if (isprint(ex->get_c() ))
{
err_stream << "near '" << (typename StringType::value_type) ex->get_c() << "' :\n";
}
else
{
err_stream << "near char(" << std::hex << ex->get_c() << std::dec << ") :\n";
}
err_stream << "\t";
err_stream.width( width > 20 ? 20 : width );
err_stream << (typename StringType::const_pointer)ex->get_index() << "\n";
}
else
{
err_stream << "(end of input).\n\t This indicates a poorly specified lexer RULE\n\t or unterminated input element such as: \"STRING[\"]\n";
err_stream << "\t The lexer was matching from line "
<< this->get_state()->get_tokenStartLine()
<< ", offset " << this->get_state()->get_tokenStartCharPositionInLine()
<< ", which\n\t ";
width = ANTLR_UINT32_CAST(((ANTLR_UINT8*)(m_input->get_data() )+
(m_input->size())) -
(ANTLR_UINT8*)(this->get_state()->get_tokenStartCharIndex() ));
if (width >= 1)
{
err_stream << "looks like this:\n\t\t";
err_stream.width( width > 20 ? 20 : width );
err_stream << (typename StringType::const_pointer)this->get_state()->get_tokenStartCharIndex() << "\n";
}
else
{
err_stream << "is also the end of the line, so you must check your lexer rules\n";
}
}
}
ImplTraits::displayRecognitionError( err_stream.str() );
}
template<class ImplTraits>
void Lexer<ImplTraits>::fillExceptionData( ExceptionBaseType* ex )
{
ex->set_c( m_input->_LA(1) ); /* Current input character */
ex->set_line( m_input->get_line() ); /* Line number comes from stream */
ex->set_charPositionInLine( m_input->get_charPositionInLine() ); /* Line offset also comes from the stream */
ex->set_index( m_input->index() );
ex->set_streamName( m_input->get_fileName() );
ex->set_message( "Unexpected character" );
}
template<class ImplTraits>
void Lexer<ImplTraits>::setCharStream(InputStreamType* input)
{
/* Install the input interface
*/
m_input = input;
/* Set the current token to nothing
*/
RecognizerSharedStateType* state = this->get_rec()->get_state();
state->set_token_present( false );
state->set_text("");
state->set_tokenStartCharIndex(-1);
/* Copy the name of the char stream to the token source
*/
this->get_tokSource()->set_fileName( input->get_fileName() );
}
template<class ImplTraits>
void Lexer<ImplTraits>::pushCharStream(InputStreamType* input)
{
// We have a stack, so we can save the current input stream
// into it.
//
this->get_istream()->mark();
this->get_rec()->get_state()->get_streams().push(this->get_input());
// And now we can install this new one
//
this->setCharStream(input);
}
template<class ImplTraits>
void Lexer<ImplTraits>::popCharStream()
{
InputStreamType* input;
// If we do not have a stream stack or we are already at the
// stack bottom, then do nothing.
//
typename RecognizerSharedStateType::StreamsType& streams = this->get_rec()->get_state()->get_streams();
if ( streams.size() > 0)
{
// We just leave the current stream to its fate, we do not close
// it or anything as we do not know what the programmer intended
// for it. This method can always be overridden of course.
// So just find out what was currently saved on the stack and use
// that now, then pop it from the stack.
//
input = streams.top();
streams.pop();
// Now install the stream as the current one.
//
this->setCharStream(input);
this->get_istream()->rewindLast();
}
return;
}
template<class ImplTraits>
void Lexer<ImplTraits>::emit(const CommonTokenType* token)
{
this->get_rec()->get_state()->set_token(token);
}
template<class ImplTraits>
typename Lexer<ImplTraits>::CommonTokenType* Lexer<ImplTraits>::emit()
{
/* We could check pointers to token factories and so on, but
* we are in code that we want to run as fast as possible
* so we are not checking any errors. So make sure you have installed an input stream before
* trying to emit a new token.
*/
RecognizerSharedStateType* state = this->get_rec()->get_state();
state->set_token_present(true);
CommonTokenType* token = state->get_token();
token->set_input( this->get_input() );
/* Install the supplied information, and some other bits we already know
* get added automatically, such as the input stream it is associated with
* (though it can all be overridden of course)
*/
token->set_type( state->get_type() );
token->set_channel( state->get_channel() );
token->set_startIndex( state->get_tokenStartCharIndex() );
token->set_stopIndex( this->getCharIndex() - 1 );
token->set_line( state->get_tokenStartLine() );
token->set_charPositionInLine( state->get_tokenStartCharPositionInLine() );
token->set_tokText( state->get_text() );
token->set_lineStart( this->get_input()->get_currentLine() );
return token;
}
template<class ImplTraits>
Lexer<ImplTraits>::~Lexer()
{
// This may have ben a delegate or delegator lexer, in which case the
// state may already have been freed (and set to NULL therefore)
// so we ignore the state if we don't have it.
//
RecognizerSharedStateType* state = this->get_rec()->get_state();
if ( state != NULL)
{
state->get_streams().clear();
}
}
template<class ImplTraits>
bool Lexer<ImplTraits>::matchs(ANTLR_UCHAR* str )
{
RecognizerSharedStateType* state = this->get_rec()->get_state();
while (*str != ANTLR_STRING_TERMINATOR)
{
if ( this->get_istream()->_LA(1) != (*str))
{
if ( state->get_backtracking() > 0)
{
state->set_failed(true);
return false;
}
this->exConstruct();
state->set_failed( true );
/* TODO: Implement exception creation more fully perhaps
*/
this->recover();
return false;
}
/* Matched correctly, do consume it
*/
this->get_istream()->consume();
str++;
}
/* Reset any failed indicator
*/
state->set_failed( false );
return true;
}
template<class ImplTraits>
bool Lexer<ImplTraits>::matchc(ANTLR_UCHAR c)
{
if (this->get_istream()->_LA(1) == c)
{
/* Matched correctly, do consume it
*/
this->get_istream()->consume();
/* Reset any failed indicator
*/
this->get_rec()->get_state()->set_failed( false );
return true;
}
/* Failed to match, exception and recovery time.
*/
if(this->get_rec()->get_state()->get_backtracking() > 0)
{
this->get_rec()->get_state()->set_failed( true );
return false;
}
this->exConstruct();
/* TODO: Implement exception creation more fully perhaps
*/
this->recover();
return false;
}
template<class ImplTraits>
bool Lexer<ImplTraits>::matchRange(ANTLR_UCHAR low, ANTLR_UCHAR high)
{
ANTLR_UCHAR c;
/* What is in the stream at the moment?
*/
c = this->get_istream()->_LA(1);
if ( c >= low && c <= high)
{
/* Matched correctly, consume it
*/
this->get_istream()->consume();
/* Reset any failed indicator
*/
this->get_rec()->get_state()->set_failed( false );
return true;
}
/* Failed to match, execption and recovery time.
*/
if (this->get_rec()->get_state()->get_backtracking() > 0)
{
this->get_rec()->get_state()->set_failed( true );
return false;
}
this->exConstruct();
/* TODO: Implement exception creation more fully
*/
this->recover();
return false;
}
template<class ImplTraits>
void Lexer<ImplTraits>::matchAny()
{
this->get_istream()->consume();
}
template<class ImplTraits>
void Lexer<ImplTraits>::recover()
{
this->get_istream()->consume();
}
template<class ImplTraits>
ANTLR_UINT32 Lexer<ImplTraits>::getLine()
{
return this->get_input()->get_line();
}
template<class ImplTraits>
ANTLR_MARKER Lexer<ImplTraits>::getCharIndex()
{
return this->get_istream()->index();
}
template<class ImplTraits>
ANTLR_UINT32 Lexer<ImplTraits>::getCharPositionInLine()
{
return this->get_input()->get_charPositionInLine();
}
template<class ImplTraits>
typename Lexer<ImplTraits>::StringType Lexer<ImplTraits>::getText()
{
RecognizerSharedStateType* state = this->get_rec()->get_state();
if ( !state->get_text().empty() )
{
return state->get_text();
}
return this->get_input()->substr( state->get_tokenStartCharIndex(),
this->getCharIndex() - this->get_input()->get_charByteSize()
);
}
template<class ImplTraits>
void Lexer<ImplTraits>::exConstruct()
{
new ANTLR_Exception<ImplTraits, RECOGNITION_EXCEPTION, InputStreamType>( this->get_rec(), "" );
}
template< class ImplTraits>
typename Lexer<ImplTraits>::TokenType* Lexer<ImplTraits>::getMissingSymbol( IntStreamType*,
ExceptionBaseType*,
ANTLR_UINT32 , BitsetListType*)
{
return NULL;
}
template< class ImplTraits>
ANTLR_INLINE const typename Lexer<ImplTraits>::RecognizerType* Lexer<ImplTraits>::get_rec() const
{
return this;
}
template< class ImplTraits>
ANTLR_INLINE const typename Lexer<ImplTraits>::RecognizerType* Lexer<ImplTraits>::get_recognizer() const
{
return this->get_rec();
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::RecognizerSharedStateType* Lexer<ImplTraits>::get_lexstate() const
{
return this->get_rec()->get_state();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::set_lexstate( RecognizerSharedStateType* lexstate )
{
this->get_rec()->set_state(lexstate);
}
template< class ImplTraits>
ANTLR_INLINE const typename Lexer<ImplTraits>::TokenSourceType* Lexer<ImplTraits>::get_tokSource() const
{
return this;
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::CommonTokenType* Lexer<ImplTraits>::get_ltoken() const
{
return this->get_lexstate()->token();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::set_ltoken( const CommonTokenType* ltoken )
{
this->get_lexstate()->set_token( ltoken );
}
template< class ImplTraits>
ANTLR_INLINE bool Lexer<ImplTraits>::hasFailed() const
{
return this->get_lexstate()->get_failed();
}
template< class ImplTraits>
ANTLR_INLINE ANTLR_INT32 Lexer<ImplTraits>::get_backtracking() const
{
return this->get_lexstate()->get_backtracking();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::inc_backtracking()
{
this->get_lexstate()->inc_backtracking();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::dec_backtracking()
{
this->get_lexstate()->dec_backtracking();
}
template< class ImplTraits>
ANTLR_INLINE bool Lexer<ImplTraits>::get_failedflag() const
{
return this->get_lexstate()->get_failed();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::set_failedflag( bool failed )
{
this->get_lexstate()->set_failed(failed);
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::InputStreamType* Lexer<ImplTraits>::get_strstream() const
{
return this->get_input();
}
template< class ImplTraits>
ANTLR_INLINE ANTLR_MARKER Lexer<ImplTraits>::index() const
{
return this->get_istream()->index();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::seek(ANTLR_MARKER index)
{
this->get_istream()->seek(index);
}
template< class ImplTraits>
ANTLR_INLINE const typename Lexer<ImplTraits>::CommonTokenType* Lexer<ImplTraits>::EOF_Token() const
{
const CommonTokenType& eof_token = this->get_tokSource()->get_eofToken();
return &eof_token;
}
template< class ImplTraits>
ANTLR_INLINE bool Lexer<ImplTraits>::hasException() const
{
return this->get_lexstate()->get_error();
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::ExceptionBaseType* Lexer<ImplTraits>::get_exception() const
{
return this->get_lexstate()->get_exception();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::constructEx()
{
this->get_rec()->exConstruct();
}
template< class ImplTraits>
ANTLR_INLINE ANTLR_MARKER Lexer<ImplTraits>::mark()
{
return this->get_istream()->mark();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::rewind(ANTLR_MARKER marker)
{
this->get_istream()->rewind(marker);
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::rewindLast()
{
this->get_istream()->rewindLast();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::memoize(ANTLR_MARKER ruleIndex, ANTLR_MARKER ruleParseStart)
{
this->get_rec()->memoize( ruleIndex, ruleParseStart );
}
template< class ImplTraits>
ANTLR_INLINE bool Lexer<ImplTraits>::haveParsedRule(ANTLR_MARKER ruleIndex)
{
return this->get_rec()->alreadyParsedRule(ruleIndex);
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::setText( const StringType& text )
{
this->get_lexstate()->set_text(text);
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::skip()
{
CommonTokenType& skipToken = this->get_tokSource()->get_skipToken();
this->get_lexstate()->set_token( &skipToken );
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::RuleMemoType* Lexer<ImplTraits>::getRuleMemo() const
{
return this->get_lexstate()->get_rulememo();
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::setRuleMemo(RuleMemoType* rulememo)
{
return this->get_lexstate()->set_rulememo(rulememo);
}
template< class ImplTraits>
ANTLR_INLINE typename Lexer<ImplTraits>::DebuggerType* Lexer<ImplTraits>::get_debugger() const
{
return this->get_rec()->get_debugger();
}
template< class ImplTraits>
ANTLR_INLINE ANTLR_UINT32 Lexer<ImplTraits>::LA(ANTLR_INT32 i)
{
return this->get_istream()->_LA(i);
}
template< class ImplTraits>
ANTLR_INLINE void Lexer<ImplTraits>::consume()
{
return this->get_istream()->consume();
}
ANTLR_END_NAMESPACE()