开发者

Small Command line scripter (like Autocad commands) one line editor

Basically I don't know from where to start, I need to add a line script for my application that is not so complicated, just to execute pre-defined commands, for instance:

command> New Invoice --> create new invoice

command> customer profile --> open customer form where cust id = CustID

command> run End-Of-Day - run the end of day process

command> scr 1020 --> open form id = 1020

How can I start? I have no problem of recommending any third party components (parsers,evaluators,etc..).

whats missing is the bas开发者_开发知识库ic structure no details, just a theory for implementation.

Thanks, Objectberg


Maybe you will like this, maybe not. But it sounds actually like you would like to get some basic understanding, too. You might like what I think is a classic first reading on how to build a compiler by Jack Crenshaw. You can find it at this address. It is more than what you are looking for but it's written in Turbo Pascal and the narrative is actually kind of fun to read.

Good luck.


If it's sufficiently simple (even with optional arguments), something based on TStringList actually works decently. Here's a simple example to get you started:

type
  TCommandRec = record
    Command: string;
    Proc: array(AArgs: TStringList);
  end;

const
  Commands: array(0..4) of TCommandRec = (
    (Command: 'New';      Proc: DoNew),
    (Command: 'Customer'; Proc: DoCustomer),
    (Command: 'Run';      Proc: DoRun),
    (Command: 'Scr';      Proc: DoScr),
    (Command: 'Find';     Proc: DoFind));

procedure RunScript(const AFileName: string);
var
  Script, Args: TStringList;
  i, j: Integer;
begin
  Script := TStringList.Create;
  try
    Script.LoadFromFile(AFileName);
    Args := TStringList.Create;
    try
      Args.Delimiter := ' ';
      for i := 0 to Script.Count - 1 do begin
        Args.DelimitedText := Script[i];
        for j := Low(Commands) to High(Commands) do
          if SameText(Args[0], Commands[j].Command) then begin
            Commands[j].Proc(Args);
            Break;
          end;
      end;
    finally
      Args.Free;
    end;
  finally
    Script.Free;
  end;
end;

procedure DoRun(AArgs: TStringList);
begin
  if SameText(AArgs[1], 'End-of-day') then
    RunEndOfDayProcess
  else if SameText(AArgs[1], 'Hourly') then
    RunHourlyProcess
  else
    raise EInvalidScript.Create;
end;

procedure DoFind(AArgs: TStringList);
var
  FindType: string;
begin
  if (AArgs.Count <> 5) or not SameText(AArgs[2], 'by') then
    raise EInvalidScript.Create;
  if SameText(AArgs[1], 'Cust') then begin
    if SameText(AArgs[3], 'Name') then
      FindCustomer(AArgs[4], '')
    else if SameText(AArgs[3], 'LastName') then
      FindCustomer('', AArgs[4])
  end
  else if SameText(AArgs[1], 'Contact') then begin
    ...
  end
  else
    raise EInvalidScript.Create;
end;

If you have multiple optional arguments (e.g., FIND CUST BY NAME John AND LASTNAME Smith) then, rather than hardcoding the stringlist offsets like I've done above, delete each argument from the stringlist as you process it (or add it to your query). That way, when it's empty you know you're done with the line, and you only need to look at AArgs[0] to see if you recognize the next bit.


You could look at tcl. That was its original purpose--to be a tool command language framework which you could embed into another program. Tcl provides a language syntax with variables and control structures (loops etc). You would add tcl commands and functions to access your program's features.


First question: If it's a limited number of canned commands, why not just implement it using menus?

But if you want real scripting, there are plenty of script engines that you can plug into Delphi. Most of them are based on real programming languages, though, which sounds a bit more complicated than what you're looking for.

If you want to design your own simple scripting language, you'll need a bit of knowledge about parser theory. I'd recommend looking around on the GOLD Parser site, which has some theoretical information available and also some tools that will help you set up your own language rules. It has a Delphi implementation available on the site.


TMS and Greatis have scripters for this, I think.


You could integrate Python with Python for Delphi. In the demos there's "command-line example" if I remember correctly.


A line scripter like your suggesting is not very hard to write, you could easily use a tStringList, set the delimiter to a space, set the text property for each line, then its a mater of evaluating the first item and dispatching the rest of the "parameters" on the line to a specific function. If you don't match the expected criteria, then you handle the error condition and stop processing the script.

If your looking for something more than a simple line scripter, take a look at PascalScript, which allows you to write scripts using a familiar pascal language.


If you are serious about "rolling your own" get a copy of "The Definitive ANTLR Reference" by Terence Parr.

It is all Java oriented, but gives a good background to parsing, and it generates parser code that is actually understandable.

There is also a commercial ANTLR for Delphi product, but I haven't actually tried it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜