-PLY (Python Lex-Yacc) Version 1.2 (November 27, 2002)
-
-David M. Beazley
-Department of Computer Science
-University of Chicago
-Chicago, IL 60637
-beazley@cs.uchicago.edu
-
-Copyright (C) 2001 David M. Beazley
-
-$Header: /home/stever/bk/newmem2/ext/ply/README 1.1 03/06/06 14:53:34-00:00 stever@ $
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-See the file COPYING for a complete copy of the LGPL.
+PLY (Python Lex-Yacc) Version 3.2
+
+Copyright (C) 2001-2009,
+David M. Beazley (Dabeaz LLC)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the David Beazley or Dabeaz LLC may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Introduction
============
PLY is a 100% Python implementation of the common parsing tools lex
-and yacc. Although several other parsing tools are available for
-Python, there are several reasons why you might want to consider PLY:
+and yacc. Here are a few highlights:
- - The tools are very closely modeled after traditional lex/yacc.
+ - PLY is very closely modeled after traditional lex/yacc.
If you know how to use these tools in C, you will find PLY
to be similar.
- Parsing is based on LR-parsing which is fast, memory efficient,
better suited to large grammars, and which has a number of nice
properties when dealing with syntax errors and other parsing problems.
- Currently, PLY builds its parsing tables using the SLR algorithm which
- is slightly weaker than LALR(1) used in traditional yacc.
+ Currently, PLY builds its parsing tables using the LALR(1)
+ algorithm used in yacc.
- - Like John Aycock's excellent SPARK toolkit, PLY uses Python
- reflection to build lexers and parsers. This greatly simplifies
- the task of parser construction since it reduces the number of files
- and eliminates the need to run a separate lex/yacc tool before
- running your program.
+ - PLY uses Python introspection features to build lexers and parsers.
+ This greatly simplifies the task of parser construction since it reduces
+ the number of files and eliminates the need to run a separate lex/yacc
+ tool before running your program.
- PLY can be used to build parsers for "real" programming languages.
Although it is not ultra-fast due to its Python implementation,
PLY can be used to parse grammars consisting of several hundred
rules (as might be found for a language like C). The lexer and LR
parser are also reasonably efficient when parsing typically
- sized programs.
-
-The original version of PLY was developed for an Introduction to
-Compilers course where students used it to build a compiler for a
-simple Pascal-like language. Their compiler had to include lexical
-analysis, parsing, type checking, type inference, and generation of
-assembly code for the SPARC processor. Because of this, the current
-implementation has been extensively tested and debugged. In addition,
-most of the API and error checking steps have been adapted to address
-common usability problems.
+ sized programs. People have used PLY to build parsers for
+ C, C++, ADA, and other real programming languages.
How to Use
==========
-PLY consists of two files : lex.py and yacc.py. To use the system,
-simply copy these files to your project and import them like standard
-Python modules.
+PLY consists of two files : lex.py and yacc.py. These are contained
+within the 'ply' directory which may also be used as a Python package.
+To use PLY, simply copy the 'ply' directory to your project and import
+lex and yacc from the associated 'ply' package. For example:
+
+ import ply.lex as lex
+ import ply.yacc as yacc
+
+Alternatively, you can copy just the files lex.py and yacc.py
+individually and use them as modules. For example:
+
+ import lex
+ import yacc
+
+The file setup.py can be used to install ply using distutils.
The file doc/ply.html contains complete documentation on how to use
the system.
The example directory contains several different examples including a
-PLY specification for ANSI C as given in K&R 2nd Ed. Note: To use
-the examples, you will need to copy the lex.py and yacc.py files to
-the example directory.
+PLY specification for ANSI C as given in K&R 2nd Ed.
A simple example is found at the end of this document
Requirements
============
-PLY requires the use of Python 2.0 or greater. It should work on
-just about any platform.
+PLY requires the use of Python 2.2 or greater. However, you should
+use the latest Python release if possible. It should work on just
+about any platform. PLY has been tested with both CPython and Jython.
+It also seems to work with IronPython.
Resources
=========
-
More information about PLY can be obtained on the PLY webpage at:
- http://systems.cs.uchicago.edu/ply
+ http://www.dabeaz.com/ply
For a detailed overview of parsing theory, consult the excellent
book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and
Ullman. The topics found in "Lex & Yacc" by Levine, Mason, and Brown
may also be useful.
-Given that this is the first release, I welcome your comments on how
-to improve the current implementation. See the TODO file for things that
-still need to be done.
+A Google group for PLY can be found at
+
+ http://groups.google.com/group/ply-hack
Acknowledgments
===============
-
A special thanks is in order for all of the students in CS326 who
suffered through about 25 different versions of these tools :-).
+The CHANGES file acknowledges those who have contributed patches.
+
+Elias Ioup did the first implementation of LALR(1) parsing in PLY-1.x.
+Andrew Waters and Markus Schoepflin were instrumental in reporting bugs
+and testing a revised LALR(1) implementation for PLY-2.0.
+
+Special Note for PLY-3.0
+========================
+PLY-3.0 the first PLY release to support Python 3. However, backwards
+compatibility with Python 2.2 is still preserved. PLY provides dual
+Python 2/3 compatibility by restricting its implementation to a common
+subset of basic language features. You should not convert PLY using
+2to3--it is not necessary and may in fact break the implementation.
+
Example
=======
-Here is a simple example showing a PLY implementation of a calculator with variables.
+Here is a simple example showing a PLY implementation of a calculator
+with variables.
# -----------------------------------------------------------------------------
# calc.py
def t_NUMBER(t):
r'\d+'
- try:
- t.value = int(t.value)
- except ValueError:
- print "Integer value too large", t.value
- t.value = 0
+ t.value = int(t.value)
return t
# Ignored characters
def t_newline(t):
r'\n+'
- t.lineno += t.value.count("\n")
+ t.lexer.lineno += t.value.count("\n")
def t_error(t):
print "Illegal character '%s'" % t.value[0]
- t.skip(1)
+ t.lexer.skip(1)
# Build the lexer
-import lex
+import ply.lex as lex
lex.lex()
# Precedence rules for the arithmetic operators
# dictionary of names (for storing variables)
names = { }
-def p_statement_assign(t):
+def p_statement_assign(p):
'statement : NAME EQUALS expression'
- names[t[1]] = t[3]
+ names[p[1]] = p[3]
-def p_statement_expr(t):
+def p_statement_expr(p):
'statement : expression'
- print t[1]
+ print p[1]
-def p_expression_binop(t):
+def p_expression_binop(p):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
- if t[2] == '+' : t[0] = t[1] + t[3]
- elif t[2] == '-': t[0] = t[1] - t[3]
- elif t[2] == '*': t[0] = t[1] * t[3]
- elif t[2] == '/': t[0] = t[1] / t[3]
+ if p[2] == '+' : p[0] = p[1] + p[3]
+ elif p[2] == '-': p[0] = p[1] - p[3]
+ elif p[2] == '*': p[0] = p[1] * p[3]
+ elif p[2] == '/': p[0] = p[1] / p[3]
-def p_expression_uminus(t):
+def p_expression_uminus(p):
'expression : MINUS expression %prec UMINUS'
- t[0] = -t[2]
+ p[0] = -p[2]
-def p_expression_group(t):
+def p_expression_group(p):
'expression : LPAREN expression RPAREN'
- t[0] = t[2]
+ p[0] = p[2]
-def p_expression_number(t):
+def p_expression_number(p):
'expression : NUMBER'
- t[0] = t[1]
+ p[0] = p[1]
-def p_expression_name(t):
+def p_expression_name(p):
'expression : NAME'
try:
- t[0] = names[t[1]]
+ p[0] = names[p[1]]
except LookupError:
- print "Undefined name '%s'" % t[1]
- t[0] = 0
+ print "Undefined name '%s'" % p[1]
+ p[0] = 0
-def p_error(t):
- print "Syntax error at '%s'" % t.value
+def p_error(p):
+ print "Syntax error at '%s'" % p.value
-import yacc
+import ply.yacc as yacc
yacc.yacc()
while 1:
yacc.parse(s)
+Bug Reports and Patches
+=======================
+My goal with PLY is to simply have a decent lex/yacc implementation
+for Python. As a general rule, I don't spend huge amounts of time
+working on it unless I receive very specific bug reports and/or
+patches to fix problems. I also try to incorporate submitted feature
+requests and enhancements into each new version. To contact me about
+bugs and/or new features, please send email to dave@dabeaz.com.
+In addition there is a Google group for discussing PLY related issues at
+ http://groups.google.com/group/ply-hack
+
+-- Dave
-
-
-
-