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.
This commit is contained in:
parent
831e9b3b7a
commit
da1eaaca0e
|
@ -1,6 +1,8 @@
|
|||
MESI_CMP_directory-msg.sm
|
||||
MESI_CMP_directory-L1cache.sm
|
||||
MESI_CMP_directory-L2cache.sm
|
||||
MESI_CMP_directory-dir.sm
|
||||
MESI_CMP_directory-dma.sm
|
||||
standard_CMP-protocol.sm
|
||||
protocol "MESI_CMP_directory";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MESI_CMP_directory-msg.sm";
|
||||
include "MESI_CMP_directory-L1cache.sm";
|
||||
include "MESI_CMP_directory-L2cache.sm";
|
||||
include "MESI_CMP_directory-dir.sm";
|
||||
include "MESI_CMP_directory-dma.sm";
|
||||
include "standard_CMP-protocol.sm";
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
MI_example-msg.sm
|
||||
MI_example-cache.sm
|
||||
MI_example-dir.sm
|
||||
MI_example-dma.sm
|
||||
standard_1level_CMP-protocol.sm
|
||||
protocol "MI_example";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MI_example-msg.sm";
|
||||
include "MI_example-cache.sm";
|
||||
include "MI_example-dir.sm";
|
||||
include "MI_example-dma.sm";
|
||||
include "standard_1level_CMP-protocol.sm";
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
MOESI_CMP_directory-msg.sm
|
||||
MOESI_CMP_directory-L2cache.sm
|
||||
MOESI_CMP_directory-L1cache.sm
|
||||
MOESI_CMP_directory-dma.sm
|
||||
MOESI_CMP_directory-dir.sm
|
||||
standard_CMP-protocol.sm
|
||||
protocol "MOESI_CMP_directory";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_CMP_directory-msg.sm";
|
||||
include "MOESI_CMP_directory-L2cache.sm";
|
||||
include "MOESI_CMP_directory-L1cache.sm";
|
||||
include "MOESI_CMP_directory-dma.sm";
|
||||
include "MOESI_CMP_directory-dir.sm";
|
||||
include "standard_CMP-protocol.sm";
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
MOESI_CMP_token-msg.sm
|
||||
MOESI_CMP_token-L1cache.sm
|
||||
MOESI_CMP_token-L2cache.sm
|
||||
MOESI_CMP_token-dir.sm
|
||||
MOESI_CMP_token-dma.sm
|
||||
standard_CMP-protocol.sm
|
||||
protocol "MOESI_CMP_token";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_CMP_token-msg.sm";
|
||||
include "MOESI_CMP_token-L1cache.sm";
|
||||
include "MOESI_CMP_token-L2cache.sm";
|
||||
include "MOESI_CMP_token-dir.sm";
|
||||
include "MOESI_CMP_token-dma.sm";
|
||||
include "standard_CMP-protocol.sm";
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
MOESI_hammer-msg.sm
|
||||
MOESI_hammer-cache.sm
|
||||
MOESI_hammer-dir.sm
|
||||
MOESI_hammer-dma.sm
|
||||
standard_1level_CMP-protocol.sm
|
||||
protocol "MOESI_hammer";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "MOESI_hammer-msg.sm";
|
||||
include "MOESI_hammer-cache.sm";
|
||||
include "MOESI_hammer-dir.sm";
|
||||
include "MOESI_hammer-dma.sm";
|
||||
include "standard_1level_CMP-protocol.sm";
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
Network_test-msg.sm
|
||||
Network_test-cache.sm
|
||||
Network_test-dir.sm
|
||||
standard_1level_CMP-protocol.sm
|
||||
protocol "Network_test";
|
||||
include "RubySlicc_interfaces.slicc";
|
||||
include "Network_test-msg.sm";
|
||||
include "Network_test-cache.sm";
|
||||
include "Network_test-dir.sm";
|
||||
include "standard_1level_CMP-protocol.sm";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
RubySlicc_Exports.sm
|
||||
RubySlicc_Types.sm
|
||||
RubySlicc_Util.sm
|
||||
RubySlicc_ComponentMapping.sm
|
||||
RubySlicc_Profiler.sm
|
||||
RubySlicc_Defines.sm
|
||||
RubySlicc_MemControl.sm
|
||||
include "RubySlicc_Exports.sm";
|
||||
include "RubySlicc_Types.sm";
|
||||
include "RubySlicc_Util.sm";
|
||||
include "RubySlicc_ComponentMapping.sm";
|
||||
include "RubySlicc_Profiler.sm";
|
||||
include "RubySlicc_Defines.sm";
|
||||
include "RubySlicc_MemControl.sm";
|
||||
|
|
|
@ -63,10 +63,10 @@ slicc_scanner = Classic("SliccScanner", ['.sm', '.slicc'], "SLICC_PATH",
|
|||
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, verbose=False)
|
||||
slicc.load(files)
|
||||
assert len(source) == 1
|
||||
filepath = source[0].srcnode().abspath
|
||||
|
||||
slicc = SLICC(filepath, verbose=False)
|
||||
slicc.process()
|
||||
slicc.writeCodeFiles(protocol_dir.abspath)
|
||||
if not env['NO_HTML']:
|
||||
|
@ -76,10 +76,10 @@ def slicc_emitter(target, source, env):
|
|||
return target, source
|
||||
|
||||
def slicc_action(target, source, env):
|
||||
protocol = source[0].get_contents()
|
||||
files = [s.srcnode().abspath for s in source[1:]]
|
||||
slicc = SLICC(protocol, verbose=True)
|
||||
slicc.load(files)
|
||||
assert len(source) == 1
|
||||
filepath = source[0].srcnode().abspath
|
||||
|
||||
slicc = SLICC(filepath, verbose=True)
|
||||
slicc.process()
|
||||
slicc.writeCodeFiles(protocol_dir.abspath)
|
||||
if not env['NO_HTML']:
|
||||
|
@ -89,11 +89,10 @@ slicc_builder = Builder(action=MakeAction(slicc_action, Transform("SLICC")),
|
|||
emitter=slicc_emitter)
|
||||
|
||||
protocol = env['PROTOCOL']
|
||||
sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"),
|
||||
protocol_dir.File("%s.slicc" % protocol) ]
|
||||
sources = [ protocol_dir.File("%s.slicc" % protocol) ]
|
||||
|
||||
env.Append(BUILDERS={'SLICC' : slicc_builder})
|
||||
nodes = env.SLICC([], [ Value(protocol) ] + sources)
|
||||
nodes = env.SLICC([], sources)
|
||||
env.Depends(nodes, slicc_depends)
|
||||
|
||||
for f in nodes:
|
||||
|
|
|
@ -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()):
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in a new issue