190 lines
7.8 KiB
Diff
190 lines
7.8 KiB
Diff
From 192d922697726dc59c7af1480a04e9fcd022cffc Mon Sep 17 00:00:00 2001
|
|
From: David Beazley <dave@dabeaz.com>
|
|
Date: Thu, 7 May 2015 15:53:44 -0500
|
|
Subject: [PATCH 1/2] Fixed issue 63
|
|
|
|
---
|
|
CHANGES | 6 ++++++
|
|
ply/lex.py | 41 ++++++++++++++++++++++-------------------
|
|
ply/yacc.py | 30 +++++++++++++++++++-----------
|
|
3 files changed, 47 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/CHANGES b/CHANGES
|
|
index fdda63fccbecd1fea842a517b12439a6706c8c16..91800a4d35d096be013fdb22436bb3cd24b695d9 100644
|
|
--- a/CHANGES
|
|
+++ b/CHANGES
|
|
@@ -1,5 +1,11 @@
|
|
+Version 3.7
|
|
+---------------------
|
|
+05/07/15: beazley
|
|
+ Fixed regression in handling of table modules if specified as module
|
|
+ objects. See https://github.com/dabeaz/ply/issues/63
|
|
+
|
|
Version 3.6
|
|
---------------------
|
|
04/25/15: beazley
|
|
If PLY is unable to create the 'parser.out' or 'parsetab.py' files due
|
|
to permission issues, it now just issues a warning message and
|
|
diff --git a/ply/lex.py b/ply/lex.py
|
|
index 8ba2051d4a75af219118023ca3551afc5931dd4b..ed1e2ed9d965500afa405791cdd5d4e1f5ca7775 100644
|
|
--- a/ply/lex.py
|
|
+++ b/ply/lex.py
|
|
@@ -169,11 +169,14 @@ class Lexer:
|
|
return c
|
|
|
|
# ------------------------------------------------------------
|
|
# writetab() - Write lexer information to a table file
|
|
# ------------------------------------------------------------
|
|
- def writetab(self, basetabmodule, outputdir=''):
|
|
+ def writetab(self, lextab, outputdir=''):
|
|
+ if isinstance(lextab, types.ModuleType):
|
|
+ raise IOError("Won't overwrite existing lextab module")
|
|
+ basetabmodule = lextab.split('.')[-1]
|
|
filename = os.path.join(outputdir, basetabmodule) + '.py'
|
|
with open(filename, 'w') as tf:
|
|
tf.write('# %s.py. This file automatically created by PLY (version %s). Don\'t edit!\n' % (basetabmodule, __version__))
|
|
tf.write('_tabversion = %s\n' % repr(__tabversion__))
|
|
tf.write('_lextokens = %s\n' % repr(self.lextokens))
|
|
@@ -883,33 +886,17 @@ def lex(module=None, object=None, debug=False, optimize=False, lextab='lextab',
|
|
if '__file__' not in ldict:
|
|
ldict['__file__'] = sys.modules[ldict['__module__']].__file__
|
|
else:
|
|
ldict = get_caller_module_dict(2)
|
|
|
|
- if outputdir is None:
|
|
- # If no output directory is set, the location of the output files
|
|
- # is determined according to the following rules:
|
|
- # - If lextab specifies a package, files go into that package directory
|
|
- # - Otherwise, files go in the same directory as the specifying module
|
|
- if '.' not in lextab:
|
|
- srcfile = ldict['__file__']
|
|
- else:
|
|
- parts = lextab.split('.')
|
|
- pkgname = '.'.join(parts[:-1])
|
|
- exec('import %s' % pkgname)
|
|
- srcfile = getattr(sys.modules[pkgname], '__file__', '')
|
|
- outputdir = os.path.dirname(srcfile)
|
|
-
|
|
# Determine if the module is package of a package or not.
|
|
# If so, fix the tabmodule setting so that tables load correctly
|
|
pkg = ldict.get('__package__')
|
|
- if pkg:
|
|
+ if pkg and isinstance(lextab, str):
|
|
if '.' not in lextab:
|
|
lextab = pkg + '.' + lextab
|
|
|
|
- baselextab = lextab.split('.')[-1]
|
|
-
|
|
# Collect parser information from the dictionary
|
|
linfo = LexerReflect(ldict, log=errorlog, reflags=reflags)
|
|
linfo.get_all()
|
|
if not optimize:
|
|
if linfo.validate_all():
|
|
@@ -1027,12 +1014,28 @@ def lex(module=None, object=None, debug=False, optimize=False, lextab='lextab',
|
|
input = lexobj.input
|
|
lexer = lexobj
|
|
|
|
# If in optimize mode, we write the lextab
|
|
if lextab and optimize:
|
|
+ if outputdir is None:
|
|
+ # If no output directory is set, the location of the output files
|
|
+ # is determined according to the following rules:
|
|
+ # - If lextab specifies a package, files go into that package directory
|
|
+ # - Otherwise, files go in the same directory as the specifying module
|
|
+ if isinstance(lextab, types.ModuleType):
|
|
+ srcfile = lextab.__file__
|
|
+ else:
|
|
+ if '.' not in lextab:
|
|
+ srcfile = ldict['__file__']
|
|
+ else:
|
|
+ parts = lextab.split('.')
|
|
+ pkgname = '.'.join(parts[:-1])
|
|
+ exec('import %s' % pkgname)
|
|
+ srcfile = getattr(sys.modules[pkgname], '__file__', '')
|
|
+ outputdir = os.path.dirname(srcfile)
|
|
try:
|
|
- lexobj.writetab(baselextab, outputdir)
|
|
+ lexobj.writetab(lextab, outputdir)
|
|
except IOError as e:
|
|
errorlog.warning("Couldn't write lextab module %r. %s" % (lextab, e))
|
|
|
|
return lexobj
|
|
|
|
diff --git a/ply/yacc.py b/ply/yacc.py
|
|
index f18e3ebbe596dd8eb833db9065cffe90d045c9f5..e0b4fafc9e2dca050b4d7311324b6b16aa9bd3bf 100644
|
|
--- a/ply/yacc.py
|
|
+++ b/ply/yacc.py
|
|
@@ -2690,11 +2690,15 @@ class LRGeneratedTable(LRTable):
|
|
# write()
|
|
#
|
|
# This function writes the LR parsing tables to a file
|
|
# -----------------------------------------------------------------------------
|
|
|
|
- def write_table(self, basemodulename, outputdir='', signature=''):
|
|
+ def write_table(self, tabmodule, outputdir='', signature=''):
|
|
+ if isinstance(tabmodule, types.ModuleType):
|
|
+ raise IOError("Won't overwrite existing tabmodule")
|
|
+
|
|
+ basemodulename = tabmodule.split('.')[-1]
|
|
filename = os.path.join(outputdir, basemodulename) + '.py'
|
|
try:
|
|
f = open(filename, 'w')
|
|
|
|
f.write('''
|
|
@@ -3202,26 +3206,30 @@ def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, star
|
|
if outputdir is None:
|
|
# If no output directory is set, the location of the output files
|
|
# is determined according to the following rules:
|
|
# - If tabmodule specifies a package, files go into that package directory
|
|
# - Otherwise, files go in the same directory as the specifying module
|
|
- if '.' not in tabmodule:
|
|
- srcfile = pdict['__file__']
|
|
+ if isinstance(tabmodule, types.ModuleType):
|
|
+ srcfile = tabmodule.__file__
|
|
else:
|
|
- parts = tabmodule.split('.')
|
|
- pkgname = '.'.join(parts[:-1])
|
|
- exec('import %s' % pkgname)
|
|
- srcfile = getattr(sys.modules[pkgname], '__file__', '')
|
|
+ if '.' not in tabmodule:
|
|
+ srcfile = pdict['__file__']
|
|
+ else:
|
|
+ parts = tabmodule.split('.')
|
|
+ pkgname = '.'.join(parts[:-1])
|
|
+ exec('import %s' % pkgname)
|
|
+ srcfile = getattr(sys.modules[pkgname], '__file__', '')
|
|
outputdir = os.path.dirname(srcfile)
|
|
|
|
# Determine if the module is package of a package or not.
|
|
# If so, fix the tabmodule setting so that tables load correctly
|
|
pkg = pdict.get('__package__')
|
|
- if pkg and '.' not in tabmodule:
|
|
- tabmodule = pkg + '.' + tabmodule
|
|
+ if pkg and isinstance(tabmodule, str):
|
|
+ if '.' not in tabmodule:
|
|
+ tabmodule = pkg + '.' + tabmodule
|
|
+
|
|
|
|
- basetabmodule = tabmodule.split('.')[-1]
|
|
|
|
# Set start symbol if it's specified directly using an argument
|
|
if start is not None:
|
|
pdict['start'] = start
|
|
|
|
@@ -3430,11 +3438,11 @@ def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, star
|
|
warned_never.append(rejected)
|
|
|
|
# Write the table file if requested
|
|
if write_tables:
|
|
try:
|
|
- lr.write_table(basetabmodule, outputdir, signature)
|
|
+ lr.write_table(tabmodule, outputdir, signature)
|
|
except IOError as e:
|
|
errorlog.warning("Couldn't create %r. %s" % (tabmodule, e))
|
|
|
|
# Write a pickled version of the tables
|
|
if picklefile:
|
|
--
|
|
2.4.3
|
|
|