суббота, 30 октября 2010 г.

Обновление примера грамматики с boost::spirit

Обновил пример для грамматики boost::spirit. Порядок построения узлов для бинарных операторов с лево-правой ассоциативностью (т.е. для всех бинарных операторов данной грамматики) был неверен, т.е. в цепочках типа
1 * 2 * 3 / 4
сначала выполнялась операция деления для операндов 3 и 4, затем операция умножения для операнда 2 и результата предыдущей операции и т.д. (на самом деле немного не так, поскольку в исходной версии была предпринята неуклюжая попытка построения правильного дерева, которая, к сожалению, работала только для простых случаев типа 5 * 6 / 7). На данный момент синтаксические деревья для любых сколь угодно сложных выражений парсятся корректно (по крайней мере в тех тестах, которые я написал и добавил в новую версию программы).
Кстати, пока занимался отладкой примера, обнаружил, что python может неверно вычислять арифметические выражения:
$ python
Python 2.6.4 (r264:75706, Jun  4 2010, 18:20:31) 
[GCC 4.4.4 20100503 (Red Hat 4.4.4-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 8 * 4 / ( 2 - 7 ) * 6 / 3
-14
>>>
Или я чего-то не понимаю в питоне, или это какой-то баг. В любом случае непонятно, как можно доверять языку, который неправильно вычисляет арифметические выражения. Может им баг засабмиттить?

Вот ссылка на новую версию программы.

В следующий раз выложу аналогичную программу, реализованную на Haskell, она почти готова.

Updateзафайлил баг в питон, но мне мягко объяснили в чем моя ошибка. Вот дословно комментарий от Mark Dickinson:

It's not a bug:  you're seeing Python's rules for integer division, which do indeed differ from those of (some) other languages when either the divisor or the dividend is negative.  For integers x and y, in Python 2.x, x / y gives the floor of the exact quotient.

>>> -32 / 5
-7
>>> 32 / -5
-7

In Python 3.x, the '/' operator does 'true division', giving you (a floating-point approximation to) the true result:

>>> -32 / 5
-6.4
>>> 32 / -5
-6.4

You can also get this behaviour in Python 2.x if you start your script with 'from __future__ import division'.

See the documentation at:

http://docs.python.org/reference/expressions.html#binary-arithmetic-operations

for more.

В общем, оператор '/' имеет какую-то странную семантику в питоне 2.x