vlasovskikh / funcparserlib

Recursive descent parsing library for Python based on functional combinators
https://funcparserlib.pirx.ru
MIT License
338 stars 38 forks source link

Python's ** is right-associative, so should the tutorial calculator be. #38

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Try to evaluate "3**3**3" in the tutorial calculator parser in 
https://bitbucket.org/vlasovskikh/funcparserlib/src/16ed98522a11620d10f5c3a9d363
82e2e0931c59/doc/Tutorial.md?at=0.3.x
2. Try to evaluate "3**3**3" in Python.

What is the expected output? What do you see instead?
3**3**3 should be 3**(3**3) == 7625597484987, but when treated as 
left-associative, it is (3**3)**3 == 3**(3*3) == 3**9 == 19683

What version of the product are you using? On what operating system?
0.3.6

Please provide any additional information below.

The following code will make the ** operator right-associative.

    def eval_expr_r(lst, z):
        return reduce(lambda s, (x, f): f(x, s), reversed(lst), z)
    eval_r = unarg(eval_expr_r)

    factor = many(primary + pow) + primary >> eval_r

Or simply design the grammar like this:

    @with_forward_decls
    def factor():
        return (
            primary + pow + factor >> (lambda (x,f,y): f(x,y))
            | primary
            )

Original issue reported on code.google.com by wks1...@gmail.com on 19 Aug 2013 at 4:55