tmodlex.cpp
来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 689 行 · 第 1/2 页
CPP
689 行
// TMODLEX.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
// Tests the lexical scanner for OPL modules.
//
//
#include <e32test.h>
#include <opllex.h>
LOCAL_D RTest test(_L("TMODLEX"));
#define SOURCE(a) TSource source(a,(sizeof(a)-1)/sizeof(TText))
#define CHECK_SOURCE(t) CheckTokens(source,t)
#define SET_CHECK_SOURCE(a,t) source.Set(a,(sizeof(a)-1)/sizeof(TText)); CHECK_SOURCE(t)
#define _MYS(a) ((const TText)L##a)
class TModLexError
{
public:
TText **lines;
TUint lineNo;
TUint iOffset;
TInt iError;
};
class TSource : public MTextSource
{
public:
TSource(const TText* anArray, TInt aSize);
void Set(const TText* anArray, TInt aSize);
TInt Read(TDes& aBuf,TInt aPos);
TInt Read(TDes& aBuf);
void Close();
private:
TSource& operator=(TSource&);
TInt iPos;
TPtrC iBuf;
};
class TOplTokenCheck // Used to check token streams
{
public:
void CheckNext(COplModuleLexer *aLex) const;
void Check(COplModuleLexer *aLex) const;
public:
TOplToken::TValue iToken;
TOplToken::TType iType;
const TAny *iValue;
};
class TTestModLex : public MTextSourceSystem
{
public:
inline TTestModLex() : iSource(NULL) {};
void RunTests();
private:
void Test1(); // Interface
void Test2(); // Constructor alloc heaven
void Test3(); // Constants
void Test4(); // Operators and punctuation
void Test5(); // Identifiers
void Test6(); // Keywords
void Test7(); // Functions
private:
COplModuleLexer *GetLex();
void DestroyLex();
void SetSource(TSource& aSource);
void CheckTokens(TSource &aSource,const TOplTokenCheck *aTokenArray);
//void CheckErrors(const TCalcLexError *errors);
TOplToken MarkLex(); // Wraps iLex.Lex() in __UHEAP_MARK/__UHEAP_MARKEND
TInt MarkError(TOplToken &aToken); // Lea is expected to leave with an error - checks start end stuff
virtual TInt OpenSource(TDes& aFileName,MTextSource*& aTextSource);
private:
TSource *iSource;
COplModuleLexer *iLex;
};
//////////////////////////////////////////////////////////////////
//
// TOplTokenCheck
//
//////////////////////////////////////////////////////////////////
void TOplTokenCheck::CheckNext(COplModuleLexer *aLex) const
//
// Checks that the next token in the input matches this one
//
{
TOplToken next;
TRAPD(r,next=aLex->LexL());
test(r==KErrNone);
test(next==iToken);
switch (next.Class())
{
case TOplToken::EOperator:
break;
case TOplToken::EIdentifier: // Check the value
test(aLex->Type()==iType);
if (iToken==TOplToken::EConstant) // FOR NOW
{
switch (iType)
{
case TOplToken::EWord:
test(aLex->Constant().AsWordL()==*(TInt *)iValue);
break;
case TOplToken::ELong:
test(aLex->Constant().AsLongL()==*(TInt32 *)iValue);
break;
case TOplToken::EReal:
test(aLex->Constant().AsRealL()==*(TReal64 *)iValue);
break;
case TOplToken::EString:
test(aLex->Constant().AsStringL().Compare(*(TDesC *)iValue)==0);
break;
default:
test(EFalse);
}
}
break;
case TOplToken::EPunctuation:
break;
case TOplToken::EKeyword:
case TOplToken::EReserved:
break;
case TOplToken::ECall:
test(aLex->Type()==iType);
break;
default:
test(EFalse);
}
}
void TOplTokenCheck::Check(COplModuleLexer *aLex) const
//
// Checks that the next token matches this one
// ALWAYS does a Lex, UnLex Lex to check it.
//
{
__UHEAP_MARK;
CheckNext(aLex);
// aLex->UnLex();
// CheckNext(aLex);
__UHEAP_MARKEND;
}
////////////////////////////////////////////////////////////
//
// TSoure - text source
//
////////////////////////////////////////////////////////////
TSource::TSource(const TText *anArray, TInt aSize) : iPos(0), iBuf(anArray, aSize)
//
//
//
{
}
void TSource::Set(const TText *anArray, TInt aSize)
//
//
//
{
iBuf.Set(anArray,aSize);
iPos=0;
}
TInt TSource::Read(TDes& aBuf, TInt aPos)
//
// Copies the relevant bit into aBuf
//
{
TInt ret=KErrEof;
if (aPos<iBuf.Length())
{
TInt remainder=iBuf.Length()-aPos;
if (remainder>aBuf.MaxLength())
remainder=aBuf.MaxLength();
aBuf.Copy(iBuf.Mid(aPos,remainder));
iPos=aPos+remainder;
ret=KErrNone;
}
return ret;
}
TInt TSource::Read(TDes& aBuf)
//
// Reads from the end of the last read;
//
{
return Read(aBuf,iPos);
}
void TSource::Close()
//
//
//
{
}
////////////////////////////////////////////////////////////////////
//
// TTestModLex
//
////////////////////////////////////////////////////////////////////
COplModuleLexer *TTestModLex::GetLex()
//
// I'm a gonna have me a lexer Pa. Creates a new lexical scanner
//
{
TRAPD(r,iLex=COplModuleLexer::NewL());
test(r==KErrNone);
return iLex;
}
void TTestModLex::DestroyLex()
//
// Chucks away the lexer
//
{
delete iLex;
iLex=NULL;
}
void TTestModLex::SetSource(TSource& aSource)
//
//
//
{
iSource=&aSource;
}
void TTestModLex::CheckTokens(TSource& aSource,const TOplTokenCheck *aTokenArray)
//
// Checks teh stream of tokens that we get back from aLineArray
//
{
TSourceTranslateError anError;
SetSource(aSource);
TRAPD(r,iLex->OpenL(*this,_L(""),anError));
test(r==KErrNone);
do
{
aTokenArray->Check(iLex);
aTokenArray++;
} while (aTokenArray->iToken!=TOplToken::EBadToken);
iLex->Reset();
}
TOplToken TTestModLex::MarkLex()
//
// Wraps successful lex __UHEAP_MARK/__UHEAP_MARKEND
//
{
__UHEAP_MARK;
TOplToken token;
TRAPD(r,token=iLex->LexL());
test(r==KErrNone);
__UHEAP_MARKEND;
return token;
}
TInt TTestModLex::MarkError(TOplToken &aToken)
//
// Wraps failed lex __UHEAP_MARK/__UHEAP_MARKEND
//
{
__UHEAP_MARK;
TRAPD(r,aToken=iLex->LexL());
__UHEAP_MARKEND;
return r;
}
TInt TTestModLex::OpenSource(TDes& /* for now*/,MTextSource*& aTextSource)
//
//
//
{
if (iSource==NULL)
return KErrNotFound;
aTextSource=iSource; // Think about it - it's not as daft as it seems
return KErrNone;
}
LOCAL_D const TText test1Source[]=
//
// Source(s) used for testing basic interface
//
{
_MYS("PROC\x2029 1 a%\x2029 1.2 c$\x2029")
};
void TTestModLex::Test1()
//
// All public funcitons
//
{
__UHEAP_MARK;
test.Start(_L("New"));
GetLex();
test.Next(_L("OpenL"));
SOURCE(test1Source);
SetSource(source);
TSourceTranslateError anError;
TRAPD(r,iLex->OpenL(*this,_L(""),anError));
test(r==KErrNone);
test.Next(_L("Error offset"));
test(iLex->TokenOffset()==0);
test.Next(_L("Lex"));
test(MarkLex()==TOplToken::EProc);
test.Next(_L("Unlex"));
iLex->UnLex();
test(iLex->TokenOffset()==0);
test(MarkLex()==TOplToken::EProc);
test(MarkLex()==TOplToken::EEos);
test.Next(_L("Line number/fetching line"));
test(iLex->LineNumber()==0);
test(MarkLex()==TOplToken::EConstant); // truck over the edge
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?