Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.12.2010, 22:42   #1
Brabus
Пользователь
 
Регистрация: 25.09.2009
Сообщений: 81
По умолчанию интерпретатор выражений на delphi

Добрый вечер форумцы. Помогите пожалуйста с одной проблемой. Есть задача:

Вывести значение целочисленного выражения, заданного в виде строки S. Выражение определяется следующим образом:
<выражение> ::= <терм> | <выражение> + <терм> |
<выражение> – <терм>
<терм> ::= <цифра> | <терм> * <цифра>

Есть её решение:

Код:
unit FormMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TfrmMain = class(TForm)
    edExpression: TLabeledEdit;
    edResult: TLabeledEdit;
    btnCuclulate: TButton;
    btnClear: TButton;
    btnExit: TButton;
    procedure btnExitClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
    procedure edExpressionChange(Sender: TObject);
    procedure edExpressionKeyPress(Sender: TObject; var Key: Char);
    procedure btnCuclulateClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnExitClick(Sender: TObject);
begin
  Close
end;

procedure TfrmMain.btnClearClick(Sender: TObject);
begin
  edExpression.Clear;
end;

procedure TfrmMain.edExpressionChange(Sender: TObject);
begin
  edResult.Clear
end;

{При нажатии на клавиши контролируем их доступность}
procedure TfrmMain.edExpressionKeyPress(Sender: TObject; var Key: Char);
begin
  {если символ недопустим, то отменяем его}
  if not (Key in [#0..#31, ' ', '0'..'9', '+', '-','*']) then
    Key:=#0;
end;

{Функция, которая вычисляет выражение
  str - строка, которая содержит выражение
  Value - значение, которое будет получено в результате вычислений
 Функция возвращает true - если выражение было заданно корректно и его смогли
 посчитать, в противном случае false}
function Calculate (const str : string; var Value : integer) : boolean;

var i : integer; // переменная, которая двигается по строке слева направо

procedure SkipSpaces (var i : integer);
begin
  while (i>=1) and (str[i]=' ') do i:=i-1;
end;

{распознавание терма}
function Term (var i : integer; var value : integer) : boolean;
var
  t : integer;
begin
  SkipSpaces(i);
  {Если выскочили за границу, то это ошибка}
  if i=0 then
    Result:=false
  {в противном случае}
  else
    {если символ не цифра, то ошибка}
    if not (str[i] in ['0'..'9']) then
      Result:=false
    else
      begin
        // запоминаем цифру
        value:=ord(str[i])-ord('0');
        {сдвигаемся влево на один символ}
        i:=i-1;
        SkipSpaces(i);
        {если не выскочили за границу и символ '*'}
        if (i>=1) and (str[i]='*') then
          begin
            {сдвигаемся влево на один символ}
            i:=i-1;
            {и пытемся опять считать терм}
            Result:=Term(i, t);
            {если терм распознан корректно, то выполняем умножение}
            if Result then
              value:=t*Value;
          end;
      end;
end;


{распознавание выражения}
function Expression (var i : integer; var value : integer) : boolean;
var
  t : integer;
  sign : char;  // знак операции
begin
  {пропускаем пробелы}
  SkipSpaces(i);
  {Если выскочили за границу, то это ошибка}
  if i=0 then
    Result:=false
  else
    {пытаемся взять терм, если неудачно, то ошибка}
    if not Term(i, value) then
      Result:=false
    {в противном случае}
    else
      begin
        Result:=true;
        {пропускаем пробелы}
        SkipSpaces(i);
        {если не выскочили за границу }
        if (i>=1) then
          {если символ не '+' и не '-'}
          if not (str[i] in ['+','-']) then
            Result:=false
          else
            begin
              {запоминаем знак}
              sign:=str[i];
              {сдвигаемся влево на один символ}
              i:=i-1;
              {и пытемся опять считать выражение}
              Result:=Expression(i, t);
              {если выражение распознано корректно, то выполняем операцию в зависимости от знака}
              if Sign='+' then
                value:=t+Value
              else
                value:=t-Value;
            end;
      end;
end;

begin
  {Становимся на последний символ строки}
  i:=length(str);
  {Пытаемся распознать выражение}
  Result:=Expression(i, value);
  {Результат только в  том случае хороший, если дошли до начала строки}
  Result:=(i=0);
end;

{при нажатии на кнопку "Посчитать"}
procedure TfrmMain.btnCuclulateClick(Sender: TObject);
var val : integer;
begin
  // если посчитать удалось, то выводим результат вычислений,
  if Calculate(edExpression.Text, val) then
    edResult.Text:=IntToStr(val)
  // иначе сообщение обошибке
  else
    edResult.Text:='Ошибка в выражении'
end;

end.
Нужно сделать так чтобы еще интерпретатор умел читать скобки (с приоритетом). Помогите пожалуйста, если не трудно
Brabus вне форума Ответить с цитированием
Старый 16.12.2010, 11:03   #2
Z1000000
Форумчанин
 
Регистрация: 04.05.2010
Сообщений: 495
По умолчанию

Возьми нормальную грамматику без левой рекурсии.
И по книге Ахо "Компиляторы" напиши. Там уже и коды есть на C, переделай.
Изображения
Тип файла: jpg parser.jpg (118.4 Кб, 154 просмотров)
Нажми на весы, поставь +
Для благодарностей : WebMoney WMR R252732729948
Z1000000 вне форума Ответить с цитированием
Старый 16.12.2010, 12:30   #3
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
И по книге Ахо "Компиляторы" напиши.
Есть книга Креншоу - там на паскале... написано очень просто.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 16.12.2010, 21:29   #4
Brabus
Пользователь
 
Регистрация: 25.09.2009
Сообщений: 81
По умолчанию

ды мне бы просто чтобы эта прога скобки читала. сдавать завтра
Brabus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Интерпретатор FALSE Granus Софт 2 13.08.2010 11:37
Разбор выражений.Delphi novi4ok_Delphi Помощь студентам 3 18.05.2010 17:51
Интерпретатор Volkodav2411 Фриланс 6 04.02.2010 21:17
Вычисление арифметических выражений.(delphi) КуДрЯ Помощь студентам 3 02.04.2009 02:54
Интерпретатор Паскаля SvetickPro Помощь студентам 1 17.10.2008 22:00