Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Pascal] правильность написания арифметических выражений


Автор: bigmaik 31.1.2012, 05:25
Помогите создать программу которая будет проверять правильность написания арифметических выражений

Автор: volvo877 31.1.2012, 19:37
Своих наработок нет - значит, переезжаем...

Автор: volvo877 31.1.2012, 19:37
Для домашних заданий, курсовых, существует "Центр Помощи".

Тема перенесена! 

Автор: bigmaik 1.2.2012, 05:16
Надеюсь это поможет решению)

Автор: Mirkes 1.2.2012, 07:15
Вообще-то лень поощрять нельзя.
Это просто перевод того, что вы уже видели
Код

Program CTranslated;

Var
  Expression: String; //static char *current_char, *start;
  Curr: Integer; // Аналог current_char
  CH: Char; // Второй аналог. В паскале нет макросов. Придется определять ручками #define CH (*current_char)
  
Procedure GCH; // заносит в CH очередной символ #define GCH current_char++
Begin
  Inc(Curr);   // Это их ++
  If Curr<=Length(Expression) Then CH:=Expression[Curr]
  Else CH:=#0; // Имитируем Null Terminated строку!
End;

Procedure Ae1; Forward;// Упреждающее описание процедуры void ae1();

Procedure IntegerProc; //void integer()
Begin //{
  While Pos(CH,'0123456789')>0 Do //  while (isdigit(CH))
    GCH;//    GCH;
End; //}

Procedure Variable; //void variable()
Begin //{
  // А вот здесь наверное ошибка, но не уверен. Не знаю что возвращает isalpha(CH). Понимает ли она цифры?
  While (Pos(CH,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789')>0)  Do //while (isalpha(CH))
    GCH;//    GCH;
  If CH='[' Then //  if (CH == '[') {
    Repeat //    do {
      GCH;//      GCH;
      Ae1; //      ae1();
    Until CH<>',';//    } while (CH == ',');

  If CH=']' Then //    if (CH == ']')
    GCH//      GCH;
  Else Begin //    else {
    WriteLn('Ошибка около ',Curr,' буквы ');//    printf("Ошибка около %d буквы", current_char - start);
    Halt(1); // exit(1);
  End; //  }
// ?    }
End; //}

Procedure Operand; // void operand()
Begin //{
  If Pos(CH,'0123456789-')>0 Then //По моему здесь пролопухали отрицательное целое в начале выражения. Поправим  if (isdigit(CH)) {
    IntegerProc // Не хочется воевать с имененм типа. Сменим имя процедуры    integer();
// Не нужно        return;
// Не нужно    };

  Else If Pos(CH,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_')>0 Then // Вот здесь С в больших прлюсах! Интересно,
                                                                                 // а _ алфавитный символ? В именах переменных допускается   if (isalpha(CH)) {
    Variable //        variable();
// Не нужно        return;
// Не нужно    };

   Else Begin
    WriteLn('Ошибка около ',Curr,' буквы ');//    printf("Ошибка около %d буквы", current_char - start);
    Halt(1); // exit(1);
   End;
End; //}

Procedure Ae1; //void ae1()
Begin //{
  While True Do Begin // Можно конечно и с постусловием, но в этой ситуации безразлично   do {
     Operand; //   operand();
     If Pos(CH,'*/-+')>0 Then //  if (CH == '*' || CH == '/' || CH == '-' || CH == '+') {
       GCH//      GCH;
     // не нужно и в С       continue;
     Else //   } else
       Break //     break;
  End; //  } while (1);
// по моему это и в С не нужно    return;
End; //}

Procedure Validate(Expr: String);// void validate(char *expression)
Begin //{
  Expression:=Expr; //  current_char = expression;
  Curr:=0;          //  start = expression;
  GCH;              // Это к предыдущей строке.
  Ae1;              //  ae1();
  If CH<>#0  Then //if (CH != '\0')
    WriteLn('Ошибка около ',Curr,' буквы ');//    printf("Ошибка около %d буквы",
//               current_char - start);
End;//}

Begin //int main()
//{
  Validate('2+4/2+1+1+3+2+3*1/3');//  validate("2+4/2+1+1+3+2+3*1/3");
  WriteLn('Все верно');
// Не надо    return 0;
End. //}


Автор: bigmaik 1.2.2012, 07:46
что то не очень получается... программа компилируется и компилируется...(((

вот какая наработка у меня есть... но там не учитывается то что нельзя делить на 0.

const digits : set of char=['0'..'9'];
letters:set of char=['_','A'..'Z','a'..'z'];
op : set of char=['+','-','*','/'];
var s : string;
i,k : word;
state : 0..3;
procedure error;
begin
writeln('Выражение некорректно'); halt
end;
procedure Identifier; {пропустить имя}
begin
while (i<length(s)) and
(s[i+1] in (letters+digits)) do i:=i+1
end;
procedure Number; {пропустить число}
begin
while (i<length(s)) and
(s[i+1] in digits) do i:=i+1
end;
begin {Main}
readln(s);
i:=0;
k:=0;
state:=0;
while state<>3 do
case state of
0:if i<length(s) then
begin
i:=i+1;
if s[i]='(' then k:=k+1 else
if not (s[i] in (letters+digits))
then error else
begin
if s[i] in letters then Identifier
else if s[i] in digits then Number;
state:=1
end
end else state:=2;
1:if i<length(s) then
begin
i:=i+1;
if s[i]=')' then
begin
k:=k-1;
if k<0 then error
end
else
if s[i] in op then state:=0
else error
end else state:=2;
2:if (s[i] in(letters+digits+[')']))and(k=0) then
begin
writeln('Выражение корректно');
state:=3
end
else error
end {case}
end.

Автор: Mirkes 1.2.2012, 08:33
Во первых, приведеите код в порядок
Во вторых - используйте выделение кода
В третьих выражение 1/0 является ПРАВИЛЬНЫМ арифметическим выражением.
Другое дело, что результат вычисления - бесконечность.
Какой средой пользуетесь?
Я свой вариант отлаживал на PascalABC, поскольку вы заявили Паскаль, а не Delphi.

Автор: bigmaik 1.2.2012, 08:52
Дык я вот тоже PascalABC использую... буду разбираться.

Автор: Yuruslugi 9.4.2012, 11:55
Спасибо, за программу....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)