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 + -
显示快捷键?