| 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() |
| |