Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];

Вниз

Калькулятор   Найти похожие ветки 

 
DiamondShark ©   (2004-07-27 16:51) [200]


> И это при том, что грамматика Паскаля, в отличие, например,
> от грамматики Оберона, не полностью поддаётся формальному
> описанию :))

С этого места подробнее.


 
Григорьев Антон ©   (2004-07-27 16:53) [201]


> pasha_golub ©   (27.07.04 16:42) [198]
> Григорьев Антон ©   (27.07.04 16:40) [197]
> Ы-ы-ы, можно носом ткнуть?


if ... then
if ... then
 ...
else
 ...


В терминах формальной грамматики невозможно описать, относится ли else к первому if или ко второму.


 
pasha_golub ©   (2004-07-27 16:55) [202]

Ко второму. Почему не возможно?


 
calm ©   (2004-07-27 16:59) [203]


> Почему не возможно?

Попробуйте.


 
pasha_golub ©   (2004-07-27 17:01) [204]

calm ©   (27.07.04 16:59) [203]
Не могу. Но чувствую, что где-то подвох. И дело только в моем незнании. :0)


 
Григорьев Антон ©   (2004-07-27 17:07) [205]


> pasha_golub ©   (27.07.04 16:55) [202]
> Ко второму. Почему не возможно?


Потому что формальное описание синтаксиса if выглядит так:

<Условный оператор>:==if <Условие> then <Оператор> [else <Оператор>]

При этом <Условный оператор> - частный случай <Оператор>. Мы можем рассматривать внешний if как if без else, а внутренний - как if c else, или наоборот - оба этих варианта удовлетворяют указанному описанию. Возникает неоднозначность. Поэтому приходится вводить правило о том, что else относится к ближайшему if, не имеющему else, и это правило не описывается никакой грамматикой.

Это как в C/C++: выражение a+++b допустимо трактовать как (a++)+b и a+(++b). Не помню, какая из трактовок считается правильной, но суть в том, что формальные грамматики этого не описывают.

Проблема эта давно известная, и в разных языках её решают по-разному. Например, в Алголе просто запретили вложенный if, если он не является частью составного оператора. А в Обероне и многих других языках отказались от идеи составного оператора, и грамматика if выглядит следующим образом:

<Условный оператор>:==if <Условие> then <Список операторов>
[{elseif <Условие> then <Список операторов}]
endif


 
pasha_golub ©   (2004-07-27 17:09) [206]

Ну про С, я наслышан. А вот про Паскаль, так слышу в первый раз. Или не в первый, просто должного внимания не уделил.


 
Игорь Шевченко ©   (2004-07-27 17:17) [207]

Григорьев Антон ©   (27.07.04 16:53) [201]

http://www.moorecad.com/standardpascal/pascal.y :)


 
Юрий Зотов ©   (2004-07-27 17:28) [208]

> Григорьев Антон

> В терминах формальной грамматики невозможно описать, относится
> ли else к первому if или ко второму.

Неоднозначность устраняется, если точку с запятой (или иной оконечный символ) сделать обязательной принадлежностью самого оператора, а не разделителем в списке операторов.

if ... then
if ... then ... ;
else ... ; // else относится к первому if

if ... then
if ... then ...
else ... ; // else относится ко второму if

То есть, формальная грамматика все же позволяет описывать такие констпукции. Пусть непаскалевская, но все равно позволяет.


 
Григорьев Антон ©   (2004-07-27 17:37) [209]


> Юрий Зотов ©   (27.07.04 17:28) [208]


Не понял. То, что у тебя обозначено многоточием, тоже является оператором, поэтому тоже должно заканчиваться точкой с запятой. И тогда мы меняем шило на мыло - неоднозначность того, к чему относится else, заменяется на неоднозначность того, к чему относится точка с запятой. В С/C++ точка с запятой - это обязательная принадлежность оператора, а неоднозначность с if"ом остаётся.


> Игорь Шевченко ©   (27.07.04 17:17) [207]


Эта грамматика не реализуется конечным автоматом:

open_if_statement : IF boolean_expression THEN statement
| IF boolean_expression THEN closed_statement ELSE open_statement
;

пока анализатор не дойдёт до ELSE (или до того места, где должно быть ELSE, но его нет), он не сможет разобраться, требуется statement или closed_statement. Для разбора таких выражений требуется усложнённый вариант конечного автомата (не помню, как он называется).


 
Игорь Шевченко ©   (2004-07-27 17:40) [210]

Григорьев Антон ©   (27.07.04 17:37)


> Эта грамматика не реализуется конечным автоматом:


Она реализуется YACC"ом, может быть, этого достаточно ? :)
Кстати, в C та же самая запись оператора if, и точно так же else относится к последнему if.


 
Юрий Зотов ©   (2004-07-27 17:43) [211]

> Григорьев Антон ©   (27.07.04 17:37) [209]

> Не понял. То, что у тебя обозначено многоточием, тоже является
> оператором, поэтому тоже должно заканчиваться точкой с
> запятой.

Совершенно верно. И тогда в конце условного оператора в полном соответствии с формальным описанием будут идти две точки с запятой подряд - что и устраняет неоднозначность.


 
Murkt ©   (2004-07-27 17:46) [212]

>Меня, кстати, тоже интересует этот вопрос. GrayFace и Кулясищще пытаются доказать, что теория для написания калькулятора не нужна. А что хотите доказать вы?

А я хочу доказать, что у меня калькулятор лучше чем у Михея (Кулясища) и GrayFace, написанный за меньшее время ;)

Теория при написании очень желательна. ИМХО. Хотя свой калькулятор я написал без теории. Просто на написание нормального парсера, который делал, например, обратную польскую запись у меня ушло бы времени побольше. Хотя точно я не знаю, не пробовал, может получится быстро.


 
Anatoly Podgoretsky ©   (2004-07-27 19:01) [213]

Григорьев Антон ©   (27.07.04 17:07) [205]
Я сильно был обижен на Вирта, что не сделал такую конструкцию IF в Паскале.


 
Огромное Кулясищще ©   (2004-07-27 19:06) [214]

>А я хочу доказать, ... чем у Михея (Кулясища)

Давайте не будем загадывать.


 
Огромное Кулясищще ©   (2004-07-27 19:07) [215]

И кстати, "Врагу не сдаётся наш гордый Варяг!!!"

P.S.: "- Если идти все прямо да прямо, далеко не уйдешь..." (c) Маленький Принц


 
nikkie ©   (2004-07-27 19:40) [216]

>Огромное Кулясищще
разъясни, плиз, что за смысл ты вкладываешь в сей PS...


 
Anatoly Podgoretsky ©   (2004-07-27 19:44) [217]

Нормальные герои всегда идут в обход.


 
DiamondShark ©   (2004-07-27 20:19) [218]


> Anatoly Podgoretsky ©   (27.07.04 19:01) [213]
> Григорьев Антон ©   (27.07.04 17:07) [205]
> Я сильно был обижен на Вирта, что не сделал такую конструкцию
> IF в Паскале.

Он быстро исправился. В Модуле она уже была.


 
Огромное Кулясищще ©   (2004-07-27 21:01) [219]

>разъясни, плиз, что за смысл ты вкладываешь в сей PS...

Думай. Думай много.


 
Murkt ©   (2004-07-27 22:10) [220]

Огромное Кулясищще ©   (27.07.04 19:06) [214]
А смайлика никто и не заметил.


 
nikkie ©   (2004-07-27 22:20) [221]

>Думай. Думай много.
у меня думалка еще такая не отросла.

Он помолчал в раздумье, потом сказал:
    - Очень хорошо,  что ты дал мне ящик:  барашек будет там  спать  по
ночам.
    - Ну конечно.  И если ты будешь умницей,  я дам тебе веревку, чтобы
днем его привязывать. И колышек.
    Маленький принц нахмурился:
    - Привязывать? Для чего это?
    - Но ведь  если ты его  не привяжешь, он  забредет неведомо куда  и
потеряется.
    Тут мой друг опять весело рассмеялся:
    - Да куда же он пойдет?
    - Мало ли куда? Все прямо, прямо, куда глаза глядят.
    Тогда Маленький принц сказал серьезно:
    - Это не страшно, ведь  у меня там очень  мало места.
    И прибавил не без грусти:
    - Если идти все прямо да прямо, далеко не уйдешь...


думаю вот. явно где-то кому-то тесно. то ли мыслям в чьей-то голове, то ли операторам в чьей-то программе... но вот, что ты имел в виду, когда эту цитату вставлял?


 
Огромное Кулясищще ©   (2004-07-27 22:29) [222]

2 nikkie:

Отлично, электронный век даёт нам быстрый и удобный поиск.


 
nikkie ©   (2004-07-27 22:36) [223]

ну и ладно. не хочешь объяснять, не надо.
не будем отвлекаться от темы. ты собирался калькулятор написать.


 
Cobalt ©   (2004-07-27 23:18) [224]

Насчёт Else -  если поразмыслить, то он должен соответствовать последнему предстоящему if.

(if <усл1>
then
[if <усл2>
then
{if <усл3>
then
else (для 3-го) }
else (для 2-го)]
else (для 1-го))


И по другому никак не сделаешь - как же можно описать случай, когда количество else меньше кол-ва if?
ну, разве что считать, что последний else ссответствует  первому if, предпоследний else ссответствует  второму if и т.д.
Но это уже как-то не очень...


 
Юрий Зотов ©   (2004-07-27 23:45) [225]

> Cobalt ©   (27.07.04 23:18) [224]

> как же можно описать случай, когда количество else меньше
> кол-ва if?

Например, так:

if <усл1> then
 if <усл2> then
   if <усл3> then <оператор> ; ; ;   // Вот оно!
else (для 1-го) ;

Перед "Вот оно": первая точка с запятой завершает <оператор>, вторая - if <усл3>, а третья - if <усл2>.

То есть, достаточно сделать точку с запятой принадлежностью самого оператора (ведь if - тоже оператор). И все сразу получается, причем  строго по грамматике.


 
Сергей Суровцев ©   (2004-07-28 09:52) [226]

>Думкин ©   (27.07.04 09:08) [159]
>А вот передергивать не надо. Стыдно должно быть при таком
>коверкании. Речь не об этом, поэтому прочитай внимательно и
>остынь, о эльф лесной.

Почему нет? Ты сам обобщил, я лишь утверждаю что от этого намного больше пользы, чем вреда. А про эльфа - мне картинка понравилась, хотя Баромир получился лучше. :))

>И не надо про иные вечные. вопрос идет о вполне явном вечном >двигателе 1-го рода. Не надо, перед детьми не стыдно?

Надеюсь ты не о себе?..

>Рамиль ©   (27.07.04 09:15) [161]
>Отвечу за Думкина:) Нет никакой подмены понятий, "даровый"
>двигатель он и есть даровый. Классический вечный двигатель не
>должен черпать энергию из вне, будь то хоть природные явления
>или пресловутый эфир, которого не существует.

Очень даже есть. Изначально вечный двигатель - это устройство, работающее само по себе, без приложения к нему энергии тем, кто его создал. Но это не значит, что эта энергия берется "ниоткуда", это значит, что источник энергии доступен устройству напрямую, без посреднических услуг человека. И тогда этот двигатель (способный производить работу) ограничен только сроком службы деталей. То что Вы называете "классическим" - это не утопия, это болное безумие, оно невозможно по самому приведенному определению. Отсюда и подмена понятий - общее направление искусственно разделено на два, бредовому оставлено старое название, а реальному придумано новое. А сделано это чтобы в очередной раз доказать - классики не ошибаются, даже если они ошибаются.

>А на основе гравитации ни вечного, ни дарового двигателя не
>получится как на основе постоянного магнитного поля.

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

>Cobalt ©   (27.07.04 10:31) [177]
>1/3sin(3,1415926)
>результат - 0,333333333333333}{0,0523359562429438
>Почему у тебя результат - не число, а строка? что это ещё за
>варианты???

Это не просто калькулятор, а вероятностный калькулятор. Результат означает 0,333333333333333, ну в крайнем случае 0,0523359562429438 :))

>GrayFace   (27.07.04 16:02) [189]
><function>::=После имени идут либо скобки, либо число, либо
>функция, либо константа.

После имени функции ВСЕГДА и без всяких "либо" идет открывающая скобка.

И вообще - в военное время значение синуса может доходить до четырех.


 
Gero ©   (2004-07-28 09:55) [227]


> После имени функции ВСЕГДА и без всяких "либо" идет открывающая
> скобка.

function a;


 
Anatoly Podgoretsky ©   (2004-07-28 09:56) [228]

Так может ни к чему так мучиться, может сразу Result := Random;


 
Думкин ©   (2004-07-28 10:03) [229]

>  [226] Сергей Суровцев ©   (28.07.04 09:52)
> Почему нет? Ты сам обобщил, я лишь утверждаю что от этого
> намного больше пользы, чем вреда.

При таком подходе мы бы только и делали, что каждый раз изобретали палки заново. Именно об этом речь в этой ветке. И именно это я вкладывал в весь пост. Эксперементировать и что-то делать новое - кто ж против. Только вот что? Я могу заниматься триссекцией хоть до помутнения, равно как и удвоением куба. Но после ознакомления с опытом прежних людей и ознакомившись с их трудами - только в пьном виде. Или создам свою математику. Только создав, ибо в этой - ну никак. Конечно, синдром Кристобаля Хозеивича иногда находит на многих, но вполне заслужено получаем гнев Федора Симеоновича.

Про двигатели. Так вот то что вы пишите это совсем иное и вы подменяете понятия. И с подменнными понятиями набрасываетесь. Это верно?
Все-таки речь идет о том(у меня во всяком случае) что чел. создает "вечный двигун" и для доказательства его вечности (именно в первоначальном смысле - классическом) он использует теоритическую физику. Не свою заметьте, а ту в которой доказано, что сие нельзя. Я не против пусть строит и получает, только пусть обоснования ищет иные.
Нельзя в той математике что имеем получить 2+2=5, только поменяв понятие 4 на 5. Что вы с успехом и продемонстрировали заменив "вечный двигатель" на некое псевдо, и разведя говорильню.

Извиняюсь за резкость. Да, Боромир неплох. :)


 
Григорьев Антон ©   (2004-07-28 10:20) [230]


> Игорь Шевченко ©   (27.07.04 17:40) [210]
> Григорьев Антон ©   (27.07.04 17:37)
>
>
> > Эта грамматика не реализуется конечным автоматом:
>
>
> Она реализуется YACC"ом, может быть, этого достаточно ?
> :)


Перечитал дома учебник, вынужден признать свою неправоту. if в Паскале описывается грамматикой Бекуса-Наура и, следовательно, реализуется конечным автоматом.

Вот, кстати, ещё одна причина учить теорию: чтобы Игорь Шевченко не поймал на глупой ошибке :))

Подробный комментарий для тех, кого заинтересовал спор на эту тему. Рассмотрим упрощённый Паскаль, в котором из структурных операторов имеется только if. Грамматика для него в этом случае запишется следующим образом:

<Оператор>::=<Согласованное_выражение> | <Несогласованное_выражение>

<Согласованное_выражение>::=if <условие> then <Согласованное_выражение> else <Согласованное_выражение> | любое выражение, не содержащее if

<Несогласованное_выражение>::=if <Условие> then <Оператор> | if <Условие> then <Согласованное_выражение> else <Несогласованное_выражение>

Такая грамматика позволяет однозначно определить, к какому if относится else. Недостатки этой грамматики по сравнению с грамматикой Оберона (см. [205]) следующие:

1) Человеку разобраться в ней сложнее.

2) Конечный автомат, реализующий такую грамматику, имеет больше состояний и, следовательно, сложнее. Кроме того, при левостороннем разборе, типичном для компиляторов, терминальный символ if не позволяет анализатору определить, согласованное ли это выражение или нет, поэтому приходится вводить в автомат ещё одно состояние: "if, но неизвестно, какой", или реализовывать не левосторонний, а более сложный разбор.

3) В Паскале присутствуют и другие операторы, и возможны конструкции типа for ... do if ... then ... [else ...], поэтому для операторов for, while, with приходится тоже вводить согласованную и несогласованную форму, а это ещё больше усложняет грамматику, а вместе с ней и анализатор.

P.S. Кого заинтересовала эта тема, могу посоветовать книгу http://www.delphikingdom.com/asp/book.asp?BookID=63


 
GrayFace   (2004-07-28 10:25) [231]

>Выражение: 2e + 5e (именно так - с пробелами)
>Результат: 7 (!!!)
>Выражение: --23e--1
>Результат: 24
Нет. --23e--1=22. Очень странно, что FloatToStr("2e")=2 и FloatToStr("23e-")=23. Это они должны создавать exception, отсекая подобные случаи. Я сделаю проверку правильности чисел, но к алгоритму это не имеет отношения.

Юрий Зотов ©   (27.07.04 16:11) [190]
> GrayFace   (27.07.04 16:02) [189]
>Это не спецификация. В спецификации должны быть четко определены ВСЕ понятия языка,
>а у Вас нет даже определения числа. Вот, скажем, 5E - это число, или синтаксическая ошибка?
Я описал только проблемные моменты. Остальное почти сооьветствует обычной спецификации.
Юрий Зотов ©   (27.07.04 16:49) [199]
>Но после того, как какая-то спецификация языка будет Вами принята, калькулятор обязан СТРОГО ей соответствовать и любое отклонение рассматривается, как глюк.
Придется делать унарный плюс. :o(

Григорьев Антон ©   (27.07.04 16:29) [193]
>Кстати, судя по всему, вы даже не понимаете разницы между унарным и бинарным минусом.
Конечно. Я не знаю, что такое бинарный минус.
>А берётесь писать калькулятор. Это всё равно что я, не знающий разницу между дебетом и кредитом,
>взялся бы писать бухгалтерскую программу.
Эти 2 слова - часть теории, ничуть не помогающая писать калькулятор, она нужна только для общения с теми, кто теорию знает.

>Попытайтесь хотя бы понять ту спецификацию, которую Юрий написал в [83], чтобы понять,
>чем она отличается от того позорища, которое вы привели.
Я не пытался написать спецификацию.

>А у вас пока глючит не по-детски, да ещё и вы, автор, не можете толком сказать, какие выражения калькулятор поймёт,
>а какие - нет. И это - после примерно 7 (если не ошибаюсь) часов работы.
Уже не глючит. Примерно 6 часов.

calm ©   (27.07.04 16:33) [195]
>Кстати, а как вы можете утверждать подобное, не владея теорией?
Я же сказал:
> в той теории, котроую мне рассказал отец
Хотя я не прав: если сделать конечный автомат, разбирающий спецификацию, то он будет гораздо универсальнее. Но если просто запрограммировать спецификацию (одна функция - для <factor>, другую -для и т.д. третью - для и т.п...), то добавлять новые операции с новыми преоритетами будет не так просто.


 
Григорьев Антон ©   (2004-07-28 10:47) [232]


> GrayFace   (28.07.04 10:25) [231]
> Я описал только проблемные моменты. Остальное почти сооьветствует
> обычной спецификации.


После такой фразы очевидно, что вы вообще не понимаете, зачем нужна спецификация. Она нужна не человеку - человек и так знает, как вычислять выражения. Она нужна компьютеру. Спецификация - это формальное описание тех правил, которые вы собираетесь заложить в свой анализатор. И слова "обычная спецификация" здесь не прокатят - компьютер не знает, что это такое. Нормальная спецификация должна быть основана на тех понятиях, которые однозначно распознаются компьютером (например, символ "+"), и любая абстракция в этой спецификации должна сводиться к комбинации этих понятий. Спецификация - это не столько набор того, что допустимо на входе анализатора, сколько описание его алгоритма.


> Я не знаю, что такое бинарный минус.


Без комментариев.


 
Юрий Зотов ©   (2004-07-28 10:48) [233]

> calm ©   (27.07.04 16:33) [195]

> Но если просто запрограммировать спецификацию (одна функция -
> для <factor>, другую -для и т.д. третью - для и т.п...), то
> добавлять новые операции с новыми преоритетами будет не так
> просто.

А новые операции добавлять и не нужно. Поддерживаемый любым языком набор операций полностью покрывает все, что может потребоваться прграммисту и поэтому заведомо известно, что новые операции просто никогда не будут нужны. И изменение приоритетов операций тоже никогда не потребуется (более того, оно просто недопустимо - иначе программа, написанная в одной версии языка может начать глючить в другой версии того же языка).

Вот набор операций Delphi:

- операции отношения
< = > <= <> >=

- логические и побитовые операции
and or not xor shl shr

- арифметические операции
+ - * / div mod

- прочие операции
@ in is as

Попробуйте предложить сюда еще что-нибудь ДЕЙСТВИТЕЛЬНО недостающее (сразу говорю, что возведение в степень ДЕЙСТВИТЕЛЬНО недостающей операцией не является).


 
Игорь Шевченко ©   (2004-07-28 10:51) [234]


> Уже не глючит.


Ссылочку на неглючный в студию :)

Григорьев Антон ©   (28.07.04 10:20)


> Вот, кстати, ещё одна причина учить теорию:


Я, честно говоря, сам ее здорово подзабыл, ту самую теорию, благо последний раз читал 15 лет назад, причем, неплохую книжку Гриса.

Кстати, пользуясь случаем, спрошу, нету ли у тебя случайно книги
"Ф.Льюис, Д.Розенкранц, Р.Стирнз, Теоретические основы проектирования компиляторов" и "Генератор компиляторов У. Маккиман, Дж. Хорнинг, Д. Уортман" (книжки старые, я на авось спрашиваю...) :))


 
pasha_golub ©   (2004-07-28 10:53) [235]

Да, по поводу книжек я бы тоже спросил. Но вот в электронном виде, ибо...


 
Cobalt ©   (2004-07-28 10:57) [236]

2 GrayFace
А ссылку на калькулятор? по адресу http://www.hot.ee/gelphi/Calculator.zip  размер архива не изменился ни на байт, mainUnit.pas - тоже (exe-ник я пересобираю из исходников)

1/3sin(1) - выдаёт 0,333333333333333}{0,0174524064372835


 
Григорьев Антон ©   (2004-07-28 11:03) [237]


> Игорь Шевченко ©   (28.07.04 10:51) [234]
> Кстати, пользуясь случаем, спрошу, нету ли у тебя случайно
> книги
> "Ф.Льюис, Д.Розенкранц, Р.Стирнз, Теоретические основы проектирования
> компиляторов" и "Генератор компиляторов У. Маккиман, Дж.
> Хорнинг, Д. Уортман" (книжки старые, я на авось спрашиваю...)
> :))


К сожалению, нет. Я тоже до недавнего времени считал, что обойдусь и без теории, поэтому моя библиотека пока очень бедна и в ней есть только новые книги.


 
Calm ©   (2004-07-28 11:05) [238]

>>Хотя я не прав: если сделать конечный автомат, разбирающий спецификацию, то он будет гораздо универсальнее.

Колькуляторописатели сдают свои позиции :((


 
GrayFace   (2004-07-28 11:09) [239]

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   Button1: TButton;
   Edit2: TEdit;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

type TOperator=function(v1,v2:extended):extended;
    TFunction=function(v:extended):extended;

    TFunc=record
      f:pointer;
      name:string;
    end;
    TConst=record
      v:Extended;
      name:string;
    end;
    TBracketFunc=record
      f:pointer;
      left:string;
      right:char;
    end;
    TOper=record
      f:pointer;
      name:string;
      prior:integer;
    end;

function Mul(v1,v2:extended):extended;
begin
 Result:=v1*v2;
end;
function Div1(v1,v2:extended):extended;
begin
 Result:=v1/v2;
end;
function Add(v1,v2:extended):extended;
begin
 Result:=v1+v2;
end;
function Dec(v1,v2:extended):extended;
begin
 Result:=v1-v2;
end;
function Stepen(v1,v2:extended):extended;
begin
 Result:=exp(ln(v1)*v2);
end;
function Sin1(v:extended):extended;
begin
 Result:=sin(v);
end;
function Cos1(v:extended):extended;
begin
 Result:=cos(v);
end;
function Tg(v:extended):extended;
begin
 Result:=tan(v);
end;
function Ctg(v:extended):extended;
begin
 Result:=CoTan(v);
end;
function aSin(v:extended):extended;
begin
 Result:=arcsin(v);
end;
function aCos(v:extended):extended;
begin
 Result:=arccos(v);
end;
function aTg(v:extended):extended;
begin
 Result:=arctan(v);
end;
function aCtg(v:extended):extended;
begin
 if v=0 then Result:=pi/2
 else Result:=arcTan(1/v);
end;
function Modul(v:extended):extended;
begin
 Result:=abs(v);
end;

const Opers:array[0..4] of TOper=((f:@Add; name:"+"; Prior:10),(f:@dec; name:"-"; prior:10),(f:@Mul; name:"*"; prior:20),(f:@Div1; name:"/"; prior:20),(f:@stepen; name:"^"; prior:30));
     OpMul:TOper=(f:@Mul; name:"*"; prior:20);
     Funcs:array[0..7] of TFunc=((f:@sin1; name:"sin"),(f:@cos1; name:"cos"),(f:@tg; name:"tg"),(f:@ctg; name:"ctg"),(f:@asin; name:"arcsin"),(f:@acos; name:"arccos"),(f:@atg; name:"arctg"),(f:@actg; name:"arcctg"));
     BracketFuncs:array[0..0] of TBracketFunc=((f:@Modul; left:"|"; right:"|"));
     Consts:array[0..0] of TConst=((v:pi; name:"pi"));

procedure DoString(From,Tom:PChar; var s:string);
var i:integer;
begin
 SetLength(s,integer(tom)-integer(from)+1);
 for i:=1 to length(s) do
 begin
   if from^="." then s[i]:=DecimalSeparator
   else s[i]:=from^;
   inc(from);
 end;
end;

function cmp(const s:string; p:PChar):boolean;
var s1:string; l:integer;
begin
 l:=length(s);
 SetLength(s1,l);
 CopyMemory(@s1[1],p,l);
 Result:=AnsiCompareText(s,s1)=0;
end;

function GetOper(var s:PChar; sep:Char; prior:integer; var done:byte; v1:extended):extended; forward;
{----------------------------------------------}

function GetNumber(var s:PChar):Extended;
var from,tom:PChar; step:integer;
begin
 from:=pointer(s);
 tom:=nil;
 step:=0;
 while true do
 begin
   if (s^="e") or (s^="E") then
   begin
     if step=1 then step:=2 else break;
   end else
   if (s^="-") then
   begin
     if (step and 1)<>0 then break;
   end else
   if (s^="+") then
   begin
     if (step and 1)<>0 then break;
   end else
   if (ord(s^)>=ord("0")) and (ord(s^)<=ord("9")) or (step<2) and ((s^=".") or (s^=DecimalSeparator)) then
   begin
     step:=step or 1;
     tom:=s;
   end else break;
   inc(s);
 end;
 if (tom=nil) then raise Exception.Create("Syntax error");
 if (step and 1)=0 then
 begin
   s:=pointer(from);
   raise Exception.Create("Syntax error");
 end;
 s:=tom;
 inc(s);
 DoString(from,tom,s1);
 try
   Result:=StrToFloat(s1);
 except
   s:=pointer(from);
   raise Exception.Create("Syntax error");
 end;
end;

var s1:string; i:integer; Len:integer; Br:char; // vloz:integer=0;


 
GrayFace   (2004-07-28 11:09) [240]

function GetValue(var s:PChar; sep:Char; prior:integer; var done:byte):extended;
var fu:pointer;
begin
//  inc(vloz);
 try
//    Application.MessageBox(PChar("&#205;&#224;&#247;&#224;&#235;&#238;. Vloz:"+IntToStr(vloz)+" "+s+" Prior:"+IntToStr(prior)+" Sep:"+sep),"");
   while (s^=" ") or (s^="+") do inc(s);
   if s^="(" then
   begin
     inc(s);
     Result:=GetValue(s,")",-MaxInt,done);
     done:=0;
     exit;
   end;
   if s^="-" then
   begin
     inc(s);
     Result:=-GetValue(s,sep,MaxInt,done);
     exit;
   end;
   len:=0;
   for i:=low(BracketFuncs) to high(BracketFuncs) do
   begin
     if (length(BracketFuncs[i].left)>len) and cmp(BracketFuncs[i].left,s) then
     begin
       Br:=BracketFuncs[i].right;
       fu:=BracketFuncs[i].f;
       len:=length(BracketFuncs[i].left);
     end;
   end;
   if len<>0 then
   begin
     inc(s,len);
     Result:=TFunction(fu)(GetValue(s,Br,-MaxInt,done));
     done:=0;
     exit;
   end;
   for i:=low(Funcs) to high(Funcs) do
   begin
     if (length(Funcs[i].name)>len) and cmp(Funcs[i].name,s) then
     begin
       fu:=Funcs[i].f;
       len:=length(Funcs[i].name);
     end;
   end;
   for i:=low(Consts) to high(Consts) do
   begin
     if (length(Consts[i].name)>len) and cmp(Consts[i].name,s) then
     begin
       fu:=nil;
       Result:=Consts[i].v;
       len:=length(Consts[i].name);
     end;
   end;
   if len<>0 then
   begin
     inc(s,len);
     if fu<>nil then
     begin
       Result:=TFunction(fu)(GetValue(s,sep,MaxInt,done));
     end;
     exit;
   end;
   Result:=GetNumber(s);
 finally
//    Application.MessageBox(PChar("Vloz:"+IntToStr(vloz)+" "+s+" Prior:"+IntToStr(prior)+" Sep:"+sep),"");
   if done<>2 then
   begin
     done:=0;
     while done=0 do
     begin
       Result:=GetOper(s,sep,prior,done,Result);
     end;
     if done=1 then done:=0;
   end;
//    vloz:=vloz-1;
 end;
end;

function GetOper(var s:PChar; sep:Char; prior:integer; var done:byte; v1:extended):extended;
var op:TOper;
begin
 while s^=" " do inc(s);
 if (s^=sep) or (s^=#0) then
 begin
   if s^<>sep then raise Exception.Create("Syntax error: ""+sep+"" wasn""t found");
   if s^<>#0 then inc(s);
   done:=2;
   Result:=v1;
   exit;
 end;
 len:=0;
 for i:=low(opers) to high(opers) do
 begin
   if (length(Opers[i].name)>len) and cmp(Opers[i].name,s) then
   begin
     op:=Opers[i];
     len:=length(Opers[i].name);
   end;
 end;
 if Len=0 then op:=OpMul;
 if op.prior>prior then
 begin
   inc(s,Len);
   Result:=TOperator(op.f)(v1,GetValue(s,sep,op.prior,done))
 end else
 begin
   Result:=v1;
   done:=1;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var b:byte; p:PChar; s:string; i:integer;
begin
//  vloz:=0;
 b:=0;
 s:=Edit1.text;
 p:=PChar(s);
 try
   Edit2.Text:=FloatToStr(GetValue(p,#0,-MaxInt,b));
   Edit1.SetFocus;
   Edit1.SelLength:=0;
   Edit1.SelStart:=length(s);
 except
   on E: Exception do
   begin
     if s="" then i:=0 else i:=integer(p)-integer(@s[1]);
     Edit2.Text:=E.Message+" at offset "+IntToStr(i);
     Edit1.SetFocus;
     Edit1.SelStart:=i;
     Edit1.SelLength:=0;
   end;
 end;
end;

end.



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 18 
19 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.11.07;
Скачать: [xml.tar.bz2];

Наверх




Память: 1.12 MB
Время: 0.176 c
1-1098655862
saNat
2004-10-25 02:11
2004.11.07
Глюки TMemo


9-1089764101
Xerx
2004-07-14 04:15
2004.11.07
GLScene


3-1097127825
ligor
2004-10-07 09:43
2004.11.07
XML->БД


1-1098343873
sergeii
2004-10-21 11:31
2004.11.07
Permezhenie Mishki


14-1098353462
Pentium133
2004-10-21 14:11
2004.11.07
Пропал ObjectInspector





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский