/*********************************************************************
Copyright (C) 2001 by
Alexander Berthold, alexander-berthold@web.de.
Hoegestr. 54
79108 Freiburg i. Breisgau
Germany
-- This file is part of cxTokenizer --
"cxTokenizer" is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
"cxTokenizer" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with "cxTokenizer"; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
---------------------------------------------------------------
If you find any bugs or if you make other corrections/
enhancements, i'd appreciate if you'd let me know about
that. My email is
alexander-berthold@web.de
If you share this code, do not remove this text.
---------------------------------------------------------------
Class: cxTokenizerContext
Author: Alexander Berthold
Copyright: Alexander Berthold
Date: 2001/12/19
Version: 0.2.01
Purpose: This class manages the context of the lexxer.
- It maintains a list of currently active lexxer rules
- It stores the cookies of the active lexxer rules
Version history:
- 2001/05/16
Fixed problem with std::list<cxListEntry*> destruction and
STLport 4.0.
- 2001/05/19
Renamed class from 'cpLexxerContext' to 'cxTokenizerContext'.
- 2001/06/12
Current source labeled version 0.1.16
- 2001/08/10
Fixed small bug when >2 rules all applied.
- 2001/12/19
Labeled version 0.2.01
*********************************************************************/
// cxTokenizerContext.h: interface for the cxTokenizerContext class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CXTOKENIZERCONTEXT_H__121468FE_E85D_42BE_8226_FDA6A3D57D52__INCLUDED_)
#define AFX_CXTOKENIZERCONTEXT_H__121468FE_E85D_42BE_8226_FDA6A3D57D52__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Forwards
class cxTokenizer;
class cxTokenizerTokenRule;
class cxTokenizerMapData;
namespace utility
{
class rule_is_deleted;
};
class cxTokenizerContext :
public ctkFlagsMixin<xtctx_flags>,
public ctkCheckValid
{
// Construction/Destruction
public:
cxTokenizerContext();
virtual ~cxTokenizerContext();
void vReset();
// Local classes
protected:
// Data class
class cxListEntry :
public ctkCheckValid
{
// Construction/Destruction
public:
cxListEntry(int _nStartPosition, cxTokenizerMapData *_ptmdRule)
{
fNotApplying =false;
fMarkedForDeletion=false;
nStartPosition =_nStartPosition;
nEndPosition =-1;
ptmdRule =_ptmdRule;
ptmdRuleLastValid=NULL;
}
// Attributes
protected:
bool fNotApplying; // Rule not applying anymore
bool fMarkedForDeletion; // Rule is marked for deletion
int nStartPosition;
int nEndPosition;
cxTokenizerMapData *ptmdRule; // Current sub-rule
cxTokenizerMapData *ptmdRuleLastValid; // Last valid rule
// Operations
public:
/*** Diagnostics ***/
#ifdef _DEBUG
bool fCheckValid() const;
#else
bool fCheckValid() const
{ return true; };
#endif
/*** Status query ***/
bool fIsCompleted() const
{ return (nEndPosition!=-1); };
bool fIsNotApplying() const
{ return fNotApplying; };
bool fIsMarkedForDeletion() const
{ return fMarkedForDeletion; };
cxTokenizerMapData* ptmdGetRule() const
{ return ptmdRule; };
cxTokenizerMapData* ptmdGetLastValidRule() const
{ return ptmdRuleLastValid; };
int nGetStartPosition() const
{ return nStartPosition; };
int nGetEndPosition() const
{ return nEndPosition; };
/*** Status manipulation ***/
void vSetRule(cxTokenizerMapData* _ptmdRule)
{ ptmdRule=_ptmdRule; };
void vMarkForDeletion()
{fMarkedForDeletion=true;};
void vSetNotApplying()
{fNotApplying=true;};
void vSetCompleted(int _nEndPosition, cxTokenizerMapData* _ptmdRuleLastValid)
{nEndPosition=_nEndPosition;
ptmdRuleLastValid=_ptmdRuleLastValid;
ASSERT(ptmdRuleLastValid!=NULL);
ASSERT(nEndPosition!=-1);};
};
// Helper classes
class hlp1 : public std::list<cxListEntry*> {};
class tc_list_type : public hlp1
{
public:
template <class _Predicate>
void remove_if(_Predicate __pred)
{
iterator __first = begin();
iterator __last = end();
while (__first != __last) {
iterator __next = __first;
++__next;
if (__pred(*__first)) erase(__first);
__first = __next;
}
}
iterator erase(iterator it)
{
delete (*it);
return hlp1::erase(it);
}
iterator erase(iterator first, iterator last)
{
iterator it;
for(it=first;it!=last;)
delete (*it);
return hlp1::erase(first,last);
}
void clear()
{
erase(begin(),end());
}
};
// Typedefs
public:
typedef std::map<DWORD,cxTokenizerContextCookie*,std::less<DWORD> >
tc_cookiemap_type;
typedef tc_cookiemap_type::iterator
cookiemap_iterator;
typedef tc_cookiemap_type::const_iterator
const_cookiemap_iterator;
typedef tc_cookiemap_type::value_type
cookiemap_valuetype;
typedef tc_list_type::iterator
rulelist_iterator;
// Attributes
protected:
// The owner of this class
cxTokenizer *m_pxtTokenizer;
// List of currently used rules
tc_list_type m_lstTokenRules;
// Current text
std::tstring m_strCurrentText;
// The map of cookies (each 'token rule' can set one)
tc_cookiemap_type m_mapCookies;
// The map of global cookies (each 'token rule' can set one)
tc_cookiemap_type m_mapGlobalCookies;
// Operations
public:
#ifdef _DEBUG
virtual bool fCheckValid() const;
static bool fRunDiagnostics();
#else
virtual bool fCheckValid() const
{ return true; };
#endif
/*** Token rule list operations ***/
tc_list_type*
plstGetTokenRuleList()
{ return &m_lstTokenRules; };
bool fActiveRules() const
{
tc_list_type::const_iterator it;
for(it=m_lstTokenRules.begin();
it!=m_lstTokenRules.end();
it++)
{
if( !(*it)->fIsNotApplying() )
return true;
}
return false;
};
/*** Cookie operations ***/
template<class T>
bool fSetCookieHlp(tc_cookiemap_type& map, const cxTokenizerTokenRule* pttrRule, T** ppCookie)
{
ASSERT(pttrRule!=NULL);
ASSERT(pttrRule->fCheckValid());
// TODO: find better solution
DWORD dwCookieID = (DWORD)pttrRule;
cxTokenizerContextCookie *ptccCookie = NULL;
cookiemap_iterator it;
it =map.find(dwCookieID);
if(it!=map.end())
{
ASSERT((*it).second->fIsDeleted());
new ((*it).second) T;
(*it).second->m_dwMyCookieID = dwCookieID;
(*ppCookie) = (T*)((*it).second);
return true;
}
ptccCookie =new T;
ptccCookie->m_dwMyCookieID=dwCookieID;
map.insert(cookiemap_valuetype(dwCookieID,ptccCookie));
(*ppCookie) = (T*)ptccCookie;
return true;
}
template<class T>
bool fGetCookieHlp(const tc_cookiemap_type& map, const cxTokenizerTokenRule* pttrRule, T** ppCookie) const
{
ASSERT(pttrRule!=NULL);
ASSERT(pttrRule->fCheckValid());
// TODO: find better solution
DWORD dwCookieID = (DWORD)pttrRule;
cxTokenizerContextCookie *pCookie = ptccGetCookie(map,dwCookieID);
(*ppCookie) = (T*)pCookie;
return (pCookie!=NULL);
}
template<class T>
bool fGetCookie(const cxTokenizerTokenRule* pttrRule, T** ppCookie) const
{ return fGetCookieHlp(m_mapCookies,pttrRule,ppCookie); };
template<class T>
bool fGetConstCookie(const cxTokenizerTokenRule* pttrRule, const T** ppCookie) const
{ return fGetCookieHlp(m_mapCookies,pttrRule,ppCookie); };
template<class T>
bool fSetCookie(const cxTokenizerTokenRule* pttrRule, T** ppCookie)
{ return fSetCookieHlp(m_mapCookies,pttrRule,ppCookie); };
template<class T>
bool fGetGlobalCookie(const cxTokenizerTokenRule* pttrRule, T** ppCookie) const
{ return fGetCookieHlp(m_mapGlobalCookies,pttrRule,ppCookie); };
template<class T>
bool fGetGlobalConstCookie(const cxTokenizerTokenRule* pttrRule, const T** ppCookie) const
{ return fGetCookieHlp(m_mapGlobalCookies,pttrRule,ppCookie); };
template<class T>
bool fSetGlobalCookie(const cxTokenizerTokenRule* pttrRule, T** ppCookie)
{ return fSetCookieHlp(m_mapGlobalCookies,pttrRule,ppCookie); };
cxTokenizerContextCookie*
ptccGetCookie(const tc_cookiemap_type& map, DWORD dwCookieID) const;
bool fDeleteCookie(cxTokenizerTokenRule* pttrRule);
bool fDeleteCookie(DWORD dwCookieID);
bool fDeleteGlobalCookie(cxTokenizerTokenRule* pttrRule);
bool fDeleteGlobalCookie(DWORD dwCookieID);
/*** Data access operations ***/
void vSetTokenizer(cxTokenizer *pxtTokenizer)
{ m_pxtTokenizer = pxtTokenizer; };
std::tstring& strGetCurrentText()
{ return m_strCurrentText; };
const std::tstring& strGetCurrentTextConst() const
{ return m_strCurrentText; };
TCHAR tcPeekNextCharacter() const;
bool fIsLastCharacter() const;
int nDeleteMarkedListEntries();
void vCleanUpAfterTokenRecognition();
void vIncludeStream(cxTokenizerInputStream *ptisInclude);
// Friend declarations
friend class cxTokenizer;
friend class utility::rule_is_deleted;
};
#endif // !defined(AFX_CXTOKENIZERCONTEXT_H__121468FE_E85D_42BE_8226_FDA6A3D57D52__INCLUDED_)