From da1eaaca0ec7f65525dd2706f4b6b207bf9ee691 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 5 Jul 2011 18:30:05 -0700 Subject: slicc: add a protocol statement and an include statement All protocols must specify their name The include statement allows any file to include another file. --- src/mem/slicc/main.py | 5 ++- src/mem/slicc/parser.py | 84 ++++++++++++++++++++++--------------------------- 2 files changed, 39 insertions(+), 50 deletions(-) (limited to 'src/mem/slicc') diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py index 15eb9d4be..0b528d805 100644 --- a/src/mem/slicc/main.py +++ b/src/mem/slicc/main.py @@ -66,7 +66,7 @@ def main(args=None): help="don't print messages") opts,files = parser.parse_args(args=args) - if len(files) < 1: + if len(files) != 1: parser.print_help() sys.exit(2) @@ -75,8 +75,7 @@ def main(args=None): output("SLICC v0.4") output("Parsing...") - slicc = SLICC(debug=opts.debug) - slicc.load(files) + slicc = SLICC(files[0], verbose=True, debug=opts.debug, traceback=opts.tb) if opts.print_files: for i in sorted(slicc.files()): diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index 596b89f64..f35a3691a 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -37,26 +37,20 @@ import slicc.ast as ast import slicc.util as util from slicc.symbols import SymbolTable -def read_slicc(sources): - if not isinstance(sources, (list,tuple)): - sources = [ sources ] - - for source in sources: - for sm_file in file(source, "r"): - sm_file = sm_file.strip() - if not sm_file: - continue - if sm_file.startswith("#"): - continue - yield sm_file - class SLICC(Grammar): - def __init__(self, protocol, verbose=False): - self.decl_list_vec = [] - self.protocol = protocol + def __init__(self, filename, verbose=False, traceback=False, **kwargs): + self.protocol = None + self.traceback = traceback self.verbose = verbose self.symtab = SymbolTable(self) + try: + self.decl_list = self.parse_file(filename, **kwargs) + except ParseError, e: + if not self.traceback: + sys.exit(str(e)) + raise + def currentLocation(self): return util.Location(self.current_source, self.current_line, no_warning=not self.verbose) @@ -66,35 +60,9 @@ class SLICC(Grammar): code['protocol'] = self.protocol return code - def parse(self, filename): - try: - decl_list = self.parse_file(filename) - except ParseError, e: - sys.exit(str(e)) - self.decl_list_vec.append(decl_list) - - def load(self, filenames): - filenames = list(filenames) - while filenames: - f = filenames.pop(0) - if isinstance(f, (list, tuple)): - filenames[0:0] = list(f) - continue - - if f.endswith(".slicc"): - dirname,basename = os.path.split(f) - filenames[0:0] = [ os.path.join(dirname, x) \ - for x in read_slicc(f)] - else: - assert f.endswith(".sm") - self.parse(f) - def process(self): - for decl_list in self.decl_list_vec: - decl_list.findMachines() - - for decl_list in self.decl_list_vec: - decl_list.generate() + self.decl_list.findMachines() + self.decl_list.generate() def writeCodeFiles(self, code_path): self.symtab.writeCodeFiles(code_path) @@ -108,8 +76,7 @@ class SLICC(Grammar): 'MachineType.hh', 'Types.hh' ]) - for decl_list in self.decl_list_vec: - f |= decl_list.files() + f |= self.decl_list.files() return f @@ -129,6 +96,8 @@ class SLICC(Grammar): t.lexer.lineno += len(t.value) reserved = { + 'protocol' : 'PROTOCOL', + 'include' : 'INCLUDE', 'global' : 'GLOBAL', 'machine' : 'MACHINE', 'in_port' : 'IN_PORT', @@ -256,12 +225,33 @@ class SLICC(Grammar): def p_declsx__list(self, p): "declsx : decl declsx" - p[0] = [ p[1] ] + p[2] + if isinstance(p[1], ast.DeclListAST): + decls = p[1].decls + elif p[1] is None: + decls = [] + else: + decls = [ p[1] ] + p[0] = decls + p[2] def p_declsx__none(self, p): "declsx : empty" p[0] = [] + def p_decl__protocol(self, p): + "decl : PROTOCOL STRING SEMI" + if self.protocol: + msg = "Protocol can only be set once! Error at %s:%s\n" % \ + (self.current_source, self.current_line) + raise ParseError(msg) + self.protocol = p[2] + p[0] = None + + def p_decl__include(self, p): + "decl : INCLUDE STRING SEMI" + dirname = os.path.dirname(self.current_source) + filename = os.path.join(dirname, p[2]) + p[0] = self.parse_file(filename) + def p_decl__machine(self, p): "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'" p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) -- cgit v1.2.3