小命令行脚本程序(如Autocad命令)一行编辑器

时间:2010-03-24 16:36:19

标签: delphi delphi-2010

基本上我不知道从哪里开始,我需要为我的应用程序添加一个不那么复杂的行脚本,只是为了执行预定义的命令,例如:

命令>新发票 - >创建新发票

命令>客户资料 - >打开客户表单,其中cust id = CustID

命令>运行End-of-Day - 运行结束日期过程

命令> scr 1020 - >开放表格id = 1020

我该如何开始? 我没有推荐任何第三方组件(解析器,评估器等)的问题。

缺少的是基本结构没有细节,只是一个实施理论。

谢谢, Objectberg

8 个答案:

答案 0 :(得分:3)

也许你会喜欢这个,也许不喜欢。但听起来实际上你也希望得到一些基本的理解。您可能会喜欢我认为如何通过Jack Crenshaw构建编译器的经典首读。您可以在this address找到它。它不仅仅是你想要的东西,而是用Turbo Pascal写的,叙述实际上很有趣。

祝你好运。

答案 1 :(得分:3)

如果它足够简单(即使使用可选参数),基于TStringList的东西实际上也可以正常工作。这是一个让你入门的简单例子:

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;

如果您有多个可选参数(例如,FIND CUST BY NAME John AND LASTNAME Smith),那么,而不是像上面那样对字符串列表偏移进行硬编码,在处理时删除stringlist中的每个参数(或将其添加到查询中) )。这样,当它空了,你就知道你完成了这条线,你只需要看AArgs[0]看看你是否认识到下一位。

答案 2 :(得分:1)

你可以看看tcl。这是它的最初目的 - 成为一个工具命令语言框架,您可以将其嵌入到另一个程序中。 Tcl提供了带有变量和控制结构(循环等)的语言语法。您可以添加tcl命令和函数来访问程序的功能。

答案 3 :(得分:1)

第一个问题:如果它是有限数量的固定命令,为什么不使用菜单实现它呢?

但是如果你想要真正的脚本,那么有很多脚本引擎可以插入Delphi。但是,大多数都是基于真正的编程语言,这听起来比你想要的要复杂得多。

如果你想设计自己的简单脚本语言,你需要一些关于解析器理论的知识。我建议您查看GOLD Parser site,其中包含一些可用的理论信息以及一些可帮助您设置自己的语言规则的工具。它在网站上提供了Delphi实现。

答案 4 :(得分:1)

我认为,TMS和Greatis为此提供了脚本编写器。

答案 5 :(得分:1)

您可以将Python与Python for Delphi集成。在演示中,如果我没记错的话,那就是“命令行示例”。

答案 6 :(得分:1)

像你的建议一样的行脚本编写器不是很难编写,你可以轻松使用tStringList,将分隔符设置为空格,为每一行设置text属性,然后是评估第一个项目并调度其余的“参数”就行到了特定的功能。如果与预期条件不匹配,则处理错误条件并停止处理脚本。

如果您正在寻找的不仅仅是简单的行脚本编写器,请查看PascalScript,它允许您使用熟悉的pascal语言编写脚本。

答案 7 :(得分:1)

如果你认真对待“自己动手”,可以获得Terence Parr的“The Definitive ANTLR Reference”的副本。

它完全是面向Java的,但它为解析提供了良好的背景,并且它生成了实际上可以理解的解析器代码。

Delphi产品还有一个商业化的ANTLR,但我还没有尝试过。