sample code using pyparsing.

2005-05-30
2013-05-14
  • Steven Siew
    Steven Siew
    2005-05-30

    Paul,

      Are you interested in a sample python codes using your pyparsing module.

      I have a small sample code which is quite powerful. You could put this code into your pyparsing package as an example file. So far, it uses pyparsing to perform simple calculations using variables.

      The entire file is only 141 lines, if you are interested then I can give your an url link to the python sourcecode.

      Here are some sample screen outputs.

    $ python Parsing_example11.py
    Type in the string to be parse or 'quit' to exit the program
    > g=67.89 + 7/5
    68.89
    > g
    68.89
    > h=(6*g+8.8)-g
    353.25
    > h + 1
    354.25
    > 67.89 + 7/5
    68.89
    > quit
    Good bye!

    $ python Parsing_example11.py
    Type in the string to be parse or 'quit' to exit the program
    > f=67 +43hj7ds%&^$dfh
    Parse Failure
    f=67 +43hj7ds%&^$dfh
            ^
    Expected end of text (8), (1,9)
    > f=67 +43hj7d
    Parse Failure
    f=67 +43hj7d
            ^
    Expected end of text (8), (1,9)
    > f=67 +43
    110
    > quit
    Good bye!

     
    • Paul McGuire
      Paul McGuire
      2005-05-30

      Steven -

      Yes, by all means!  Several of the other files in the examples directory are submissions from other pyparsing users, you can join their vaunted ranks!

      Thanks!
      -- Paul

       
    • Steven Siew
      Steven Siew
      2005-05-30

       
    • Steven Siew
      Steven Siew
      2005-05-31

      Well? What do you think? I think the source code is more user friendly than the example code of fourFn.py

       
      • Paul McGuire
        Paul McGuire
        2005-05-31

        Looks great!  Here are some cleanup suggestions:
        1. Remove import readline, since you use raw_input instead.
        2. Change assignVar to:
        def assignVar( str, loc, toks ):
            varStack.append( toks[0] )
        There is no longer any need to return toks if they are unchanged by the parse action, and for this parse action, toks will never be empty.  Also, no need to declare varStack as global, since you are not assigning it (similar comments for pushFirst - I need to make same changes in fourFn.py).
        3. Add a method for evaluating an expression and call that from within your while loop.  Then put your while loop inside an "if __name__ == "__main__":" block.  This way your program will run interactively just as you have it, *or* it could be called as a module from another Python module.

        I'll include it in the examples directory for 1.3.1.

        -- Paul

         
    • Steven Siew
      Steven Siew
      2005-06-10

      Paul McGuire,

        Sorry about the long delay between responses, I was very busy with work and also my continued fractions project in python using your pyparsing module.

        I have implemented all your suggestions.

        I have changed the name of the program to SimpleCalc.py

        Here is the new source code. Feel free to include in the examples directory for your next pyparsing release.

      http://members.optusnet.com.au/~ksiew/SimpleCalc.py

       
      • Paul McGuire
        Paul McGuire
        2005-06-10

        Steven -

        Thanks for this submission.  I had found one other item, and I just made this change in my copy, in the definition of ident.  You had:

        ident = Combine(Word(alphas) + Optional(Word(alphas + nums + '_')))

        In other words, ident must start with an alpha, and may optionally be followed by alphas, numbers, or underscore.

        Word has a two-argument constructor that does all this for you.  If only one argument is provided, it gives the list of characters that may be in the word.  If two arguments are provided, the first gives the list of allowed initial characters, and the second gives the list of allowed body characters.  So ident can be more simply defined as (using another pyparsing built-in, alphanums):

        ident = Word(alphas, alphanums + '_')

        I also replaced the values returned for pi and e with math.pi and math.e, which are much more precise than the literals I originally had in fourFn.py.

        Thanks again, I hope to get 1.3.1 out before the end of the month.

        -- Paul

         
    • Paul McGuire
      Paul McGuire
      2005-06-10

      Steven -

      Did you mean to include integer division in SimpleCalc?  In your samples, "67.89 + 7/5" returns 68.89.  This occurs because you separately detect floats vs. integers, and construct a float or long value respectively.  In fourFn.py, I assumed people would relate this example more to a handheld calculator, and so integer division would throw them off.

      We can resolve this by adding "from __future__ import division" or by just combining the two case branches to create a float regardless of whether the input string is an integer or not.

      I can go either way, just wanted to point it out.

      -- Paul

       
    • Steven Siew
      Steven Siew
      2005-06-10

      Paul,

        Sorry I missed that one. Yes, / should be float division and not integer division.

        I guess adding "from __future__import division" is the easiest way of solving this problem.

       
    • Steven Siew
      Steven Siew
      2005-06-10

      Done.

        Would you believe while I was doing this , the oncall phone rang and I have to help the Unix guy in India, set up a tape drive for a machine in Turkey.

      http://members.optusnet.com.au/~ksiew/SimpleCalc.py

      # Parsing_example11.py
      #
      # Demonstration of the parsing module,
      # Sample usage
      #
      #     $ python SimpleCalc.py
      #     Type in the string to be parse or 'quit' to exit the program
      #     > g=67.89 + 7/5
      #     69.29
      #     > g
      #     69.29
      #     > h=(6*g+8.8)-g
      #     355.25
      #     > h + 1
      #     356.25
      #     > 87.89 + 7/5
      #     89.29
      #     > ans+10
      #     99.29
      #     > quit
      #     Good bye!
      #
      #

      from __future__ import division

      # Uncomment the line below for readline support on interactive terminal
      # import readline
      import re
      from pyparsing import Word, alphas, ParseException, Literal, CaselessLiteral \ , Combine, Optional, nums, Or, Forward, ZeroOrMore, StringEnd

      # Debugging flag can be set to either "debug_flag=True" or "debug_flag=False"
      debug_flag=False

      exprStack = []
      varStack  = []
      variables = {}