// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// This library 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
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/cfgscript/SourceTokenizer.h,v 1.16 2005/05/02 23:07:26 kommer Exp $
#ifndef acdk_cfgscript_SourceTokenizer_h
#define acdk_cfgscript_SourceTokenizer_h
#include "Config.h"
#include <acdk/io/File.h>
#include <acdk/io/StreamTokenizer.h>
#include <acdk/util/logging/Log.h>
namespace acdk {
namespace cfgscript {
/**
represents an parsed CfgScript token.
This class is only used inside the interpreter
*/
struct ACDK_CFGSCRIPT_LIB_PUBLIC SourceToken
{
int tk;
acdk::lang::dmi::ScriptVar value;
acdk::io::CharStreamPos sourcePos;
SourceToken(int token, IN(acdk::lang::dmi::ScriptVar) val, IN(acdk::io::CharStreamPos) spos)
: tk(token)
, value(val)
, sourcePos(spos)
{
}
};
enum SourceTk
{
STkTemplateText = -100,
STkTemplateExpression = -101,
STkTemplateComment = -102
};
enum STFlags
{
STWantWhiteSpace = 0x00001,
STWantNewLine = 0x00002,
STWantComments = 0x00004,
STParseTemplate = 0x00008
};
ACDK_DEF_LIB_ENUM(ACDK_CFGSCRIPT_LIB_PUBLIC, STFlags);
ACDK_DECL_CLASS(TokenizedSource);
/**
before executing a CfgScript the source will be parsed
to token.
This class is only used inside the interpreter.
*/
class ACDK_CFGSCRIPT_LIB_PUBLIC TokenizedSource
: extends acdk::lang::Object
{
public:
typedef acdk::lang::sys::core_vector<SourceToken> TokenContainer;
TokenContainer _tokenStack;
int _tokenIdx;
int _endTokenIdx;
RString _fileName;
RString _sourceText;
acdk::io::RReader _reader;
acdk::io::RStreamTokenizer _streamTokenizer;
bool _sourceTokenized;
/**
STFlags currently only 0 or STParseTemplate
*/
int _flags;
TokenizedSource(INP(RString) fileName, int flags = 0);
TokenizedSource(INP(RString) fileName, INP(RString) sourceText, int flags = 0);
TokenizedSource(INP(RString) fileName, INP(acdk::io::RReader) sourceReader, int flags = 0);
void parseAll();
/**
return Nil if line cannot be found
*/
RString getCodeOfLine(int lineNo);
SourceToken& getSourceToken(int tkidx)
{
if (tkidx > _tokenStack.size() - 1)
tkidx = _tokenStack.size() - 1;
return _tokenStack[tkidx];
}
int getEndTokenIdx()
{
if (_endTokenIdx == -1)
return _tokenStack.size();
return _endTokenIdx;
}
foreign RString _dumpTokens();
virtual void getCollectableFields(FieldReferences& fields);
protected:
void _loadSource();
void _parseTemplate();
int _parseTemplateText();
int _parseSource();
};
ACDK_DECL_CLASS(SourceTokenizer);
/**
before executing a CfgScript the source will be parsed
to token.
This class is only used inside the interpreter.
*/
class ACDK_CFGSCRIPT_LIB_PUBLIC SourceTokenizer
//: extends acdk::io::StreamTokenizer
: extends acdk::lang::Object
{
public:
RTokenizedSource _tokenized;
int _tokenIdx;
int _endTokenIdx;
protected:
acdk::lang::sys::core_vector<int> _flagStack;
public:
//SourceTokenizer(INP(RString) fileName, int flags = 0);
//SourceTokenizer(INP(RString) fileName, INP(RString) sourceText, int flags = 0);
SourceTokenizer(INP(RTokenizedSource) source, int flags = 0)
: _tokenized(source)
, _tokenIdx(source->_tokenIdx)
, _endTokenIdx(source->getEndTokenIdx())
{
_flagStack.push_back(flags);
}
int nextToken();
foreign SourceToken& nextSourceToken();
foreign SourceToken& curSourceToken();
void pushBack();
foreign acdk::lang::dmi::ScriptVar& curValue();
RString getCurTokenAsCode() { return acdk::io::StreamTokenizer::toCode(curSourceToken().tk, curSourceToken().value); }
//RString getCurTokenAsString() { return acdk::io::StreamTokenizer::toCode(curSourceToken().tk, curSourceToken().value); }
int curToken();
inline int getFlags() { return _flagStack[_flagStack.size() - 1]; }
inline void pushFlags(int flags) { _flagStack.push_back(flags); }
inline void popFlags() { _flagStack.pop_back(); }
int getCurrentTokenIndex() { return _tokenIdx; }
void setCurrentTokenIndex(int tokenIndex) { _tokenIdx = tokenIndex; }
/**
return token represents EOF
*/
foreign static SourceToken& _getEofToken();
foreign RString _dumpTokens();
protected:
bool _skipToken();
};
#if !defined(DOXYGENONLY)
struct SourceTokenizerPosGuard
{
RSourceTokenizer _st;
int _sp;
SourceTokenizerPosGuard(INP(RSourceTokenizer) st)
: _st(st)
{
_sp = _st->getCurrentTokenIndex();
}
~SourceTokenizerPosGuard()
{
_st->setCurrentTokenIndex(_sp);
}
};
#endif //!defined(DOXYGENONLY)
} // cfgscript
} // acdk
#endif //acdk_cfgscript_SourceTokenizer_h
|