README (8533B)
1PLY (Python Lex-Yacc) Version 2.2 (November 1, 2006) 2 3David M. Beazley (dave@dabeaz.com) 4 5Copyright (C) 2001-2006 David M. Beazley 6 7This library is free software; you can redistribute it and/or 8modify it under the terms of the GNU Lesser General Public 9License as published by the Free Software Foundation; either 10version 2.1 of the License, or (at your option) any later version. 11 12This library is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15Lesser General Public License for more details. 16 17You should have received a copy of the GNU Lesser General Public 18License along with this library; if not, write to the Free Software 19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 21See the file COPYING for a complete copy of the LGPL. 22 23Introduction 24============ 25 26PLY is a 100% Python implementation of the common parsing tools lex 27and yacc. Although several other parsing tools are available for 28Python, there are several reasons why you might want to consider PLY: 29 30 - The tools are very closely modeled after traditional lex/yacc. 31 If you know how to use these tools in C, you will find PLY 32 to be similar. 33 34 - PLY provides *very* extensive error reporting and diagnostic 35 information to assist in parser construction. The original 36 implementation was developed for instructional purposes. As 37 a result, the system tries to identify the most common types 38 of errors made by novice users. 39 40 - PLY provides full support for empty productions, error recovery, 41 precedence specifiers, and moderately ambiguous grammars. 42 43 - Parsing is based on LR-parsing which is fast, memory efficient, 44 better suited to large grammars, and which has a number of nice 45 properties when dealing with syntax errors and other parsing problems. 46 Currently, PLY builds its parsing tables using the SLR algorithm which 47 is slightly weaker than LALR(1) used in traditional yacc. 48 49 - PLY uses Python introspection features to build lexers and parsers. 50 This greatly simplifies the task of parser construction since it reduces 51 the number of files and eliminates the need to run a separate lex/yacc 52 tool before running your program. 53 54 - PLY can be used to build parsers for "real" programming languages. 55 Although it is not ultra-fast due to its Python implementation, 56 PLY can be used to parse grammars consisting of several hundred 57 rules (as might be found for a language like C). The lexer and LR 58 parser are also reasonably efficient when parsing typically 59 sized programs. 60 61The original version of PLY was developed for an Introduction to 62Compilers course where students used it to build a compiler for a 63simple Pascal-like language. Their compiler had to include lexical 64analysis, parsing, type checking, type inference, and generation of 65assembly code for the SPARC processor. Because of this, the current 66implementation has been extensively tested and debugged. In addition, 67most of the API and error checking steps have been adapted to address 68common usability problems. 69 70How to Use 71========== 72 73PLY consists of two files : lex.py and yacc.py. These are contained 74within the 'ply' directory which may also be used as a Python package. 75To use PLY, simply copy the 'ply' directory to your project and import 76lex and yacc from the associated 'ply' package. For example: 77 78 import ply.lex as lex 79 import ply.yacc as yacc 80 81Alternatively, you can copy just the files lex.py and yacc.py 82individually and use them as modules. For example: 83 84 import lex 85 import yacc 86 87The file setup.py can be used to install ply using distutils. 88 89The file doc/ply.html contains complete documentation on how to use 90the system. 91 92The example directory contains several different examples including a 93PLY specification for ANSI C as given in K&R 2nd Ed. 94 95A simple example is found at the end of this document 96 97Requirements 98============ 99PLY requires the use of Python 2.0 or greater. It should work on 100just about any platform. PLY has been tested with both CPython and 101Jython. However, it does not work with IronPython. 102 103Resources 104========= 105More information about PLY can be obtained on the PLY webpage at: 106 107 http://www.dabeaz.com/ply 108 109For a detailed overview of parsing theory, consult the excellent 110book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and 111Ullman. The topics found in "Lex & Yacc" by Levine, Mason, and Brown 112may also be useful. 113 114A Google group for PLY can be found at 115 116 http://groups.google.com/group/ply-hack 117 118Acknowledgments 119=============== 120A special thanks is in order for all of the students in CS326 who 121suffered through about 25 different versions of these tools :-). 122 123The CHANGES file acknowledges those who have contributed patches. 124 125Elias Ioup did the first implementation of LALR(1) parsing in PLY-1.x. 126Andrew Waters and Markus Schoepflin were instrumental in reporting bugs 127and testing a revised LALR(1) implementation for PLY-2.0. 128 129Special Note for PLY-2.x 130======================== 131PLY-2.0 is the first in a series of PLY releases that will be adding a 132variety of significant new features. The first release in this series 133(Ply-2.0) should be 100% compatible with all previous Ply-1.x releases 134except for the fact that Ply-2.0 features a correct implementation of 135LALR(1) table generation. 136 137If you have suggestions for improving PLY in future 2.x releases, please 138contact me. - Dave 139 140Example 141======= 142 143Here is a simple example showing a PLY implementation of a calculator 144with variables. 145 146# ----------------------------------------------------------------------------- 147# calc.py 148# 149# A simple calculator with variables. 150# ----------------------------------------------------------------------------- 151 152tokens = ( 153 'NAME','NUMBER', 154 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 155 'LPAREN','RPAREN', 156 ) 157 158# Tokens 159 160t_PLUS = r'\+' 161t_MINUS = r'-' 162t_TIMES = r'\*' 163t_DIVIDE = r'/' 164t_EQUALS = r'=' 165t_LPAREN = r'\(' 166t_RPAREN = r'\)' 167t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 168 169def t_NUMBER(t): 170 r'\d+' 171 try: 172 t.value = int(t.value) 173 except ValueError: 174 print "Integer value too large", t.value 175 t.value = 0 176 return t 177 178# Ignored characters 179t_ignore = " \t" 180 181def t_newline(t): 182 r'\n+' 183 t.lexer.lineno += t.value.count("\n") 184 185def t_error(t): 186 print "Illegal character '%s'" % t.value[0] 187 t.lexer.skip(1) 188 189# Build the lexer 190import ply.lex as lex 191lex.lex() 192 193# Precedence rules for the arithmetic operators 194precedence = ( 195 ('left','PLUS','MINUS'), 196 ('left','TIMES','DIVIDE'), 197 ('right','UMINUS'), 198 ) 199 200# dictionary of names (for storing variables) 201names = { } 202 203def p_statement_assign(p): 204 'statement : NAME EQUALS expression' 205 names[p[1]] = p[3] 206 207def p_statement_expr(p): 208 'statement : expression' 209 print p[1] 210 211def p_expression_binop(p): 212 '''expression : expression PLUS expression 213 | expression MINUS expression 214 | expression TIMES expression 215 | expression DIVIDE expression''' 216 if p[2] == '+' : p[0] = p[1] + p[3] 217 elif p[2] == '-': p[0] = p[1] - p[3] 218 elif p[2] == '*': p[0] = p[1] * p[3] 219 elif p[2] == '/': p[0] = p[1] / p[3] 220 221def p_expression_uminus(p): 222 'expression : MINUS expression %prec UMINUS' 223 p[0] = -p[2] 224 225def p_expression_group(p): 226 'expression : LPAREN expression RPAREN' 227 p[0] = p[2] 228 229def p_expression_number(p): 230 'expression : NUMBER' 231 p[0] = p[1] 232 233def p_expression_name(p): 234 'expression : NAME' 235 try: 236 p[0] = names[p[1]] 237 except LookupError: 238 print "Undefined name '%s'" % p[1] 239 p[0] = 0 240 241def p_error(p): 242 print "Syntax error at '%s'" % p.value 243 244import ply.yacc as yacc 245yacc.yacc() 246 247while 1: 248 try: 249 s = raw_input('calc > ') 250 except EOFError: 251 break 252 yacc.parse(s) 253 254 255Bug Reports and Patches 256======================= 257Because of the extremely specialized and advanced nature of PLY, I 258rarely spend much time working on it unless I receive very specific 259bug-reports and/or patches to fix problems. I also try to incorporate 260submitted feature requests and enhancements into each new version. To 261contact me about bugs and/or new features, please send email to 262dave@dabeaz.com. 263 264In addition there is a Google group for discussing PLY related issues at 265 266 http://groups.google.com/group/ply-hack 267 268-- Dave 269 270 271 272 273 274 275 276 277