Небольшой скрипт командной строки (например, команды Autocad) редактор одной строки - PullRequest
5 голосов
/ 24 марта 2010

В принципе, я не знаю, с чего начать, мне нужно добавить сценарий строки для моего приложения, который не так сложен, просто для выполнения предопределенных команд, например:

команда> Новый счет -> создать новый счет

команда> профиль клиента -> открыть форму клиента, где cust id = CustID

command> run End-Of-Day - запустить процесс окончания дня

команда> scr 1020 -> идентификатор открытой формы = 1020

Как я могу начать? У меня нет проблем с рекомендациями сторонних компонентов (анализаторы, оценщики и т. Д.).

отсутствует базовая структура без подробностей, просто теория реализации.

Спасибо, Objectberg

Ответы [ 8 ]

3 голосов
/ 24 марта 2010

Может быть, вам понравится, а может и нет. Но на самом деле это звучит так, как будто вы хотели бы также получить некоторое базовое понимание. Вам может понравиться то, что я считаю классическим первым чтением о том, как построить компилятор, Джеком Креншоу. Вы можете найти его на этот адрес . Это больше, чем то, что вы ищете, но написано на Turbo Pascal, и повествование на самом деле забавно читать.

Удачи.

3 голосов
/ 24 марта 2010

Если это достаточно просто (даже с необязательными аргументами), то что-то на основе 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), тогда вместо жесткого кодирования смещений списка строк, как я делал выше, удалите каждый аргумент из списка строк при его обработке (или добавьте его в свой запрос). Таким образом, когда он пуст, вы знаете, что со строкой покончено, и вам нужно только взглянуть на AArgs[0], чтобы увидеть, распознаете ли вы следующий бит.

1 голос
/ 25 марта 2010

Если вы серьезно относитесь к «сворачиванию своего», получите копию «The Definitive ANTLR Reference» от Terence Parr.

Все это ориентировано на Java, но дает хороший фон для синтаксического анализа и генерирует код синтаксического анализатора, который действительно понятен.

Существует также коммерческий ANTLR для продукта Delphi, но я на самом деле не пробовал его.

1 голос
/ 24 марта 2010

Строковый сценарий, подобный вашему предложению, не очень сложен в написании, вы можете легко использовать tStringList, установить разделитель на пробел, установить текстовое свойство для каждой строки, а затем - оценить первый элемент и отправить Остальные «параметры» в строке для конкретной функции. Если вы не соответствуете ожидаемым критериям, вы обрабатываете условие ошибки и прекращаете обработку сценария.

Если вы ищете что-то большее, чем простой строчный сценарий, взгляните на PascalScript , который позволяет вам писать сценарии с использованием знакомого языка паскаль.

1 голос
/ 24 марта 2010

Вы можете интегрировать Python с Python для Delphi . В демоверсиях есть «пример командной строки», если я правильно помню.

1 голос
/ 24 марта 2010

У TMS и Greatis есть сценаристы для этого, я думаю.

1 голос
/ 24 марта 2010

Первый вопрос: если это ограниченное количество стандартных команд, почему бы просто не реализовать их с помощью меню?

Но если вам нужен настоящий сценарий, существует множество механизмов сценариев, которые вы можете подключить к Delphi.Большинство из них основаны на реальных языках программирования, хотя это звучит немного сложнее, чем то, что вы ищете.

Если вы хотите создать свой собственный простой язык сценариев, вам понадобится немногознание теории парсеров.Я бы порекомендовал заглянуть на сайт GOLD Parser , на котором есть некоторая теоретическая информация, а также некоторые инструменты, которые помогут вам настроить свои собственные языковые правила.На сайте доступна реализация Delphi.

1 голос
/ 24 марта 2010

Вы можете посмотреть на Tcl.Это было его первоначальной целью - стать инструментом языка командных инструментов, который вы могли бы встроить в другую программу.Tcl предоставляет синтаксис языка с переменными и управляющими структурами (циклами и т. Д.).Вы бы добавили команды и функции tcl для доступа к функциям вашей программы.

...