Original in Russian: http://18delphi.blogspot.ru/2013/11/gui_5.html
GUI-testing. Table of contents
Now, a couple of words about how it is organized.
(I’m writing “at sight” from memory.)
We have a parser that parsers the input stream for tokens.
The parser interface is something like this:
We have a script engine that parsers text using parser and compiles it.
The main procedure of the script engine is something like this:
The process of compilation and launch:
To be continued, for sure. I have already written a plan of 8 more articles. I hope that “at the end of the path” the interested readers will be able to compile the script/test engine of the parts.
GUI-testing. Table of contents
Now, a couple of words about how it is organized.
(I’m writing “at sight” from memory.)
We have a parser that parsers the input stream for tokens.
The parser interface is something like this:
type TscriptTokenType = (ttInteger, ttString, ttKeyWord); IscriptParser = interface function IsEOF : Boolean; procedure NextToken; function TokenType: TscriptTokenType; function IntegerToken: Integer; function StringToken: String; function KeyWordToken: TscriptKeyWord; end;//IscriptParser
We have a script engine that parsers text using parser and compiles it.
The main procedure of the script engine is something like this:
type
TscriptContext = class
function PopInteger: Integer;
procedure PushInteger(aValue : Integer);
function PopString: String;
procedure PushString(const aValue : String);
function PopObject: TObject;
procedure PushObject(aValue : TObject);
...
end;//TscriptContext
TscriptKeyWord = class
function IsImmediate: Boolean; virtual;
{* - is the word DIRECTLY executed? Like PROCEDURE, FUNCTION, VAR, CONST, etc. }
procedure DoIt(aContext: TscriptContext); virtual; abstract;
{* - the code of word execution. }
end;//TscriptKeyWord
TscriptCode = class
procedure CompileInteger(aValue: Integer);
procedure CompileString(const aValue: String);
procedure CompileKeyWord(aValue: TscriptKeyWord);
procedure Run; // - executes the compiled code
procedure RunInContext(aContext: TscriptContext); // - executes the compiled code in the specified context
...
end;//TscriptCode
TscriptCompileContext = class(TscriptContext)
property Parser: IscriptParser;
{* - The current parcer. }
property Code: TscriptCode;
{* - The current compiled code. }
end;//TscriptCompileContext
procedure TscriptEngine.Compile(const aParser : IscriptParser; aCode : TscriptCode);
var
l_Context : TscriptCompileContext;
begin
l_Context := TscriptCompileContext.Create;
try
l_Context.Parser := aParser;
// - So that words of DIRECT execution could be executed and the current parser could be managed
l_Context.Code := aCode; // - place where the code is compiled to
while not aParser.IsEOF do
begin
Case aParser.TokenType of
ttInteger :
aCode.CompileInteger(aParser.IntegerToken); // - we compile the integer
ttStringr :
aCode.CompileString(aParser.StringToken); // - we compile the string
ttKeyWord :
begin
if aParser.KeyWordToken.IsImmediate then
// - the word of DIRECT execution like PROCEDURE, FUNCTION, VAR, CONST, etc.
// (“user” words – can also be like this)
aParser.KeyWordToken.DoIt(l_Context)
// - we execute the word in context of compilation,
// at the same time such words can manage either parser or the compiled code
else
aCode.CompileKeyWord(aParser.KeyWordToken); // - we compile the word call
end;//ttKeyWord
else
Assert(false); // - in case it appears (by the way, it exists)
end;//Case aParser.TokenType
aParser.NextToken;
end;//while not aParser.IsEOF
finally
FreeAndNil(l_Context);
end;//try..finally
end;//TscriptEngine.Compile
The process of compilation and launch:
procedure RunCode(const aParser : IscriptParser); var l_Code : TscriptCode; l_ScriptEngine : TscriptEngine; begin l_Code := TscriptCode.Create; try l_ScriptEngine := TscriptEngine.Create; try l_ScriptEngine.Compile(aParser, l_Code); // - we compile the code from the input stream finally FreeAndNil(l_ScriptEngine); end;//try..finally l_Code.Run; // - the code can be executed at once, // but, in general, it can be saved in some outer object // and executed a number of times finally FreeAndNil(l_Code); end;//try..finally end;
To be continued, for sure. I have already written a plan of 8 more articles. I hope that “at the end of the path” the interested readers will be able to compile the script/test engine of the parts.
Комментариев нет:
Отправить комментарий