Программа–распознаватель арифметических выражений
Оглавление
Введение
. Теоретическая часть
.1 История разработки вопроса разбора математических
выражений
.2 Обратная польская нотация
.3 Вычисления на стеке
.4 Преобразование из инфиксной нотации
. Практическая часть
.1 Постановке задачи
.2 Описание входного языка
.3 Описание выходной информации
.4 Алгоритмические аспекты программы
.5 Алгоритм программы
.7 Работа с программой
Заключение
Литература
Приложение
Введение
Мы все знаем, что такое математическое выражение. Это формула. Формулы
встречаются повсеместно в экономике, физике, биологии, и, конечно же, в
математике. В общем, везде, где нужно символически представить какую-нибудь
функцию или соотношение. Символическое представление, конечно, не единственное.
Можно представить выражение в виде графика, или таблицы. Но все же формула
является самым компактным и универсальным способом.
В данной курсовой работе будет разработана программа, которая
продемонстрирует способ распознавания компьютером введённых пользователем
математических формул.
Цель данной работы - разработать программу распознавания математических
формул.
Для достижения цели необходимо выполнить следующие задачи:
1. Изучить теоретический материал по предмету.
2. Разработать концепцию реализации программы.
. Реализовать программу на языке программирования Delphi 7.
. Составить пояснительную записку.
1.
Теоретическая часть
.1 История
разработки вопроса разбора математических выражений
Существуют три вида записи выражений:
. инфиксная форма, в которой оператор расположен между операндами (например,
"а + b");
. постфиксная форма, в которой оператор расположен после операндов
("а b + ");
. префиксная форма, в которой оператор расположен перед операндами
("+ а b").
Постфиксная и префиксная формы образуют т.н. польскую форму записи
(польская нотация). Польская форма удобна, прежде всего, тем, что в ней
отсутствуют скобки.
Обратная польская нотация была разработана австралийским философом и
специалистом в области теории вычислительных машин Чарльзом Хэмблином в
середине 1950-х на основе польской нотации, которая была предложена в 1920 году
польским математиком Яном Лукасевичем. Работа Хэмблина была представлена на
конференции в июне 1957, и издана в 1957 и 1962.
Первыми компьютерами, поддерживающими обратную польскую нотацию были KDF9
от English Electric Company, который был анонсирован в 1960 и выпущен (появился
в продаже) в 1963, и американский Burroughs B5000, анонсирован в 1961, выпущен
в том же 1963. Один из проектировщиков B5000, Р. С. Бартон, позже написал, что
разработал обратную польскую запись назависимо от Хэмблина, примерно в 1958, в
процессе чтения книги по символьной логике, и до того как познакомился с
работой Хэмблина.
Компания Friden перенесла ОПН в настольные калькуляторы, выпустив в июне
1964 модель EC-130. А в 1968 инженеры Hewlett-Packard разработали настольный
калькулятор 9100A с поддержкой ОПН. Этот калькулятор сделал обратную польскую
нотацию популярной среди учёных и инженеров, даже несмотря на то, что в ранней
рекламе 9100A ОПН не упоминалась. В 1972 калькулятор HP-35 с поддержкой ОПН
стал первым научным карманным калькулятором.
В 1971 году появился оригинальный язык программирования Forth, языковая
машина которого имеет двухстековую структуру и где все вычисления проводятся на
стеке. В этом языке ОПН является естественным способом записи любых операций с
данными, хотя возможна, при желании, реализация и обычной (инфиксной) записи
арифметических операций.
ОПН применялась в советском инженерном калькуляторе Б3-19М (совместная
разработка с ГДР), выпущенном в 1976 году. Все выпускаемые в СССР вплоть до
конца 1980-х годов программируемые микрокалькуляторы, за исключением
«Электроника МК-85», использовали ОПН - она проще реализовывалась и позволяла
обойтись в программировании вычислений меньшим числом команд, по сравнению с
обычной алгебраической нотацией, а количество программной памяти в этих моделях
всегда было критическим ресурсом (не более 105 ячеек, при том, что команда
занимала 1-2 ячейки). ОПН используется в современных российских программируемых
калькуляторах «Электроника МК-152» и «ЭЛЕКТРОНИКА МК-161», что обеспечивает их
совместимость с программами, написанными для советских калькуляторов.
.2 Обратная
польская нотация
Отличительной особенностью обратной польской нотации является то, что все
аргументы (или операнды) расположены перед знаком операции. В общем виде запись
выглядит следующим образом:
· Запись набора операций состоит из последовательности операндов и знаков
операций. Операнды в выражении при письменной записи разделяются пробелами.
· Выражение читается слева направо. Когда в выражении
встречается знак операции, выполняется соответствующая операция над двумя
последними встретившимися перед ним операндами в порядке их записи. Результат
операции заменяет в выражении последовательность её операндов и её знак, после
чего выражение вычисляется дальше по тому же правилу.
· Результатом вычисления выражения становится результат
последней вычисленной операции.
Например, рассмотрим вычисление выражения 7 2 3 * - (эквивалентное
выражение в инфиксной нотации: 7-2*3).
· Первый по порядку знак операции - «*», поэтому первой выполняется
операция умножения над операндами 2 и 3 (они стоят последними перед знаком).
Выражение при этом преобразуется к виду 7 6 - (результат умножения - 6, -
заменяет тройку «2 3 *»).
· Второй знак операции - «-». Выполняется операция вычитания
над операндами 7 и 6.
· Вычисление закончено. Результат последней операции равен 1,
это и есть результат вычисления выражения.
Очевидное расширение обратной польской записи на унарные, тернарные и
операции с любым другим количеством операндов: при использовании знаков таких
операций в вычислении выражения операция применяется к соответствующему числу
последних встретившихся операндов.
Особенности обратной польской записи следующие:
· Порядок выполнения операций однозначно задаётся порядком следования
знаков операций в выражении, поэтому отпадает необходимость использования
скобок и введения приоритетов и ассоциативности операций.
· В отличие от инфиксной записи, невозможно использовать одни и
те же знаки для записи унарных и бинарных операций. Так, в инфиксной записи
выражение 5 * (-3 + 8) использует знак «минус» как символ унарной операции
(изменение знака числа), а выражение (10 - 15) * 3 применяет этот же знак для
обозначения бинарной операции (вычитание). Конкретная операция определяется
тем, в какой позиции находится знак. Обратная польская запись не позволяет
этого: запись 5 3 - 8 + * (условный аналог первого выражения) будет
интерпретирована как ошибочная, поскольку невозможно определить, что «минус»
после 5 и 3 обозначает не вычитание; в результате будет сделана попытка
вычислить сначала 5 - 3, затем 2 + 8, после чего выяснится, что для операции
умножения не хватает операндов. Чтобы всё же записать это выражение, придётся
либо переформулировать его, либо ввести для операции изменения знака отдельное
обозначение, например, «±»: 5 3 ± 8 + *.
· Так же, как и в инфиксной нотации, в ОПН одно и то же
вычисление может быть записано в нескольких разных вариантах. Например,
выражение (10 - 15) * 3 в ОПН можно записать как 10 15 - 3 *, а можно - как 3
10 15 - *
· Из-за отсутствия скобок обратная польская запись короче
инфиксной. За этот счёт при вычислениях на калькуляторах повышается скорость
работы оператора (уменьшается количество нажимаемых клавиш), а в
программируемых устройствах сокращается объём тех частей программы, которые
описывают вычисления. Последнее может быть немаловажно для портативных и
встроенных вычислительных устройств, имеющих жёсткие ограничения на объём
памяти.
.3 Вычисления
на стеке
Автоматизация вычисления выражений в обратной польской нотации основана
на использовании стека. Алгоритм вычисления для стековой машины элементарен:
1. Обработка входного символа.
2. Если на вход подан операнд, он помещается на вершину стека.
. Если на вход подан знак операции, то соответствующая операция
выполняется над требуемым количеством значений, извлечённых из стека, взятых в
порядке добавления. Результат выполненной операции кладётся на вершину стека.
. Если входной набор символов обработан не полностью, перейти к шагу
1.
. После полной обработки входного набора символов результат
вычисления выражения лежит на вершине стека.
Реализация стековой машины, как программная, так и аппаратная,
чрезвычайно проста и может быть очень эффективной. Обратная польская запись
совершенно унифицирована - она принципиально одинаково записывает унарные,
бинарные, тернарные и любые другие операции, а также обращения к функциям, что
позволяет не усложнять конструкцию вычислительных устройств при расширении
набора поддерживаемых операций. Это и послужило причиной использования обратной
польской записи в некоторых научных и программируемых микрокалькуляторах.
.4
Преобразование из инфиксной нотации
Эдсгер Дейкстра изобрёл алгоритм для преобразования выражений из
инфиксной нотации в ОПН. Алгоритм получил название «сортировочная станция», за
сходство его операций с происходящим на железнодорожных сортировочных станциях.
Инфиксная нотация - это форма математических записей, которую использует
большинство людей (например, 3 + 4 или 3 + 4 * (2 - 1)). Как и алгоритм
вычисления ОПН, алгоритм сортировочной станции основан на стеке. В
преобразовании участвуют две текстовых переменных: входная и выходная строки. В
процессе преобразования используется стек, хранящий ещё не добавленные к
выходной строке операторы. Преобразующая программа читает входную строку
последовательно символ за символом (символ - это не обязательно буква),
выполняет на каждом шаге некоторые действия в зависимости от того, какой символ
был прочитан.
Алгоритм
* Пока есть ещё символы для чтения:
* Читаем очередной символ.
* Если символ является числом, добавить его к выходной строке.
* Если символ является символом функции, помещаем его в стек.
* Если символ является открывающей скобкой, помещаем его в стек.
* Если символ является закрывающей скобкой:
До тех пор, пока верхним элементом стека не станет открывающая скобка,
выталкиваем элементы из стека в выходную строку. При этом открывающая скобка
удаляется из стека, но в выходную строку не добавляется. Если после этого шага
на вершине стека оказывается символ функции, выталкиваем его в выходную строку.
Если стек закончился раньше, чем мы встретили открывающую скобку, это означает,
что в выражении либо неверно поставлен разделитель, либо не согласованы скобки.
* Если символ является оператором о1, тогда:
) пока…
… (если оператор o1 ассоциированный, либо лево-ассоциированный) приоритет
o1 меньше либо равен приоритету оператора, находящегося на вершине стека…
… (если оператор o1 право-ассоциированый) приоритет ''''' меньше
приоритета оператора, находящегося на вершине стека…
… выталкиваем верхние элементы стека в выходную строку;
* Когда входная строка закончилась, вытолкнуть все символы из стека в
выходную строку. В стеке должны были остаться только символы операторов; если
это не так, значит в выражении не согласованы скобки.
2.
Практическая часть
.1 Постановке
задачи
В рамках данного курсового проекта необходимо разработать программу -
распознаватель арифметических выражений. Для эффективной организации процесса
разработки и получения удовлетворительного результата мною были определены
следующие требования к программе:
1. Программа должна получать входную информацию в виде строки
арифметического выражения, представленного на обычном математическом языке.
2. Программа должна уметь различать приоритетность входных
арифметических операций.
. Программа должна уметь вычислять сложные выражения, содержащие в
себе несколько математических операторов.
. Программ должна вычислять результат введённого математического
выражения.
. Программа должна демонстрировать пользователю этапы выполняемых
ею математических операций и промежуточные результаты данных вычислений.
. Программа должна выполняться под управление ОС Windows.
.2 Описание
входного языка
Программа разработана в соответствии со следующей спецификацией входной
информации:
Входная информация - строка символов, являющаяся правильным
математическим выражением, содержащая операнды и операторы.
Набор операторов входного языка приведён в следующей таблице:
Таблица
1
Операторы
входного языка
№
|
Обозначение в программе
|
Математическое обозначение
|
Функция
|
Правила использования
|
1. 1
|
+
|
+
|
Сложение
|
Складывает два операнда
находящиеся справа и слева от оператора.
|
2. 2
|
-
|
-
|
Вычитание
|
Вычитает из операнда
находящегося слева из операнда, находящегося справа от оператора.
|
3.
|
*
|
*
|
Произведение
|
Умножает два операнда
находящиеся справа и слева от оператора.
|
4.
|
/
|
:
|
Частное
|
Делит операнд, находящейся
слева, на операнд, находящейся справа от оператора.
|
5.
|
^
|
ОснованиеСтепень
|
Степень
|
Возводит операнд,
находящийся слева, в степень по операнду, находящемуся справа от оператора
|
Набор символов входного языка, составляющих операнды, представлен в
следующей таблице:
Таблица
2
Символы
входного языка
№
|
Обозначение в программе
|
Математическое обозначение
|
Наименование
|
1.
|
1
|
1
|
Один
|
2.
|
2
|
2
|
Два
|
3.
|
3
|
3
|
Три
|
4.
|
4
|
4
|
Четыре
|
5.
|
5
|
5
|
Пять
|
6
|
6
|
Шесть
|
7.
|
7
|
7
|
Семь
|
8.
|
8
|
8
|
Восемь
|
9.
|
9
|
9
|
Девять
|
10.
|
0
|
0
|
Ноль
|
программа
распознаватель арифметический выражение
2.3 Описание
выходной информации
Выходной информацией данной программы являются следующие данные:
1. Дерево разбора.
2. Результаты промежуточных вычислений.
. Конечный результат.
Дерево разбора представляет собой отображение структуры дерева в
табличном виде, для связи родительских веток с дочерними используются
специального вида ссылки.
Результаты промежуточных вычислений представляют собой результаты
примитивных математических операций, выполняющихся в пределах одного узла
дерева разбора.
Конечный результат представляет собой итог всех операций и является
результатом вычисления арифметического выражения.
.4
Алгоритмические аспекты программы
Алгоритм программы представляет собой соединение двух алгоритмов:
1. Построение дерева разбора.
2. Построение выражение по принципу польской префиксной записи.
Первый алгоритм представляет собой построение дерева, представленного в
табличном виде, по принципу разности приоритета используемых во входном
выражении операндов.
Приоритеты операндов показаны в таблице 3.
Таблица
3
Приоритеты
операндов
№
|
Операнд
|
Наименование
|
Приоритет выполнения
|
1.
|
+
|
Сложение
|
1
|
2.
|
-
|
Вычитание
|
1
|
3.
|
*
|
Произведение
|
2
|
4.
|
/
|
Деление
|
2
|
5.
|
^
|
Степень
|
3
|
Кроме того, в набор языка вводиться новый операнд, представляющий цифру,
обозначенную с двух сторон кавычками. Данный оператор обозначает ссылку на
выражение и символизирует результат вычисления данного выражения. Данный
оператор используется во второй части алгоритма в качестве оператора при записи
выражения в виде польской префиксной записи.
2.5 Алгоритм
программы
Алгоритм программы представлен следующей схемой:
Рисунок
1 - Алгоритм программы
Рисунок
2 - Алгоритм программы
Рисунок
3 - Алгоритм программы
Рисунок
4 - Алгоритм программы
Рисунок
5 - Алгоритм программы
Рисунок
7 - Алгоритм программы
2.7 Работа с
программой
Разработанная программа не требует инсталляции. Для её запуска достаточно
запустить исполнимый файл. Вид программы предстален на рисунке.
Рисунок
8 - Окно программы.
Верхнее
поле предназначено для ввода арифметического выражения.
Рисунок
9 - Введено выражение.
Для
запуска процесса распознавания нажмите кнопку выполнить. Программа заполнит
дерево разбора узлами с информацией в виде префиксной записи и список
промежуточных результатов. В нижнем поле будет результат выражения.
Рисунок
10 - Выполненная программа.
Чтобы
очистить поля программы нажмите кнопку очистить.
Заключение
В результате работы была разработана программа, реализующая алгоритм
разбора арифметического выражения, используя классические конструкции обратной
польской нотации. Данная программа демонстрирует правила разбора выражения при
помощи построения дерева разбора, с последующим вычислением выражения с выводом
промежуточных результатов. Тестирование программы показало правильность её
работы, а простота интерфейса - даёт удобство в использовании.
В процессе работы над программой мною были изучены следующие темы:
Правила создания бинарных деревьев.
Правила преобразования инфиксной записи в польскую обратную нотацию.
Литература
1. А. В.
Ахо, Р. Сети, Д. Д. Ульман. Компиляторы: принципы, технологии и инструменты.
М.: «Вильямс», 2003.
2. Компаниец
Р.И. и др. Системное программирование.Основы построения трансляторов.- СПб.:
КОРОНА принт, 2000.-256 с.
3. Компаниец
Р.И., Маньков Е.В., Филатов Н.Е. Основы построения трансляторов. -СПб.: КОРОНА
принт, 2000. -256 с.
4. Хантер
Р. Проектирование и конструирование компиляторов. М.: Финансы и статистика.
1984 г.
. Грис
Д. Конструирование компиляторов для цифровых вычислительных машин. М.: Мир,1975
г.
. Иртегов
Д. Введение в операционные системы. Учебное пособие. - СПб.: БХВ-Петербург,
2002. - 624 с.
. Молчанов
А.Ю. Системное программное обеспечение. Лабораторный практкум.- СПб.: Питер,
2005.- 284 с.
. Юров
В.И. Assembler. Учебник для вузов. 2-е издание - СПб.: Питер.- 2004.- 637 с.
. Компаниец
Р.И., Маньков Е.В., Филатов Н.Е. Системное программирование: Основы построения
трансляторов + FD.- М.: КОРОНА принт.- 2004.- 255 с.
. Молчанов
А.Ю. Системное программное обеспечение. Лабораторный практикум. - СПб.: Питер,
2005. - 284 с.
. Юров
В.И. Assembler. Учебник для вузов. 2-е изд. - СПб: Питер, 2004. - 637 с.
. Ахо
А., Ульман Дж. Теория синтаксического анализа, перевода и компиляции. - М.:Мир,
1978. - Т.1, 612 с. Т. 2, 487 с.
. Ахо
А.,Сети Р., Ульман Дж. Компиляторы: принципы, технологии и инструменты: Пер. с
англ. - М.: Издательский дом «Вильямс», 2003. - 768 с.
. Гордеев
А.В., Молчанов А.Ю. Системное программное обеспечение. - СПб.: Питер, 2002. -
734 с.
. Компаниец
Р.И., Маньков Е.В., Филатов Н.Е. Системное программирование. Основы построения
трансляторов: Учебное пособие для высших средних учебных заведений. -
СПб:КОРОНА принт, 2000. - 256 с.
. Гордеев
А.В. Опреационные системы: Учебник для вузов. 2-е изд. - СПб.: Питер, 2004. -
416 с.
Приложение
Листинг программыUnit1;
interface
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms,
Dialogs, StdCtrls, math;
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Memo2: TMemo;
Label3: TLabel;
Button2: TButton;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
Form1: TForm1;
st,op1,op2:string;
mtxi,mtxpr:integer;
mtx:array of string;
{$R *.dfm}is_num(a:string):boolean;
if ((a='"') or (a='0') or (a='1') or (a='2') or (a='3')
or (a='4') or (a='5') or (a='6') or (a='7') or (a='8') or (a='9'))
then is_num:=true
else is_num:=false;;
TForm1.Button1Click(Sender:
TObject);i,j,fl,m,l:integer;:string;:=form1.Edit1.Text;:=0;
memo1.Lines.Add('');
fl:=1;
if (pos('^',st)>0) then
begin
fl:=0;
memo1.Lines[m]:=memo1.Lines[m]+'^ ';
i:=pos('^',st);
j:=i+1;
ss:='';
while is_num(st[i]) do
begin
ss:=ss+st[i];
i:=i-1;
end;
for l:=length(ss) downto 0 do
memo1.Lines[m]:=memo1.Lines[m]+ss[l];
memo1.Lines[m]:=memo1.Lines[m]+' ';
while is_num(st[j]) do
begin
memo1.Lines[m]:=memo1.Lines[m]+st[j];
j:=j+1;
end;
delete(st,i+1,j-i-1);
insert('"'+inttostr(m)+'"',st,i+1);
edit1.text:=st;
m:=m+1;
end;fl=1;
memo1.Lines.Add('');
fl:=1;
if (pos('*',st)>0) then
begin
fl:=0;
memo1.Lines[m]:=memo1.Lines[m]+'* ';
i:=pos('*',st);
j:=i+1;
i:=i-1;
ss:='';
while is_num(st[i]) do
begin
ss:=ss+st[i];
i:=i-1;
end;
for l:=length(ss) downto 0 do
memo1.Lines[m]:=memo1.Lines[m]+ss[l];
memo1.Lines[m]:=memo1.Lines[m]+' ';
while is_num(st[j]) do
begin
memo1.Lines[m]:=memo1.Lines[m]+st[j];
j:=j+1;
end;
delete(st,i+1,j-i-1);
insert('"'+inttostr(m)+'"',st,i+1);
edit1.text:=st;
m:=m+1;
end;fl=1;
memo1.Lines.Add('');
fl:=1;
if (pos('/',st)>0) then
begin
fl:=0;
memo1.Lines[m]:=memo1.Lines[m]+'/ ';
i:=pos('/',st);
j:=i+1;
i:=i-1;
ss:='';
while is_num(st[i]) do
begin
ss:=ss+st[i];
i:=i-1;
end;
for l:=length(ss) downto 0 do
memo1.Lines[m]:=memo1.Lines[m]+ss[l];
memo1.Lines[m]:=memo1.Lines[m]+' ';
while is_num(st[j]) do
begin
memo1.Lines[m]:=memo1.Lines[m]+st[j];
j:=j+1;
end;
delete(st,i+1,j-i-1);
insert('"'+inttostr(m)+'"',st,i+1);
edit1.text:=st;
end;fl=1;
memo1.Lines.Add('');
fl:=1;
if (pos('+',st)>0) then
begin
fl:=0;
memo1.Lines[m]:=memo1.Lines[m]+'+ ';
i:=pos('+',st);
j:=i+1;
i:=i-1;
ss:='';
while is_num(st[i]) do
begin
ss:=ss+st[i];
i:=i-1;
end;
for l:=length(ss) downto 0 do memo1.Lines[m]:=memo1.Lines[m]+ss[l];
memo1.Lines[m]:=memo1.Lines[m]+' ';
while is_num(st[j]) do
begin
memo1.Lines[m]:=memo1.Lines[m]+st[j];
j:=j+1;
end;
delete(st,i+1,j-i-1);
insert('"'+inttostr(m)+'"',st,i+1);
edit1.text:=st;
m:=m+1;
end;fl=1;
memo1.Lines.Add('');
fl:=1;
if (pos('-',st)>0) then
begin
fl:=0;
memo1.Lines[m]:=memo1.Lines[m]+'- ';
i:=pos('-',st);
j:=i+1;
i:=i-1;
ss:='';
while is_num(st[i]) do
begin
ss:=ss+st[i];
i:=i-1;
end;
for l:=length(ss) downto 0 do
memo1.Lines[m]:=memo1.Lines[m]+ss[l];
memo1.Lines[m]:=memo1.Lines[m]+' ';
while is_num(st[j]) do
begin
memo1.Lines[m]:=memo1.Lines[m]+st[j];
j:=j+1;
end;
delete(st,i+1,j-i-1);
insert('"'+inttostr(m)+'"',st,i+1);
edit1.text:=st;
m:=m+1;
end;fl=1;
memo1.Lines[memo1.Lines.Count-1]='' do
memo1.Lines.Delete(memo1.Lines.Count-1);
.Lines:=memo1.Lines;
i:=0 to memo2.Lines.Count do
if ((length(memo1.Lines[i])<>0)) then
st:=memo1.Lines[i];
case st[1] of
'^':begin
delete(st,1,2);
if (st[1]='"') then
begin
op1:=memo2.Lines[strtoint(st[2])];
delete(st,1,4);
end
else
op1:=copy(st,1,pos(' ',st));
delete(st,1,pos(' ',st));
end;
if (st[1]='"') then
begin
op2:=st[2]; memo2.Lines[strtoint(st[2])];
edit2.text:=op2;
end
else
begin
op2:=st;
end;
memo2.Lines[i]:=floattostr(Power(strtofloat(op1),strtofloat(op2)));
end;
'*':begin
delete(st,1,2);
if (st[1]='"') then
begin
op1:=memo2.Lines[strtoint(st[2])];
delete(st,1,4);
end
else
begin
op1:=copy(st,1,pos(' ',st));
delete(st,1,pos(' ',st));
end;
if (st[1]='"') then
begin
op2:=st[2]; memo2.Lines[strtoint(st[2])];
edit2.text:=op2;
end
else
begin
op2:=st;
end;
memo2.Lines[i]:=floattostr(strtofloat(op1)*strtofloat(op2));
end;
'+':begin
delete(st,1,2);
if (st[1]='"') then
begin
op1:=memo2.Lines[strtoint(st[2])];
delete(st,1,4);
end
else
begin
op1:=copy(st,1,pos(' ',st));
delete(st,1,pos(' ',st));
end;
if (st[1]='"') then
begin
op2:=memo2.Lines[strtoint(st[2])];
memo2.Lines[strtoint(st[2])];
end
else
begin
op2:=st;
end;
memo2.Lines[i]:=floattostr(strtofloat(op1)+strtofloat(op2));
end;
end;
edit2.text:=memo2.Lines[memo2.Lines.count-1];;
;
TForm1.Button2Click(Sender:
TObject);.Text:='';.Text:='';.Lines.Clear;.Lines.Clear;
end;
.