Форум: "Потрепаться";
Текущий архив: 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("Íà÷àëî. 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