Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pybison
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
pybison
Commits
3b828fe0
Commit
3b828fe0
authored
Nov 24, 2011
by
Sander Mathijs van Veen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Code cleanup in pybison's python file.
parent
858c8461
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
146 deletions
+146
-146
src/python/bison.py
src/python/bison.py
+146
-146
No files found.
src/python/bison.py
View file @
3b828fe0
...
@@ -19,17 +19,21 @@ If you wish to use this software in a commercial application,
...
@@ -19,17 +19,21 @@ If you wish to use this software in a commercial application,
and wish to depart from the GPL licensing requirements,
and wish to depart from the GPL licensing requirements,
please contact the author and apply for a commercial license.
please contact the author and apply for a commercial license.
"""
"""
#@+others
import
sys
#@+node:imports
import
os
import
sys
,
os
,
sha
,
re
,
imp
,
traceback
,
xml
.
dom
,
xml
.
dom
.
minidom
,
types
import
sha
import
re
import
imp
import
traceback
import
xml.dom
import
xml.dom.minidom
import
types
import
distutils.sysconfig
import
distutils.sysconfig
import
distutils.ccompiler
import
distutils.ccompiler
from
bison_
import
ParserEngine
,
unquoted
from
bison_
import
ParserEngine
,
unquoted
#@-node:imports
reSpaces
=
re
.
compile
(
'
\
\
s+'
)
#@+node:globals
reSpaces
=
re
.
compile
(
"
\
\
s+"
)
class
ParserSyntaxError
(
Exception
):
class
ParserSyntaxError
(
Exception
):
...
@@ -48,7 +52,7 @@ class BisonError:
...
@@ -48,7 +52,7 @@ class BisonError:
"""
"""
_pyBisonError
=
1
_pyBisonError
=
1
def
__init__
(
self
,
value
=
"syntax error"
):
def
__init__
(
self
,
value
=
'syntax error'
):
self
.
value
=
value
self
.
value
=
value
...
@@ -81,7 +85,7 @@ class BisonNode:
...
@@ -81,7 +85,7 @@ class BisonNode:
self
.
kw
=
kw
self
.
kw
=
kw
def
__str__
(
self
):
def
__str__
(
self
):
return
"<BisonNode:%s>"
%
self
.
target
return
'<BisonNode:%s>'
%
self
.
target
def
__repr__
(
self
):
def
__repr__
(
self
):
return
str
(
self
)
return
str
(
self
)
...
@@ -105,7 +109,8 @@ class BisonNode:
...
@@ -105,7 +109,8 @@ class BisonNode:
return
self
return
self
return
self
.
values
[
item
[
0
]][
item
[
1
:]]
return
self
.
values
[
item
[
0
]][
item
[
1
:]]
else
:
else
:
raise
TypeError
(
"Can only index %s objects with an int or a list/tuple"
%
self
.
__class
.
__name__
)
raise
TypeError
(
'Can only index %s objects with an int or a'
' list/tuple'
%
self
.
__class
.
__name__
)
def
__len__
(
self
):
def
__len__
(
self
):
...
@@ -122,17 +127,18 @@ class BisonNode:
...
@@ -122,17 +127,18 @@ class BisonNode:
For debugging - prints a recursive dump of a parse tree node and its children
For debugging - prints a recursive dump of a parse tree node and its children
"""
"""
specialAttribs
=
[
'option'
,
'target'
,
'names'
,
'values'
]
specialAttribs
=
[
'option'
,
'target'
,
'names'
,
'values'
]
indents
=
" "
*
indent
*
2
indents
=
' '
*
indent
*
2
#print "%s%s: %s %s" % (indents, self.target, self.option, self.names)
#print "%s%s: %s %s" % (indents, self.target, self.option, self.names)
print
"%s%s:"
%
(
indents
,
self
.
target
)
print
'%s%s:'
%
(
indents
,
self
.
target
)
for
name
,
val
in
self
.
kw
.
items
()
+
zip
(
self
.
names
,
self
.
values
):
for
name
,
val
in
self
.
kw
.
items
()
+
zip
(
self
.
names
,
self
.
values
):
if
name
in
specialAttribs
or
name
.
startswith
(
"_"
):
if
name
in
specialAttribs
or
name
.
startswith
(
'_'
):
continue
continue
if
isinstance
(
val
,
BisonNode
):
if
isinstance
(
val
,
BisonNode
):
val
.
dump
(
indent
+
1
)
val
.
dump
(
indent
+
1
)
else
:
else
:
print
indents
+
" %s=%s"
%
(
name
,
val
)
print
indents
+
' %s=%s'
%
(
name
,
val
)
def
toxml
(
self
):
def
toxml
(
self
):
"""
"""
...
@@ -145,7 +151,8 @@ class BisonNode:
...
@@ -145,7 +151,8 @@ class BisonNode:
def
toprettyxml
(
self
,
indent
=
' '
,
newl
=
'
\
n
'
,
encoding
=
None
):
def
toprettyxml
(
self
,
indent
=
' '
,
newl
=
'
\
n
'
,
encoding
=
None
):
"""
"""
returns a human-readable xml serialisation of this node and its children
Returns a human-readable xml serialisation of this node and its
children.
"""
"""
return
self
.
toxmldoc
().
toprettyxml
(
indent
=
indent
,
return
self
.
toxmldoc
().
toprettyxml
(
indent
=
indent
,
newl
=
newl
,
newl
=
newl
,
...
@@ -153,7 +160,8 @@ class BisonNode:
...
@@ -153,7 +160,8 @@ class BisonNode:
def
toxmldoc
(
self
):
def
toxmldoc
(
self
):
"""
"""
Returns the node and its children as an xml.dom.minidom.Document object
Returns the node and its children as an xml.dom.minidom.Document
object.
"""
"""
d
=
xml
.
dom
.
minidom
.
Document
()
d
=
xml
.
dom
.
minidom
.
Document
()
d
.
appendChild
(
self
.
toxmlelem
(
d
))
d
.
appendChild
(
self
.
toxmlelem
(
d
))
...
@@ -161,7 +169,7 @@ class BisonNode:
...
@@ -161,7 +169,7 @@ class BisonNode:
def
toxmlelem
(
self
,
docobj
):
def
toxmlelem
(
self
,
docobj
):
"""
"""
Returns a DOM Element object of this node and its children
Returns a DOM Element object of this node and its children
.
"""
"""
specialAttribs
=
[
'option'
,
'target'
,
'names'
,
'values'
]
specialAttribs
=
[
'option'
,
'target'
,
'names'
,
'values'
]
...
@@ -170,16 +178,18 @@ class BisonNode:
...
@@ -170,16 +178,18 @@ class BisonNode:
# set attribs
# set attribs
for
name
,
val
in
self
.
kw
.
items
():
for
name
,
val
in
self
.
kw
.
items
():
if
name
in
[
'names'
,
'values'
]
or
name
.
startswith
(
"_"
):
if
name
in
[
'names'
,
'values'
]
or
name
.
startswith
(
'_'
):
continue
continue
x
.
setAttribute
(
name
,
str
(
val
))
x
.
setAttribute
(
name
,
str
(
val
))
#x.setAttribute('target', self.target)
#x.setAttribute('target', self.target)
#x.setAttribute('option', self.option)
#x.setAttribute('option', self.option)
# and add the children
# and add the children
for
name
,
val
in
zip
(
self
.
names
,
self
.
values
):
for
name
,
val
in
zip
(
self
.
names
,
self
.
values
):
if
name
in
specialAttribs
or
name
.
startswith
(
"_"
):
if
name
in
specialAttribs
or
name
.
startswith
(
'_'
):
continue
continue
if
isinstance
(
val
,
BisonNode
):
if
isinstance
(
val
,
BisonNode
):
x
.
appendChild
(
val
.
toxmlelem
(
docobj
))
x
.
appendChild
(
val
.
toxmlelem
(
docobj
))
else
:
else
:
...
@@ -205,20 +215,20 @@ class BisonParser(object):
...
@@ -205,20 +215,20 @@ class BisonParser(object):
# override these if you need to
# override these if you need to
# command and options for running yacc/bison, except for filename arg
# command and options for running yacc/bison, except for filename arg
bisonCmd
=
[
"bison"
,
"-d"
,
"-v"
,
'-t'
]
bisonCmd
=
[
'bison'
,
'-d'
,
'-v'
,
'-t'
]
bisonFile
=
"tmp.y"
bisonFile
=
'tmp.y'
bisonCFile
=
"tmp.tab.c"
bisonCFile
=
'tmp.tab.c'
bisonHFile
=
"tmp.tab.h"
# name of header file generated by bison cmd
bisonHFile
=
'tmp.tab.h'
# name of header file generated by bison cmd
bisonCFile1
=
"tmp.bison.c"
# c output file from bison gets renamed to this
bisonCFile1
=
'tmp.bison.c'
# c output file from bison gets renamed to this
bisonHFile1
=
"tokens.h"
# bison-generated header file gets renamed to this
bisonHFile1
=
'tokens.h'
# bison-generated header file gets renamed to this
flexCmd
=
[
"flex"
,
]
# command and options for running [f]lex, except for filename arg
flexCmd
=
[
'flex'
,
]
# command and options for running [f]lex, except for filename arg
flexFile
=
"tmp.l"
flexFile
=
'tmp.l'
flexCFile
=
"lex.yy.c"
flexCFile
=
'lex.yy.c'
flexCFile1
=
"tmp.lex.c"
# c output file from lex gets renamed to this
flexCFile1
=
'tmp.lex.c'
# c output file from lex gets renamed to this
cflags_pre
=
[
'-fPIC'
]
# = CFLAGS added before all arguments.
cflags_pre
=
[
'-fPIC'
]
# = CFLAGS added before all arguments.
cflags_post
=
[
'-O3'
,
'-g'
]
# = CFLAGS added after all arguments.
cflags_post
=
[
'-O3'
,
'-g'
]
# = CFLAGS added after all arguments.
...
@@ -266,11 +276,11 @@ class BisonParser(object):
...
@@ -266,11 +276,11 @@ class BisonParser(object):
fileobj
=
kw
.
get
(
'file'
,
None
)
fileobj
=
kw
.
get
(
'file'
,
None
)
if
fileobj
:
if
fileobj
:
if
type
(
fileobj
)
==
type
(
""
):
if
isinstance
(
fileobj
,
str
):
try
:
try
:
fileobj
=
open
(
fileobj
,
"rb"
)
fileobj
=
open
(
fileobj
,
'rb'
)
except
:
except
:
raise
Exception
(
"Cannot open input file %s"
%
fileobj
)
raise
Exception
(
'Cannot open input file %s'
%
fileobj
)
self
.
file
=
fileobj
self
.
file
=
fileobj
else
:
else
:
self
.
file
=
sys
.
stdin
self
.
file
=
sys
.
stdin
...
@@ -286,7 +296,7 @@ class BisonParser(object):
...
@@ -286,7 +296,7 @@ class BisonParser(object):
# if engine lib name not declared, invent ont
# if engine lib name not declared, invent ont
if
not
self
.
bisonEngineLibName
:
if
not
self
.
bisonEngineLibName
:
self
.
bisonEngineLibName
=
self
.
__class__
.
__module__
+
"-parser"
self
.
bisonEngineLibName
=
self
.
__class__
.
__module__
+
'-parser'
# get an engine
# get an engine
self
.
engine
=
ParserEngine
(
self
)
self
.
engine
=
ParserEngine
(
self
)
...
@@ -320,7 +330,7 @@ class BisonParser(object):
...
@@ -320,7 +330,7 @@ class BisonParser(object):
# % (targetname, repr(self.last))
# % (targetname, repr(self.last))
else
:
else
:
if
self
.
verbose
:
if
self
.
verbose
:
print
"no handler for %s, using default"
%
targetname
print
'no handler for %s, using default'
%
targetname
self
.
last
=
BisonNode
(
targetname
,
option
=
option
,
names
=
names
,
values
=
values
)
self
.
last
=
BisonNode
(
targetname
,
option
=
option
,
names
=
names
,
values
=
values
)
# reset any resulting errors (assume they've been handled)
# reset any resulting errors (assume they've been handled)
...
@@ -342,16 +352,16 @@ class BisonParser(object):
...
@@ -342,16 +352,16 @@ class BisonParser(object):
- debug - enables garrulous parser debugging output, default 0
- debug - enables garrulous parser debugging output, default 0
"""
"""
if
self
.
verbose
:
if
self
.
verbose
:
print
"Parser.run: calling engine"
print
'Parser.run: calling engine'
# grab keywords
# grab keywords
fileobj
=
kw
.
get
(
'file'
,
self
.
file
)
fileobj
=
kw
.
get
(
'file'
,
self
.
file
)
if
type
(
fileobj
)
==
type
(
""
):
if
isinstance
(
fileobj
,
str
):
filename
=
fileobj
filename
=
fileobj
try
:
try
:
fileobj
=
open
(
fileobj
,
"rb"
)
fileobj
=
open
(
fileobj
,
'rb'
)
except
:
except
:
raise
Exception
(
"Cannot open input file %s"
%
fileobj
)
raise
Exception
(
'Cannot open input file "%s"'
%
fileobj
)
else
:
else
:
filename
=
None
filename
=
None
fileobj
=
None
fileobj
=
None
...
@@ -375,18 +385,20 @@ class BisonParser(object):
...
@@ -375,18 +385,20 @@ class BisonParser(object):
self
.
engine
.
runEngine
(
debug
)
self
.
engine
.
runEngine
(
debug
)
if
self
.
lasterror
:
if
self
.
lasterror
:
#print "Got error: %s" % repr(self.error)
if
filename
!=
None
:
if
filename
!=
None
:
raise
ParserSyntaxError
(
"%s:%d: '%s' near '%s'"
%
((
filename
,)
+
self
.
lasterror
))
raise
ParserSyntaxError
(
'%s:%d: "%s" near "%s"'
%
((
filename
,)
+
self
.
lasterror
))
else
:
else
:
raise
ParserSyntaxError
(
"Line %d: '%s' near '%s'"
%
self
.
lasterror
)
raise
ParserSyntaxError
(
'Line %d: "%s" near "%s"'
%
self
.
lasterror
)
# restore old values
# restore old values
self
.
file
=
oldfile
self
.
file
=
oldfile
self
.
read
=
oldread
self
.
read
=
oldread
if
self
.
verbose
:
if
self
.
verbose
:
print
"Parser.run: back from engine"
print
'Parser.run: back from engine'
return
self
.
last
return
self
.
last
def
read
(
self
,
nbytes
):
def
read
(
self
,
nbytes
):
...
@@ -400,15 +412,19 @@ class BisonParser(object):
...
@@ -400,15 +412,19 @@ class BisonParser(object):
"""
"""
# default to stdin
# default to stdin
if
self
.
verbose
:
if
self
.
verbose
:
print
"Parser.read: want %s bytes"
%
nbytes
print
'Parser.read: want %s bytes'
%
nbytes
bytes
=
self
.
file
.
readline
(
nbytes
)
bytes
=
self
.
file
.
readline
(
nbytes
)
if
self
.
verbose
:
if
self
.
verbose
:
print
"Parser.read: got %s bytes"
%
len
(
bytes
)
print
'Parser.read: got %s bytes'
%
len
(
bytes
)
return
bytes
return
bytes
def
_error
(
self
,
linenum
,
msg
,
tok
):
def
_error
(
self
,
linenum
,
msg
,
tok
):
print
"Parser: line %s: syntax error '%s' before '%s'"
%
(
linenum
,
msg
,
tok
)
print
'Parser: line %s: syntax error "%s" before "%s"'
\
%
(
linenum
,
msg
,
tok
)
def
error
(
self
,
value
):
def
error
(
self
,
value
):
"""
"""
...
@@ -484,15 +500,15 @@ class BisonParser(object):
...
@@ -484,15 +500,15 @@ class BisonParser(object):
namespace
=
globals
()
namespace
=
globals
()
objname
=
xmlobj
.
tagName
objname
=
xmlobj
.
tagName
classname
=
objname
+
"_Node"
classname
=
objname
+
'_Node'
classobj
=
namespace
.
get
(
classname
,
None
)
classobj
=
namespace
.
get
(
classname
,
None
)
namespacekeys
=
namespace
.
keys
()
namespacekeys
=
namespace
.
keys
()
# barf if node is not a known parse node or token
# barf if node is not a known parse node or token
if
(
not
classobj
)
and
objname
not
in
self
.
tokens
:
if
(
not
classobj
)
and
objname
not
in
self
.
tokens
:
raise
Exception
(
"Cannot reconstitute %s: can't find required node class or token %s"
%
(
raise
Exception
(
'Cannot reconstitute %s: can
\
'
t find required'
objname
,
classname
))
' node class or token %s'
%
(
objname
,
classname
))
if
classobj
:
if
classobj
:
nodeobj
=
classobj
()
nodeobj
=
classobj
()
...
@@ -500,28 +516,27 @@ class BisonParser(object):
...
@@ -500,28 +516,27 @@ class BisonParser(object):
# add the attribs
# add the attribs
for
k
,
v
in
xmlobj
.
attributes
.
items
():
for
k
,
v
in
xmlobj
.
attributes
.
items
():
setattr
(
nodeobj
,
k
,
v
)
setattr
(
nodeobj
,
k
,
v
)
else
:
else
:
nodeobj
=
None
nodeobj
=
None
#print
"----------------"
#print
'----------------'
#print
"objname=%s"
% repr(objname)
#print
'objname=%s'
% repr(objname)
#print
"classname=%s"
% repr(classname)
#print
'classname=%s'
% repr(classname)
#print
"classobj=%s"
% repr(classobj)
#print
'classobj=%s'
% repr(classobj)
#print
"nodeobj=%s"
% repr(nodeobj)
#print
'nodeobj=%s'
% repr(nodeobj)
# now add the children
# now add the children
for
child
in
xmlobj
.
childNodes
:
for
child
in
xmlobj
.
childNodes
:
#print
"%s attributes=%s"
% (child, child.attributes.items())
#print
'%s attributes=%s'
% (child, child.attributes.items())
childname
=
child
.
attributes
[
'target'
].
value
childname
=
child
.
attributes
[
'target'
].
value
#print
"childname=%s"
% childname
#print
'childname=%s'
% childname
if
childname
+
"_Node"
in
namespacekeys
:
if
childname
+
'_Node'
in
namespacekeys
:
#print
"we have a node for class %s"
% classname
#print
'we have a node for class %s'
% classname
childobj
=
self
.
loadxmlobj
(
child
,
namespace
)
childobj
=
self
.
loadxmlobj
(
child
,
namespace
)
else
:
else
:
# it's a token
# it's a token
childobj
=
child
.
childNodes
[
0
].
nodeValue
childobj
=
child
.
childNodes
[
0
].
nodeValue
#print
"got token %s=%s"
% (childname, childobj)
#print
'got token %s=%s'
% (childname, childobj)
nodeobj
.
names
.
append
(
childname
)
nodeobj
.
names
.
append
(
childname
)
nodeobj
.
values
.
append
(
childobj
)
nodeobj
.
values
.
append
(
childobj
)
...
@@ -533,10 +548,9 @@ class BisonParser(object):
...
@@ -533,10 +548,9 @@ class BisonParser(object):
def
bisonToPython
(
bisonfileName
,
lexfileName
,
pyfileName
,
generateClasses
=
0
):
def
bisonToPython
(
bisonfileName
,
lexfileName
,
pyfileName
,
generateClasses
=
0
):
"""
"""
Rips the rules, tokens and precedences from a bison file, and the
Rips the rules, tokens and precedences from a bison file, and the verbatim
verbatim text from a lex file and generates
text from a lex file and generates a boilerplate python file containing a
a boilerplate python file containing a Parser class with handler
Parser class with handler methods and grammar attributes.
methods and grammar attributes
Arguments:
Arguments:
- bisonfileName - name of input bison script
- bisonfileName - name of input bison script
...
@@ -544,56 +558,60 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -544,56 +558,60 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
- pyfileName - name of output python file
- pyfileName - name of output python file
- generateClasses - flag - default 0 - if 1, causes a unique class to
- generateClasses - flag - default 0 - if 1, causes a unique class to
be defined for each parse target, and for the corresponding target
be defined for each parse target, and for the corresponding target
handler method in the main Parser class to use this class when
creating
handler method in the main Parser class to use this class when
the node.
creating
the node.
"""
"""
# try to create output file
# try to create output file
try
:
try
:
pyfile
=
file
(
pyfileName
,
"w"
)
pyfile
=
file
(
pyfileName
,
'w'
)
except
:
except
:
raise
Exception
(
"Cannot create output file '%s'"
%
pyfileName
)
raise
Exception
(
'Cannot create output file "%s"'
%
pyfileName
)
# try to open/read the bison file
# try to open/read the bison file
try
:
try
:
rawBison
=
file
(
bisonfileName
).
read
()
rawBison
=
file
(
bisonfileName
).
read
()
except
:
except
:
raise
Exception
(
"Cannot open bison file %s"
%
bisonfileName
)
raise
Exception
(
'Cannot open bison file "%s"'
%
bisonfileName
)
# try to open/read the lex file
# try to open/read the lex file
try
:
try
:
rawLex
=
file
(
lexfileName
).
read
()
rawLex
=
file
(
lexfileName
).
read
()
except
:
except
:
raise
Exception
(
"Cannot open lex file %s"
%
lexfileName
)
raise
Exception
(
'Cannot open lex file %s'
%
lexfileName
)
# break up into the three '%%'-separated sections
# break up into the three '%%'-separated sections
try
:
try
:
prologue
,
rulesRaw
,
epilogue
=
rawBison
.
split
(
"
\
n
%%
\
n
"
)
prologue
,
rulesRaw
,
epilogue
=
rawBison
.
split
(
'
\
n
%%
\
n
'
)
except
:
except
:
raise
Exception
(
raise
Exception
(
"File %s is not a properly formatted bison file"
'File %s is not a properly formatted bison file'
" (needs 3 sections separated by %%%%"
%
(
bisonfileName
)
' (needs 3 sections separated by %%%%'
%
(
bisonfileName
)
)
)
# --------------------------------------
# --------------------------------------
# process prologue
# process prologue
prologue
=
prologue
.
split
(
"%}"
)[
-
1
].
strip
()
# ditch the C code
prologue
=
prologue
.
split
(
'%}'
)[
-
1
].
strip
()
# ditch the C code
prologue
=
re
.
sub
(
"
\
\
n([
\
t
]+)"
,
" "
,
prologue
)
# join broken lines
prologue
=
re
.
sub
(
'
\
\
n([
\
t
]+)'
,
' '
,
prologue
)
# join broken lines
#prologueLines = [line.strip() for line in prologue.split(
"\n"
)]
#prologueLines = [line.strip() for line in prologue.split(
'\n'
)]
lines
=
prologue
.
split
(
"
\
n
"
)
lines
=
prologue
.
split
(
'
\
n
'
)
tmp
=
[]
tmp
=
[]
for
line
in
lines
:
for
line
in
lines
:
tmp
.
append
(
line
.
strip
())
tmp
.
append
(
line
.
strip
())
prologueLines
=
tmp
prologueLines
=
tmp
prologueLines
=
filter
(
None
,
prologueLines
)
prologueLines
=
filter
(
None
,
prologueLines
)
tokens
=
[]
tokens
=
[]
precRules
=
[]
precRules
=
[]
for
line
in
prologueLines
:
for
line
in
prologueLines
:
words
=
reSpaces
.
split
(
line
)
words
=
reSpaces
.
split
(
line
)
kwd
=
words
[
0
]
kwd
=
words
[
0
]
args
=
words
[
1
:]
args
=
words
[
1
:]
if
kwd
==
'%token'
:
if
kwd
==
'%token'
:
tokens
.
extend
(
args
)
tokens
.
extend
(
args
)
elif
kwd
in
[
'%left'
,
'%right'
,
'%nonassoc'
]:
elif
kwd
in
[
'%left'
,
'%right'
,
'%nonassoc'
]:
...
@@ -603,37 +621,29 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -603,37 +621,29 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
# -------------------------------------------------------------
# -------------------------------------------------------------
# process rules
# process rules
rulesRaw
=
re
.
sub
(
"
\
\
n([
\
t
]+)"
,
" "
,
rulesRaw
)
# join broken lines
rulesRaw
=
re
.
sub
(
'
\
\
n([
\
t
]+)'
,
' '
,
rulesRaw
)
# join broken lines
rulesLines
=
filter
(
''
,
map
(
str
.
strip
,
re
.
split
(
unquoted
%
';'
,
rulesRaw
)))
#rulesLines = filter(None, [r.strip() for r in rulesRaw.split(";")])
rulesLines
=
[]
#for r in rulesRaw.split(";"):
for
r
in
re
.
split
(
unquoted
%
";"
,
rulesRaw
):
r
=
r
.
strip
()
if
r
:
rulesLines
.
append
(
r
)
rules
=
[]
rules
=
[]
for
rule
in
rulesLines
:
for
rule
in
rulesLines
:
#print
"--"
#print
'--'
#print repr(rule)
#print repr(rule)
#tgt, terms = rule.split(
":"
)
#tgt, terms = rule.split(
':'
)
try
:
try
:
tgt
,
terms
=
re
.
split
(
unquoted
%
":"
,
rule
)
tgt
,
terms
=
re
.
split
(
unquoted
%
':'
,
rule
)
except
ValueError
:
except
ValueError
:
print
"Error in rule: %s"
%
rule
print
'Error in rule: %s'
%
rule
raise
raise
tgt
,
terms
=
tgt
.
strip
(),
terms
.
strip
()
tgt
,
terms
=
tgt
.
strip
(),
terms
.
strip
()
#terms = [t.strip() for t in terms.split(
"|"
)]
#terms = [t.strip() for t in terms.split(
'|'
)]
#terms = [reSpaces.split(t) for t in terms]
#terms = [reSpaces.split(t) for t in terms]
tmp
=
[]
tmp
=
[]
#for t in terms.split(
"|"
):
#for t in terms.split(
'|'
):
for
t
in
re
.
split
(
unquoted
%
r
"\
|
"
, terms):
for
t
in
re
.
split
(
unquoted
%
r
'\
|
'
, terms):
t = t.strip()
t = t.strip()
tmp.append(reSpaces.split(t))
tmp.append(reSpaces.split(t))
...
@@ -642,7 +652,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -642,7 +652,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
rules.append((tgt, terms))
rules.append((tgt, terms))
# now we have our rulebase, we can churn out our skeleton Python file
# now we have our rulebase, we can churn out our skeleton Python file
pyfile.write(
"
\
n
"
.join([
pyfile.write(
'
\
n
'
.join([
'
#!/usr/bin/env python',
'
#!/usr/bin/env python',
''
,
''
,
'"""'
,
'"""'
,
...
@@ -654,8 +664,8 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -654,8 +664,8 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
''
,
''
,
'from bison import BisonParser, BisonNode, BisonError'
,
'from bison import BisonParser, BisonNode, BisonError'
,
''
,
''
,
'bisonFile =
"
%
s
"
# original bison file' % bisonfileName,
'bisonFile =
\
'
%s
\
'
# original bison file'
%
bisonfileName
,
'lexFile =
"
%
s
"
# original flex file' % lexfileName,
'lexFile =
\
'
%s
\
'
# original flex file'
%
lexfileName
,
'
\
n
'
,
'
\
n
'
,
]))
]))
...
@@ -674,7 +684,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -674,7 +684,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
''
,
''
,
' def __str__(self):'
,
' def __str__(self):'
,
' """Customise as needed"""'
,
' """Customise as needed"""'
,
' return
"
<%
s
instance
at
0
x
%
x
>
"
% (self.__class__.__name__, hash(self))',
' return
\
'
<%s instance at 0x%x>
\
'
% (self.__class__.__name__, hash(self))'
,
''
,
''
,
' def __repr__(self):'
,
' def __repr__(self):'
,
' """Customise as needed"""'
,
' """Customise as needed"""'
,
...
@@ -695,9 +705,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -695,9 +705,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
# now spit out class decs for every parse target
# now spit out class decs for every parse target
for
target
,
options
in
rules
:
for
target
,
options
in
rules
:
tmp = []
tmp
=
map
(
' '
.
join
,
options
)
for t in options:
tmp.append("
".join(t))
# totally self-indulgent grammatical pedantry
# totally self-indulgent grammatical pedantry
if
target
[
0
].
lower
()
in
[
'a'
,
'e'
,
'i'
,
'o'
,
'u'
]:
if
target
[
0
].
lower
()
in
[
'a'
,
'e'
,
'i'
,
'o'
,
'u'
]:
...
@@ -720,7 +728,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -720,7 +728,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
# start churning out the class dec
# start churning out the class dec
pyfile.write(
"
\
n
"
.join([
pyfile
.
write
(
'
\
n
'
.
join
([
'class Parser(BisonParser):'
,
'class Parser(BisonParser):'
,
' """'
,
' """'
,
' bison Parser class generated automatically by bison2py from the'
,
' bison Parser class generated automatically by bison2py from the'
,
...
@@ -740,7 +748,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -740,7 +748,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
# add the default node class
# add the default node class
if
not
generateClasses
:
if
not
generateClasses
:
pyfile.write(
"
\
n
"
.join([
pyfile
.
write
(
'
\
n
'
.
join
([
' # -------------------------------------------------'
,
' # -------------------------------------------------'
,
' # Default class to use for creating new parse nodes'
,
' # Default class to use for creating new parse nodes'
,
' # -------------------------------------------------'
,
' # -------------------------------------------------'
,
...
@@ -749,22 +757,21 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -749,22 +757,21 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
]))
]))
# add the name of the dynamic library we need
# add the name of the dynamic library we need
libfileName = os.path.splitext(os.path.split(pyfileName)[1])[0] + "
-
engine
"
libfileName
=
os
.
path
.
splitext
(
os
.
path
.
split
(
pyfileName
)[
1
])[
0
]
\
pyfile.write("
\
n
".join([
+
'-engine'
pyfile
.
write
(
'
\
n
'
.
join
([
' # --------------------------------------------'
,
' # --------------------------------------------'
,
' # basename of binary parser engine dynamic lib'
,
' # basename of binary parser engine dynamic lib'
,
' # --------------------------------------------'
,
' # --------------------------------------------'
,
' bisonEngineLibName =
"
%
s
"
' % (parser.buildDirectory + libfileName),
' bisonEngineLibName =
\
'
%s
\
'
'
%
(
parser
.
buildDirectory
+
libfileName
),
'
\
n
'
,
'
\
n
'
,
]))
]))
# add the tokens
# add the tokens
#pyfile.write(' tokens = (%s,)
\
n
\
n
' % "
,
".join(['"
%
s
"' % t for t in tokens]))
#pyfile.write(' tokens = (%s,)\n\n' % ', '.join([''%s'' % t for t in tokens]))
tmp = []
toks
=
', '
.
join
(
tokens
)
for t in tokens:
#tmp.append('"'+t+'"')
tmp.append(t)
toks = "
,
".join(tmp)
pyfile
.
write
(
' # ----------------------------------------------------------------
\
n
'
)
pyfile
.
write
(
' # ----------------------------------------------------------------
\
n
'
)
pyfile
.
write
(
' # lexer tokens - these must match those in your lex script (below)
\
n
'
)
pyfile
.
write
(
' # lexer tokens - these must match those in your lex script (below)
\
n
'
)
pyfile
.
write
(
' # ----------------------------------------------------------------
\
n
'
)
pyfile
.
write
(
' # ----------------------------------------------------------------
\
n
'
)
...
@@ -776,59 +783,52 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -776,59 +783,52 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
pyfile
.
write
(
' # ------------------------------
\
n
'
)
pyfile
.
write
(
' # ------------------------------
\
n
'
)
pyfile
.
write
(
' precedences = (
\
n
'
)
pyfile
.
write
(
' precedences = (
\
n
'
)
for
prec
in
precRules
:
for
prec
in
precRules
:
tmp = []
precline
=
', '
.
join
(
prec
[
1
])
for p in prec[1]:
pyfile
.
write
(
' (
\
'
%s
\
'
, %s,),
\
n
'
%
(
#tmp.append('"'+p+'"')
tmp.append(p)
precline = "
,
".join(tmp)
#pyfile.write(' ("
%
s
", (%s,)),
\
n
' % (
pyfile.write(' ("
%
s
", %s,),
\
n
' % (
prec
[
0
][
1
:],
# left/right/nonassoc, quote-wrapped, no '%s'
prec
[
0
][
1
:],
# left/right/nonassoc, quote-wrapped, no '%s'
tmp
,
# quote-wrapped targets
tmp
,
# quote-wrapped targets
)
)
)
)
pyfile
.
write
(
' )
\
n
\
n
'
),
pyfile
.
write
(
' )
\
n
\
n
'
),
pyfile.write(
"
\
n
"
.join([
pyfile
.
write
(
'
\
n
'
.
join
([
' # ---------------------------------------------------------------'
,
' # ---------------------------------------------------------------'
,
' # Declare the start target here (by name)'
,
' # Declare the start target here (by name)'
,
' # ---------------------------------------------------------------'
,
' # ---------------------------------------------------------------'
,
' start =
"
%
s
"
' % startTarget,
' start =
\
'
%s
\
'
'
%
startTarget
,
'
\
n
'
,
'
\
n
'
,
]))
]))
# now the interesting bit - write the rule handler methods
# now the interesting bit - write the rule handler methods
pyfile.write(
"
\
n
"
.join([
pyfile
.
write
(
'
\
n
'
.
join
([
' # ---------------------------------------------------------------'
,
' # ---------------------------------------------------------------'
,
' # These methods are the python handlers for the bison targets.'
,
' # These methods are the python handlers for the bison targets.'
,
' # (which get called by the bison code each time the corresponding'
,
' # (which get called by the bison code each time the corresponding'
,
' # parse target is unambiguously reached)'
,
' # parse target is unambiguously reached)'
,
' #'
,
' #'
,
"
# WARNING - don't touch the method docstrings unless you know what"
,
' # WARNING - don
\
'
t touch the method docstrings unless you know what'
,
" # you are doing - they are in bison rule syntax, and are passed"
,
' # you are doing - they are in bison rule syntax, and are passed'
,
" # verbatim to bison to build the parser engine library."
,
' # verbatim to bison to build the parser engine library.'
,
' # ---------------------------------------------------------------'
,
' # ---------------------------------------------------------------'
,
'
\
n
'
,
'
\
n
'
,
]))
]))
for
target
,
options
in
rules
:
for
target
,
options
in
rules
:
tmp
=
[]
tmp
=
map
(
' '
.
join
,
options
)
for
t
in
options
:
tmp
.
append
(
" "
.
join
(
t
))
if
generateClasses
:
if
generateClasses
:
nodeClassName
=
target
+
"_Node"
nodeClassName
=
target
+
'_Node'
else
:
else
:
nodeClassName
=
'self.defaultNodeClass'
nodeClassName
=
'self.defaultNodeClass'
pyfile
.
write
(
"
\
n
"
.
join
([
pyfile
.
write
(
'
\
n
'
.
join
([
' def on_%s(self, target, option, names, values):'
%
target
,
' def on_%s(self, target, option, names, values):'
%
target
,
' """'
,
' """'
,
' %s'
%
target
,
' %s'
%
target
,
' : '
+
"
\
n
| "
.
join
(
tmp
),
' : '
+
'
\
n
| '
.
join
(
tmp
),
' """'
,
' """'
,
' return %s('
%
nodeClassName
,
' return %s('
%
nodeClassName
,
' target=
"%s"
,'
%
target
,
' target=
\
'
%s
\
'
,'
%
target
,
' option=option,'
,
' option=option,'
,
' names=names,'
,
' names=names,'
,
' values=values)'
,
' values=values)'
,
...
@@ -836,7 +836,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -836,7 +836,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
]))
]))
# now the ugly bit - add the raw lex script
# now the ugly bit - add the raw lex script
pyfile
.
write
(
"
\
n
"
.
join
([
pyfile
.
write
(
'
\
n
'
.
join
([
' # -----------------------------------------'
,
' # -----------------------------------------'
,
' # raw lex script, verbatim here'
,
' # raw lex script, verbatim here'
,
' # -----------------------------------------'
,
' # -----------------------------------------'
,
...
@@ -851,14 +851,14 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -851,14 +851,14 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
]))
]))
# and now, create a main for testing which either reads stdin, or a filename arg
# and now, create a main for testing which either reads stdin, or a filename arg
pyfile
.
write
(
"
\
n
"
.
join
([
pyfile
.
write
(
'
\
n
'
.
join
([
'def usage():'
,
'def usage():'
,
' print
"%s: PyBison parser derived from %s and %s"
% (sys.argv[0], bisonFile, lexFile)'
,
' print
\
'
%s: PyBison parser derived from %s and %s
\
'
% (sys.argv[0], bisonFile, lexFile)'
,
' print
"Usage: %s [-k] [-v] [-d] [filename]"
% sys.argv[0]'
,
' print
\
'
Usage: %s [-k] [-v] [-d] [filename]
\
'
% sys.argv[0]'
,
' print
" -k Keep temporary files used in building parse engine lib"
'
,
' print
\
'
-k Keep temporary files used in building parse engine lib
\
'
'
,
' print
" -v Enable verbose messages while parser is running"
'
,
' print
\
'
-v Enable verbose messages while parser is running
\
'
'
,
' print
" -d Enable garrulous debug messages from parser engine"
'
,
' print
\
'
-d Enable garrulous debug messages from parser engine
\
'
'
,
' print
" filename path of a file to parse, defaults to stdin"
'
,
' print
\
'
filename path of a file to parse, defaults to stdin
\
'
'
,
''
,
''
,
'def main(*args):'
,
'def main(*args):'
,
' """'
,
' """'
,
...
@@ -870,21 +870,21 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -870,21 +870,21 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
' debug = 0'
,
' debug = 0'
,
' filename = None'
,
' filename = None'
,
''
,
''
,
' for s in [
"-h", "-help", "--h", "--help", "-?"
]:'
,
' for s in [
\
'
-h
\
'
,
\
'
-help
\
'
,
\
'
--h
\
'
,
\
'
--help
\
'
,
\
'
-?
\
'
]:'
,
' if s in args:'
,
' if s in args:'
,
' usage()'
,
' usage()'
,
' sys.exit(0)'
,
' sys.exit(0)'
,
''
,
''
,
' if len(args) > 0:'
,
' if len(args) > 0:'
,
' if
"-k"
in args:'
,
' if
\
'
-k
\
'
in args:'
,
' keepfiles = 1'
,
' keepfiles = 1'
,
' args.remove(
"-k"
)'
,
' args.remove(
\
'
-k
\
'
)'
,
' if
"-v"
in args:'
,
' if
\
'
-v
\
'
in args:'
,
' verbose = 1'
,
' verbose = 1'
,
' args.remove(
"-v"
)'
,
' args.remove(
\
'
-v
\
'
)'
,
' if
"-d"
in args:'
,
' if
\
'
-d
\
'
in args:'
,
' debug = 1'
,
' debug = 1'
,
' args.remove(
"-d"
)'
,
' args.remove(
\
'
-d
\
'
)'
,
' if len(args) > 0:'
,
' if len(args) > 0:'
,
' filename = args[0]'
,
' filename = args[0]'
,
''
,
''
,
...
@@ -892,7 +892,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
...
@@ -892,7 +892,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
' tree = p.run(file=filename, debug=debug)'
,
' tree = p.run(file=filename, debug=debug)'
,
' return tree'
,
' return tree'
,
''
,
''
,
'if __name__ ==
"__main__"
:'
,
'if __name__ ==
\
'
__main__
\
'
:'
,
' main(*(sys.argv[1:]))'
,
' main(*(sys.argv[1:]))'
,
''
,
''
,
''
,
''
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment