summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/protocol/SConscript88
-rw-r--r--src/mem/slicc/ast/AST.py2
-rw-r--r--src/mem/slicc/main.py22
-rw-r--r--src/mem/slicc/parser.py32
-rw-r--r--src/mem/slicc/symbols/SymbolTable.py12
-rw-r--r--src/mem/slicc/util.py20
6 files changed, 66 insertions, 110 deletions
diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript
index 5f64938c6..47a19aecb 100644
--- a/src/mem/protocol/SConscript
+++ b/src/mem/protocol/SConscript
@@ -29,10 +29,13 @@
# Authors: Nathan Binkert
import os
+import re
import sys
from os.path import isdir, isfile, join as joinpath
+from SCons.Scanner import Classic
+
Import('*')
if not env['RUBY']:
@@ -54,77 +57,36 @@ for root,dirs,files in os.walk(slicc_dir.srcnode().abspath):
#
# Use SLICC
#
-
-def slicc_scanner(node, env, path):
- contents = node.get_contents()
- files = [ line.strip() for line in contents.splitlines() if line ]
- return files
-
-env.Append(SCANNERS=Scanner(function=slicc_scanner,skeys=['.slicc']))
+env['SLICC_PATH'] = str(protocol_dir)
+slicc_scanner = Classic("SliccScanner", ['.sm', '.slicc'], "SLICC_PATH",
+ r'''include[ \t]["'](.*)["'];''')
+env.Append(SCANNERS=slicc_scanner)
def slicc_emitter(target, source, env):
protocol = source[0].get_contents()
files = [s.srcnode().abspath for s in source[1:]]
- slicc = SLICC(protocol, debug=True)
- print "SLICC parsing..."
- for name in slicc.load(files, verbose=True):
- print " %s" % name
-
- target.extend(sorted(slicc.files()))
- pdir = str(protocol_dir)
- hdir = str(html_dir)
-
- if not isdir(pdir):
- os.mkdir(pdir)
- if not isdir(hdir):
- os.mkdir(hdir)
-
- print "SLICC Generator pass 1..."
- slicc.findMachines()
-
- print "SLICC Generator pass 2..."
- slicc.generate()
-
- print "SLICC writing C++ files..."
- slicc.writeCodeFiles(pdir)
-
- if env['NO_HTML']:
- print "skipping HTML file creation"
- else:
- print "SLICC writing HTML files..."
- slicc.writeHTMLFiles(hdir)
+ slicc = SLICC(protocol, verbose=False)
+ slicc.load(files)
+ slicc.process()
+ slicc.writeCodeFiles(protocol_dir.abspath)
+ if not env['NO_HTML']:
+ slicc.writeHTMLFiles(html_dir.abspath)
+
+ target.extend([protocol_dir.File(f) for f in sorted(slicc.files())])
return target, source
def slicc_action(target, source, env):
protocol = source[0].get_contents()
- pdir = str(protocol_dir)
- hdir = str(html_dir)
-
- if not isdir(pdir):
- os.mkdir(pdir)
- if not isdir(hdir):
- os.mkdir(hdir)
-
- slicc = SLICC(protocol, debug=True)
- files = [str(s) for s in source[1:]]
- slicc.load(files, verbose=False)
-
- print "SLICC Generator pass 1..."
- slicc.findMachines()
-
- print "SLICC Generator pass 2..."
- slicc.generate()
-
- print "SLICC writing C++ files..."
- slicc.writeCodeFiles(pdir)
-
- if env['NO_HTML']:
- print "skipping HTML file creation"
- else:
- print "SLICC writing HTML files..."
- slicc.writeHTMLFiles(hdir)
-
-slicc_builder = Builder(action=slicc_action, emitter=slicc_emitter)
+ files = [s.srcnode().abspath for s in source[1:]]
+ slicc = SLICC(protocol, verbose=True)
+ slicc.load(files)
+ slicc.process()
+ slicc.writeCodeFiles(protocol_dir.abspath)
+ if not env['NO_HTML']:
+ slicc.writeHTMLFiles(html_dir.abspath)
+
+slicc_builder = Builder(action=MakeAction(slicc_action, Transform("SLICC")),
+ emitter=slicc_emitter)
protocol = env['PROTOCOL']
sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"),
diff --git a/src/mem/slicc/ast/AST.py b/src/mem/slicc/ast/AST.py
index d098c8642..b74867114 100644
--- a/src/mem/slicc/ast/AST.py
+++ b/src/mem/slicc/ast/AST.py
@@ -30,7 +30,7 @@ from slicc.util import PairContainer, Location
class AST(PairContainer):
def __init__(self, slicc, pairs=None):
self.slicc = slicc
- self.location = Location(slicc.current_source, slicc.current_line)
+ self.location = slicc.currentLocation()
self.pairs = {}
if pairs:
self.pairs.update(getattr(pairs, "pairs", pairs))
diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py
index f8efcc323..15eb9d4be 100644
--- a/src/mem/slicc/main.py
+++ b/src/mem/slicc/main.py
@@ -60,6 +60,8 @@ def main(args=None):
help="Path where html output goes")
parser.add_option("-F", "--print-files",
help="Print files that SLICC will generate")
+ parser.add_option("--tb", "--traceback", action='store_true',
+ help="print traceback on error")
parser.add_option("-q", "--quiet",
help="don't print messages")
opts,files = parser.parse_args(args=args)
@@ -71,30 +73,26 @@ def main(args=None):
output = nprint if opts.quiet else eprint
output("SLICC v0.4")
- slicc = SLICC(debug=opts.debug)
-
output("Parsing...")
- for filename in slicc.load(files, verbose=True):
- output(" %s", filename)
+
+ slicc = SLICC(debug=opts.debug)
+ slicc.load(files)
if opts.print_files:
for i in sorted(slicc.files()):
print ' %s' % i
else:
- output("Generator pass 1...")
- slicc.findMachines()
-
- output("Generator pass 2...")
- slicc.generate()
+ output("Processing AST...")
+ slicc.process()
- output("Generating C++ files...")
+ output("Writing C++ files...")
slicc.writeCodeFiles(opts.code_path)
if opts.html_path:
- nprint("Writing HTML files...")
+ output("Writing HTML files...")
slicc.writeHTMLFiles(opts.html_path)
- eprint("SLICC is Done.")
+ output("SLICC is Done.")
if __name__ == "__main__":
main()
diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py
index eb10c2dc4..596b89f64 100644
--- a/src/mem/slicc/parser.py
+++ b/src/mem/slicc/parser.py
@@ -51,11 +51,16 @@ def read_slicc(sources):
yield sm_file
class SLICC(Grammar):
- def __init__(self, protocol, **kwargs):
+ def __init__(self, protocol, verbose=False):
self.decl_list_vec = []
self.protocol = protocol
+ self.verbose = verbose
self.symtab = SymbolTable(self)
+ def currentLocation(self):
+ return util.Location(self.current_source, self.current_line,
+ no_warning=not self.verbose)
+
def codeFormatter(self, *args, **kwargs):
code = code_formatter(*args, **kwargs)
code['protocol'] = self.protocol
@@ -68,7 +73,7 @@ class SLICC(Grammar):
sys.exit(str(e))
self.decl_list_vec.append(decl_list)
- def _load(self, *filenames):
+ def load(self, filenames):
filenames = list(filenames)
while filenames:
f = filenames.pop(0)
@@ -76,7 +81,6 @@ class SLICC(Grammar):
filenames[0:0] = list(f)
continue
- yield f
if f.endswith(".slicc"):
dirname,basename = os.path.split(f)
filenames[0:0] = [ os.path.join(dirname, x) \
@@ -85,34 +89,18 @@ class SLICC(Grammar):
assert f.endswith(".sm")
self.parse(f)
- def load(self, *filenames, **kwargs):
- verbose = kwargs.pop("verbose", False)
- if kwargs:
- raise TypeError
-
- gen = self._load(*filenames)
- if verbose:
- return gen
- else:
- # Run out the generator if we don't want the verbosity
- for foo in gen:
- pass
-
- def findMachines(self):
+ def process(self):
for decl_list in self.decl_list_vec:
decl_list.findMachines()
- def generate(self):
for decl_list in self.decl_list_vec:
decl_list.generate()
def writeCodeFiles(self, code_path):
- util.makeDir(code_path)
self.symtab.writeCodeFiles(code_path)
- def writeHTMLFiles(self, code_path):
- util.makeDir(code_path)
- self.symtab.writeHTMLFiles(code_path)
+ def writeHTMLFiles(self, html_path):
+ self.symtab.writeHTMLFiles(html_path)
def files(self):
f = set([
diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py
index dd45ac06c..81d0768f9 100644
--- a/src/mem/slicc/symbols/SymbolTable.py
+++ b/src/mem/slicc/symbols/SymbolTable.py
@@ -25,7 +25,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-from m5.util import code_formatter
+from m5.util import makeDir
from slicc.generate import html
from slicc.symbols.StateMachine import StateMachine
@@ -42,13 +42,15 @@ class SymbolTable(object):
pairs = {}
pairs["enumeration"] = "yes"
- MachineType = Type(self, "MachineType", Location("init", 0), pairs)
+ location = Location("init", 0, no_warning=not slicc.verbose)
+ MachineType = Type(self, "MachineType", location, pairs)
self.newSymbol(MachineType)
pairs = {}
pairs["primitive"] = "yes"
pairs["external"] = "yes"
- void = Type(self, "void", Location("init", 0), pairs)
+ location = Location("init", 0, no_warning=not slicc.verbose)
+ void = Type(self, "void", location, pairs)
self.newSymbol(void)
def __repr__(self):
@@ -123,6 +125,8 @@ class SymbolTable(object):
yield symbol
def writeCodeFiles(self, path):
+ makeDir(path)
+
code = self.codeFormatter()
code('''
/** Auto generated C++ code started by $__file__:$__line__ */
@@ -139,6 +143,8 @@ class SymbolTable(object):
symbol.writeCodeFiles(path)
def writeHTMLFiles(self, path):
+ makeDir(path)
+
machines = list(self.getAllType(StateMachine))
if len(machines) > 1:
name = "%s_table.html" % machines[0].ident
diff --git a/src/mem/slicc/util.py b/src/mem/slicc/util.py
index abadc3e30..83badf46d 100644
--- a/src/mem/slicc/util.py
+++ b/src/mem/slicc/util.py
@@ -27,13 +27,6 @@
import os
import sys
-def makeDir(path):
- if os.path.exists(path):
- if not os.path.isdir(path):
- raise AttributeError, "%s exists but is not directory" % path
- else:
- os.mkdir(path)
-
class PairContainer(object):
def __init__(self, pairs=None):
self.pairs = {}
@@ -53,14 +46,23 @@ class PairContainer(object):
return self.pairs.get(item, failobj)
class Location(object):
- def __init__(self, filename, lineno):
+ def __init__(self, filename, lineno, no_warning=False):
+ if not isinstance(filename, basestring):
+ raise AttributeError, \
+ "filename must be a string, found '%s'" % (type(filename), )
+ if not isinstance(lineno, (int, long)):
+ raise AttributeError, \
+ "filename must be an integer, found '%s'" % (type(lineno), )
self.filename = filename
self.lineno = lineno
+ self.no_warning = no_warning
def __str__(self):
return '%s:%d' % (os.path.basename(self.filename), self.lineno)
def warning(self, message, *args):
+ if self.no_warning:
+ return
if args:
message = message % args
#raise Exception, "%s: Warning: %s" % (self, message)
@@ -72,4 +74,4 @@ class Location(object):
raise Exception, "%s: Error: %s" % (self, message)
sys.exit("\n%s: Error: %s" % (self, message))
-__all__ = [ 'makeDir', 'PairContainer', 'Location' ]
+__all__ = [ 'PairContainer', 'Location' ]