source: mainline/contrib/arch/hadlbppp.py@ 338d0935

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 338d0935 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100755
File size: 45.1 KB
RevLine 
[e742429]1#!/usr/bin/env python
2#
3# Copyright (c) 2009 Martin Decky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29"""
[07fdf203]30HelenOS Architecture Description Language and Behavior Protocols preprocessor
[e742429]31"""
32
33import sys
34import os
35
[2a70672]36INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
[3037384]37 INST, VAR, FIN, BIND, TO, SUBSUME, DELEGATE, IFACE, EXTENDS, PRE_BODY, \
[6d4c549]38 PROTOTYPE, PAR_LEFT, PAR_RIGHT, SIGNATURE, PROTOCOL, INITIALIZATION, \
39 FINALIZATION, FRAME, PROVIDES, REQUIRES = range(29)
[2a70672]40
[e742429]41def usage(prname):
42 "Print usage syntax"
[a35b458]43
[28f4adb]44 print("%s <--bp|--ebp|--adl|--dot|--nop>+ <OUTPUT>" % prname)
45 print()
46 print("--bp Dump original Behavior Protocols (dChecker, BPSlicer)")
47 print("--ebp Dump Extended Behavior Protocols (bp2promela)")
48 print("--adl Dump Architecture Description Language (modified SOFA ADL/CDL)")
49 print("--dot Dump Dot architecture diagram (GraphViz)")
50 print("--nop Do not dump anything (just input files syntax check)")
51 print()
[e742429]52
53def tabs(cnt):
54 "Return given number of tabs"
[a35b458]55
[e742429]56 return ("\t" * cnt)
57
58def cond_append(tokens, token, trim):
59 "Conditionally append token to tokens with trim"
[a35b458]60
[e742429]61 if (trim):
62 token = token.strip(" \t")
[a35b458]63
[1993f9a]64 if (token != ""):
[e742429]65 tokens.append(token)
[a35b458]66
[e742429]67 return tokens
68
[1993f9a]69def split_tokens(string, delimiters, trim = False, separate = False):
[e742429]70 "Split string to tokens by delimiters, keep the delimiters"
[a35b458]71
[e742429]72 tokens = []
73 last = 0
74 i = 0
[a35b458]75
[e742429]76 while (i < len(string)):
77 for delim in delimiters:
78 if (len(delim) > 0):
[a35b458]79
[1993f9a]80 if (string[i:(i + len(delim))] == delim):
81 if (separate):
82 tokens = cond_append(tokens, string[last:i], trim)
83 tokens = cond_append(tokens, delim, trim)
84 last = i + len(delim)
85 elif (i > 0):
86 tokens = cond_append(tokens, string[last:i], trim)
87 last = i
[a35b458]88
[e742429]89 i += len(delim) - 1
90 break
[a35b458]91
[e742429]92 i += 1
[a35b458]93
[e742429]94 tokens = cond_append(tokens, string[last:len(string)], trim)
[a35b458]95
[e742429]96 return tokens
97
[2a70672]98def identifier(token):
99 "Check whether the token is an identifier"
[a35b458]100
[2a70672]101 if (len(token) == 0):
102 return False
[a35b458]103
[2a70672]104 for i, char in enumerate(token):
105 if (i == 0):
106 if ((not char.isalpha()) and (char != "_")):
107 return False
108 else:
109 if ((not char.isalnum()) and (char != "_")):
110 return False
[a35b458]111
[2a70672]112 return True
113
114def descriptor(token):
115 "Check whether the token is an interface descriptor"
[a35b458]116
[2a70672]117 parts = token.split(":")
118 if (len(parts) != 2):
119 return False
[a35b458]120
[2a70672]121 return (identifier(parts[0]) and identifier(parts[1]))
122
123def word(token):
124 "Check whether the token is a word"
[a35b458]125
[2a70672]126 if (len(token) == 0):
127 return False
[a35b458]128
[2a70672]129 for i, char in enumerate(token):
130 if ((not char.isalnum()) and (char != "_") and (char != ".")):
131 return False
[a35b458]132
[2a70672]133 return True
134
[51d4040]135def tentative_bp(name, tokens):
[ee5b35a]136 "Preprocess tentative statements in Behavior Protocol"
[a35b458]137
[ee5b35a]138 result = []
139 i = 0
[a35b458]140
[ee5b35a]141 while (i < len(tokens)):
142 if (tokens[i] == "tentative"):
143 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
144 i += 2
145 start = i
146 level = 1
[a35b458]147
[ee5b35a]148 while ((i < len(tokens)) and (level > 0)):
149 if (tokens[i] == "{"):
150 level += 1
151 elif (tokens[i] == "}"):
152 level -= 1
[a35b458]153
[ee5b35a]154 i += 1
[a35b458]155
[ee5b35a]156 if (level == 0):
157 result.append("(")
[51d4040]158 result.extend(tentative_bp(name, tokens[start:(i - 1)]))
[ee5b35a]159 result.append(")")
160 result.append("+")
161 result.append("NULL")
162 if (i < len(tokens)):
163 result.append(tokens[i])
164 else:
[28f4adb]165 print("%s: Syntax error in tentative statement" % name)
[ee5b35a]166 else:
[28f4adb]167 print("%s: Expected '{' for tentative statement" % name)
[51d4040]168 else:
169 result.append(tokens[i])
[a35b458]170
[51d4040]171 i += 1
[a35b458]172
[51d4040]173 return result
174
175def alternative_bp(name, tokens):
176 "Preprocess alternative statements in Behavior Protocol"
[a35b458]177
[51d4040]178 result = []
179 i = 0
[a35b458]180
[51d4040]181 while (i < len(tokens)):
182 if (tokens[i] == "alternative"):
183 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "(")):
184 i += 2
185 reps = []
[a35b458]186
[51d4040]187 while ((i < len(tokens)) and (tokens[i] != ")")):
188 reps.append(tokens[i])
189 if ((i + 1 < len(tokens)) and (tokens[i + 1] == ";")):
190 i += 2
191 else:
192 i += 1
[a35b458]193
[51d4040]194 if (len(reps) >= 2):
195 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
196 i += 2
[a35b458]197
[51d4040]198 start = i
199 level = 1
[a35b458]200
[51d4040]201 while ((i < len(tokens)) and (level > 0)):
202 if (tokens[i] == "{"):
203 level += 1
204 elif (tokens[i] == "}"):
205 level -= 1
[a35b458]206
[51d4040]207 i += 1
[a35b458]208
[51d4040]209 if (level == 0):
210 first = True
[a35b458]211
[51d4040]212 for rep in reps[1:]:
213 retokens = []
214 for token in tokens[start:(i - 1)]:
215 parts = token.split(".")
216 if ((len(parts) == 2) and (parts[0] == reps[0])):
217 retokens.append("%s.%s" % (rep, parts[1]))
218 else:
219 retokens.append(token)
[a35b458]220
[51d4040]221 if (first):
222 first = False
223 else:
224 result.append("+")
[a35b458]225
[51d4040]226 result.append("(")
227 result.extend(alternative_bp(name, retokens))
228 result.append(")")
[a35b458]229
[51d4040]230 if (i < len(tokens)):
231 result.append(tokens[i])
232 else:
[28f4adb]233 print("%s: Syntax error in alternative statement" % name)
[51d4040]234 else:
[28f4adb]235 print("%s: Expected '{' for alternative statement body" % name)
[51d4040]236 else:
[28f4adb]237 print("%s: At least one pattern and one replacement required for alternative statement" % name)
[51d4040]238 else:
[28f4adb]239 print("%s: Expected '(' for alternative statement head" % name)
[1993f9a]240 else:
[ee5b35a]241 result.append(tokens[i])
[a35b458]242
[ee5b35a]243 i += 1
[a35b458]244
[ee5b35a]245 return result
246
[fed03a3]247def split_bp(protocol):
248 "Convert Behavior Protocol to tokens"
[a35b458]249
[fed03a3]250 return split_tokens(protocol, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
251
252def extend_bp(name, tokens, iface):
[51d4040]253 "Convert interface Behavior Protocol to generic protocol"
[a35b458]254
[6d4c549]255 result = []
[fed03a3]256 i = 0
[a35b458]257
[fed03a3]258 while (i < len(tokens)):
259 result.append(tokens[i])
[a35b458]260
[fed03a3]261 if (tokens[i] == "?"):
262 if (i + 1 < len(tokens)):
263 i += 1
264 parts = tokens[i].split(".")
[a35b458]265
[fed03a3]266 if (len(parts) == 1):
267 result.append("%s.%s" % (iface, tokens[i]))
268 else:
269 result.append(tokens[i])
270 else:
[28f4adb]271 print("%s: Unexpected end of protocol" % name)
[a35b458]272
[fed03a3]273 i += 1
[a35b458]274
[fed03a3]275 return result
276
[6d4c549]277def merge_bp(initialization, finalization, protocols):
[fed03a3]278 "Merge several Behavior Protocols"
[a35b458]279
[6d4c549]280 indep = []
[a35b458]281
[fed03a3]282 if (len(protocols) > 1):
283 first = True
[a35b458]284
[fed03a3]285 for protocol in protocols:
286 if (first):
287 first = False
288 else:
[6d4c549]289 indep.append("|")
[a35b458]290
[6d4c549]291 indep.append("(")
292 indep.extend(protocol)
293 indep.append(")")
294 elif (len(protocols) == 1):
295 indep = protocols[0]
[a35b458]296
[6d4c549]297 inited = []
[a35b458]298
[6d4c549]299 if (initialization != None):
300 if (len(indep) > 0):
301 inited.append("(")
302 inited.extend(initialization)
303 inited.append(")")
304 inited.append(";")
305 inited.append("(")
306 inited.extend(indep)
307 inited.append(")")
308 else:
309 inited = initialization
310 else:
311 inited = indep
[a35b458]312
[6d4c549]313 finited = []
[a35b458]314
[6d4c549]315 if (finalization != None):
316 if (len(inited) > 0):
317 finited.append("(")
318 finited.extend(inited)
319 finited.append(")")
320 finited.append(";")
321 finited.append("(")
322 finited.extend(finalization)
323 finited.append(")")
324 else:
325 finited = finalization
326 else:
327 finited = inited
[a35b458]328
[6d4c549]329 return finited
[fed03a3]330
331def parse_bp(name, tokens, base_indent):
[ee5b35a]332 "Parse Behavior Protocol"
[a35b458]333
[51d4040]334 tokens = tentative_bp(name, tokens)
335 tokens = alternative_bp(name, tokens)
[a35b458]336
[ee5b35a]337 indent = base_indent
[2a70672]338 output = ""
[a35b458]339
[e742429]340 for token in tokens:
341 if (token == "\n"):
342 continue
[a35b458]343
[e742429]344 if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
[2a70672]345 output += " %s" % token
[e742429]346 elif (token == "("):
[2a70672]347 output += "\n%s%s" % (tabs(indent), token)
[e742429]348 indent += 1
349 elif (token == ")"):
[ee5b35a]350 if (indent < base_indent):
[28f4adb]351 print("%s: Too many parentheses" % name)
[a35b458]352
[e742429]353 indent -= 1
[2a70672]354 output += "\n%s%s" % (tabs(indent), token)
[e742429]355 elif (token == "{"):
[2a70672]356 output += " %s" % token
[e742429]357 indent += 1
358 elif (token == "}"):
[ee5b35a]359 if (indent < base_indent):
[28f4adb]360 print("%s: Too many parentheses" % name)
[a35b458]361
[e742429]362 indent -= 1
[2a70672]363 output += "\n%s%s" % (tabs(indent), token)
[e742429]364 elif (token == "*"):
[2a70672]365 output += "%s" % token
[1993f9a]366 elif ((token == "!") or (token == "?") or (token == "NULL")):
[2a70672]367 output += "\n%s%s" % (tabs(indent), token)
[e742429]368 else:
[2a70672]369 output += "%s" % token
[a35b458]370
[ee5b35a]371 if (indent > base_indent):
[28f4adb]372 print("%s: Missing parentheses" % name)
[a35b458]373
[ee5b35a]374 output = output.strip()
375 if (output == ""):
376 return "NULL"
[a35b458]377
[2a70672]378 return output
[1993f9a]379
[100aaf5]380def parse_ebp(component, name, tokens, base_indent):
381 "Parse Behavior Protocol and generate Extended Behavior Protocol output"
[a35b458]382
[100aaf5]383 return "component %s {\n\tbehavior {\n\t\t%s\n\t}\n}" % (component, parse_bp(name, tokens, base_indent + 2))
384
[fed03a3]385def get_iface(name):
386 "Get interface by name"
[a35b458]387
[fed03a3]388 global iface_properties
[a35b458]389
[fed03a3]390 if (name in iface_properties):
391 return iface_properties[name]
[a35b458]392
[fed03a3]393 return None
394
[3037384]395def inherited_protocols(iface):
396 "Get protocols inherited by an interface"
[a35b458]397
[3037384]398 result = []
[a35b458]399
[3037384]400 if ('extends' in iface):
401 supiface = get_iface(iface['extends'])
402 if (not supiface is None):
403 if ('protocol' in supiface):
404 result.append(supiface['protocol'])
405 result.extend(inherited_protocols(supiface))
406 else:
[28f4adb]407 print("%s: Extends unknown interface '%s'" % (iface['name'], iface['extends']))
[a35b458]408
[3037384]409 return result
410
[af6cad4]411def dump_frame(directed_binds, frame, outdir, var, archf):
[fed03a3]412 "Dump Behavior Protocol of a given frame"
[a35b458]413
[6d4c549]414 global opt_bp
[100aaf5]415 global opt_ebp
[a35b458]416
[100aaf5]417 if (opt_ebp):
418 fname = "%s.ebp" % frame['name']
419 else:
420 fname = "%s.bp" % frame['name']
[a35b458]421
[6d4c549]422 if (archf != None):
423 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
[a35b458]424
[57688fe2]425 outname = os.path.join(outdir, fname)
[a35b458]426
[fed03a3]427 protocols = []
428 if ('protocol' in frame):
429 protocols.append(frame['protocol'])
[a35b458]430
[6d4c549]431 if ('initialization' in frame):
432 initialization = frame['initialization']
433 else:
434 initialization = None
[a35b458]435
[6d4c549]436 if ('finalization' in frame):
437 finalization = frame['finalization']
438 else:
439 finalization = None
[a35b458]440
[fed03a3]441 if ('provides' in frame):
442 for provides in frame['provides']:
443 iface = get_iface(provides['iface'])
444 if (not iface is None):
[af6cad4]445 binds = directed_binds['%s.%s' % (var, provides['iface'])]
446 if (not binds is None):
447 cnt = len(binds)
448 else:
449 cnt = 1
[a35b458]450
[fed03a3]451 if ('protocol' in iface):
[af6cad4]452 proto = extend_bp(outname, iface['protocol'], iface['name'])
453 for _ in range(0, cnt):
454 protocols.append(proto)
[a35b458]455
[3037384]456 for protocol in inherited_protocols(iface):
[af6cad4]457 proto = extend_bp(outname, protocol, iface['name'])
458 for _ in range(0, cnt):
459 protocols.append(proto)
[fed03a3]460 else:
[28f4adb]461 print("%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface']))
[a35b458]462
[6d4c549]463 if (opt_bp):
[28f4adb]464 outf = open(outname, "w")
[6d4c549]465 outf.write(parse_bp(outname, merge_bp(initialization, finalization, protocols), 0))
466 outf.close()
[a35b458]467
[100aaf5]468 if (opt_ebp):
[28f4adb]469 outf = open(outname, "w")
[100aaf5]470 outf.write(parse_ebp(frame['name'], outname, merge_bp(initialization, finalization, protocols), 0))
471 outf.close()
[ee5b35a]472
[fed03a3]473def get_system_arch():
474 "Get system architecture"
[a35b458]475
[fed03a3]476 global arch_properties
[a35b458]477
[fed03a3]478 for arch, properties in arch_properties.items():
479 if ('system' in properties):
480 return properties
[a35b458]481
[fed03a3]482 return None
483
484def get_arch(name):
485 "Get architecture by name"
[a35b458]486
[fed03a3]487 global arch_properties
[a35b458]488
[fed03a3]489 if (name in arch_properties):
490 return arch_properties[name]
[a35b458]491
[fed03a3]492 return None
493
494def get_frame(name):
495 "Get frame by name"
[a35b458]496
[fed03a3]497 global frame_properties
[a35b458]498
[fed03a3]499 if (name in frame_properties):
500 return frame_properties[name]
[a35b458]501
[fed03a3]502 return None
503
[57688fe2]504def create_null_bp(fname, outdir, archf):
[fed03a3]505 "Create null frame protocol"
[a35b458]506
[6d4c549]507 global opt_bp
[100aaf5]508 global opt_ebp
[a35b458]509
[6d4c549]510 if (archf != None):
511 archf.write("frame \"%s\"\n" % fname)
[a35b458]512
[57688fe2]513 outname = os.path.join(outdir, fname)
[a35b458]514
[6d4c549]515 if (opt_bp):
[28f4adb]516 outf = open(outname, "w")
[6d4c549]517 outf.write("NULL")
518 outf.close()
[a35b458]519
[100aaf5]520 if (opt_ebp):
[28f4adb]521 outf = open(outname, "w")
[100aaf5]522 outf.write("component null {\n\tbehavior {\n\t\tNULL\n\t}\n}")
523 outf.close()
[fed03a3]524
[f1fb1d1]525def flatten_binds(binds, delegates, subsumes):
526 "Remove bindings which are replaced by delegation or subsumption"
[a35b458]527
[f1fb1d1]528 result = []
529 stable = True
[a35b458]530
[f1fb1d1]531 for bind in binds:
532 keep = True
[a35b458]533
[f1fb1d1]534 for delegate in delegates:
535 if (bind['to'] == delegate['to']):
536 keep = False
537 result.append({'from': bind['from'], 'to': delegate['rep']})
[a35b458]538
[f1fb1d1]539 for subsume in subsumes:
540 if (bind['from'] == subsume['from']):
541 keep = False
542 result.append({'from': subsume['rep'], 'to': bind['to']})
[a35b458]543
[f1fb1d1]544 if (keep):
545 result.append(bind)
546 else:
547 stable = False
[a35b458]548
[f1fb1d1]549 if (stable):
550 return result
551 else:
552 return flatten_binds(result, delegates, subsumes)
553
[41eca31]554def direct_binds(binds):
555 "Convert bindings matrix to set of sources by destination"
[a35b458]556
[41eca31]557 result = {}
[a35b458]558
[41eca31]559 for bind in binds:
560 if (not bind['to'] in result):
561 result[bind['to']] = set()
[a35b458]562
[41eca31]563 result[bind['to']].add(bind['from'])
[a35b458]564
[41eca31]565 return result
566
[c123609]567def merge_arch(prefix, arch, outdir):
[2088dfc]568 "Merge subarchitecture into architecture"
[a35b458]569
[57688fe2]570 insts = []
571 binds = []
572 delegates = []
573 subsumes = []
[a35b458]574
[57688fe2]575 if ('inst' in arch):
576 for inst in arch['inst']:
577 subarch = get_arch(inst['type'])
578 if (not subarch is None):
[c123609]579 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
[57688fe2]580 insts.extend(subinsts)
581 binds.extend(subbinds)
582 delegates.extend(subdelegates)
583 subsumes.extend(subsubsumes)
584 else:
585 subframe = get_frame(inst['type'])
586 if (not subframe is None):
587 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
588 else:
[28f4adb]589 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
[a35b458]590
[57688fe2]591 if ('bind' in arch):
592 for bind in arch['bind']:
593 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
[a35b458]594
[57688fe2]595 if ('delegate' in arch):
596 for delegate in arch['delegate']:
597 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
[a35b458]598
[57688fe2]599 if ('subsume' in arch):
600 for subsume in arch['subsume']:
601 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
[a35b458]602
[57688fe2]603 return (insts, binds, delegates, subsumes)
604
605def dump_archbp(outdir):
606 "Dump system architecture Behavior Protocol"
[a35b458]607
[6d4c549]608 global opt_bp
[100aaf5]609 global opt_ebp
[a35b458]610
[57688fe2]611 arch = get_system_arch()
[a35b458]612
[57688fe2]613 if (arch is None):
[28f4adb]614 print("Unable to find system architecture")
[57688fe2]615 return
[a35b458]616
[57688fe2]617 insts = []
618 binds = []
619 delegates = []
620 subsumes = []
[a35b458]621
[fed03a3]622 if ('inst' in arch):
623 for inst in arch['inst']:
624 subarch = get_arch(inst['type'])
625 if (not subarch is None):
[c123609]626 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch(subarch['name'], subarch, outdir)
[57688fe2]627 insts.extend(subinsts)
628 binds.extend(subbinds)
629 delegates.extend(subdelegates)
630 subsumes.extend(subsubsumes)
[fed03a3]631 else:
632 subframe = get_frame(inst['type'])
633 if (not subframe is None):
[57688fe2]634 insts.append({'var': inst['var'], 'frame': subframe})
[fed03a3]635 else:
[28f4adb]636 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
[a35b458]637
[8c73012]638 if ('bind' in arch):
639 for bind in arch['bind']:
[57688fe2]640 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
[a35b458]641
[57688fe2]642 if ('delegate' in arch):
643 for delegate in arch['delegate']:
[28f4adb]644 print("Unable to delegate interface in system architecture")
[57688fe2]645 break
[a35b458]646
[57688fe2]647 if ('subsume' in arch):
648 for subsume in arch['subsume']:
[28f4adb]649 print("Unable to subsume interface in system architecture")
[57688fe2]650 break
[a35b458]651
[af6cad4]652 directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
[a35b458]653
[57688fe2]654 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
[100aaf5]655 if ((opt_bp) or (opt_ebp)):
[28f4adb]656 outf = open(outname, "w")
[6d4c549]657 else:
658 outf = None
[a35b458]659
[57688fe2]660 create_null_bp("null.bp", outdir, outf)
[a35b458]661
[57688fe2]662 for inst in insts:
[af6cad4]663 dump_frame(directed_binds, inst['frame'], outdir, inst['var'], outf)
[a35b458]664
[41eca31]665 for dst, src in directed_binds.items():
[6d4c549]666 if (outf != None):
667 outf.write("bind %s to %s\n" % (", ".join(src), dst))
[a35b458]668
[6d4c549]669 if (outf != None):
670 outf.close()
[ee5b35a]671
672def preproc_adl(raw, inarg):
673 "Preprocess %% statements in ADL"
[a35b458]674
[ee5b35a]675 return raw.replace("%%", inarg)
676
[2a70672]677def parse_adl(base, root, inname, nested, indent):
[1993f9a]678 "Parse Architecture Description Language"
[a35b458]679
[ee5b35a]680 global output
681 global context
682 global architecture
683 global interface
684 global frame
685 global protocol
[6d4c549]686 global initialization
687 global finalization
[a35b458]688
[fed03a3]689 global iface_properties
690 global frame_properties
691 global arch_properties
[a35b458]692
[fed03a3]693 global arg0
[a35b458]694
[1993f9a]695 if (nested):
[2a70672]696 parts = inname.split("%")
[a35b458]697
[2a70672]698 if (len(parts) > 1):
699 inarg = parts[1]
700 else:
701 inarg = "%%"
[a35b458]702
[2a70672]703 if (parts[0][0:1] == "/"):
704 path = os.path.join(base, ".%s" % parts[0])
[1993f9a]705 nested_root = os.path.dirname(path)
706 else:
[2a70672]707 path = os.path.join(root, parts[0])
[1993f9a]708 nested_root = root
[a35b458]709
[1993f9a]710 if (not os.path.isfile(path)):
[28f4adb]711 print("%s: Unable to include file %s" % (inname, path))
[2a70672]712 return ""
[1993f9a]713 else:
714 inarg = "%%"
[2a70672]715 path = inname
[1993f9a]716 nested_root = root
[a35b458]717
[28f4adb]718 inf = open(path, "r")
[a35b458]719
[2a70672]720 raw = preproc_adl(inf.read(), inarg)
721 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
[a35b458]722
[1993f9a]723 for token in tokens:
[a35b458]724
[2a70672]725 # Includes
[a35b458]726
[2a70672]727 if (INC in context):
728 context.remove(INC)
[ee5b35a]729 parse_adl(base, nested_root, token, True, indent)
[2a70672]730 context.add(POST_INC)
[1993f9a]731 continue
[a35b458]732
[2a70672]733 if (POST_INC in context):
734 if (token != "]"):
[28f4adb]735 print("%s: Expected ]" % inname)
[a35b458]736
[2a70672]737 context.remove(POST_INC)
738 continue
[a35b458]739
[2a70672]740 # Comments and newlines
[a35b458]741
[2a70672]742 if (BLOCK_COMMENT in context):
743 if (token == "*/"):
744 context.remove(BLOCK_COMMENT)
[a35b458]745
[2a70672]746 continue
[a35b458]747
[2a70672]748 if (LINE_COMMENT in context):
749 if (token == "\n"):
750 context.remove(LINE_COMMENT)
[a35b458]751
[2a70672]752 continue
[a35b458]753
[2a70672]754 # Any context
[a35b458]755
[2a70672]756 if (token == "/*"):
757 context.add(BLOCK_COMMENT)
758 continue
[a35b458]759
[2a70672]760 if (token == "#"):
761 context.add(LINE_COMMENT)
762 continue
[a35b458]763
[2a70672]764 if (token == "["):
765 context.add(INC)
766 continue
[a35b458]767
[ee5b35a]768 if (token == "\n"):
769 continue
[a35b458]770
[ee5b35a]771 # "frame"
[a35b458]772
[ee5b35a]773 if (FRAME in context):
774 if (NULL in context):
775 if (token != ";"):
[28f4adb]776 print("%s: Expected ';' in frame '%s'" % (inname, frame))
[ee5b35a]777 else:
778 output += "%s\n" % token
[a35b458]779
[ee5b35a]780 context.remove(NULL)
781 context.remove(FRAME)
782 frame = None
[2a70672]783 continue
[a35b458]784
[ee5b35a]785 if (BODY in context):
[6d4c549]786 if (FINALIZATION in context):
787 if (token == "{"):
788 indent += 1
789 elif (token == "}"):
790 indent -= 1
[a35b458]791
[6d4c549]792 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
793 bp = split_bp(finalization)
794 finalization = None
[a35b458]795
[6d4c549]796 if (not frame in frame_properties):
797 frame_properties[frame] = {}
[a35b458]798
[6d4c549]799 if ('finalization' in frame_properties[frame]):
[28f4adb]800 print("%s: Finalization protocol for frame '%s' already defined" % (inname, frame))
[6d4c549]801 else:
802 frame_properties[frame]['finalization'] = bp
[a35b458]803
[6d4c549]804 output += "\n%s" % tabs(2)
805 output += parse_bp(inname, bp, 2)
[a35b458]806
[6d4c549]807 context.remove(FINALIZATION)
808 if (indent == -1):
809 output += "\n%s" % token
810 context.remove(BODY)
811 context.add(NULL)
812 indent = 0
813 continue
814 else:
815 indent = 2
816 else:
817 finalization += token
818 continue
[a35b458]819
[6d4c549]820 if (INITIALIZATION in context):
821 if (token == "{"):
822 indent += 1
823 elif (token == "}"):
824 indent -= 1
[a35b458]825
[6d4c549]826 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
827 bp = split_bp(initialization)
828 initialization = None
[a35b458]829
[6d4c549]830 if (not frame in frame_properties):
831 frame_properties[frame] = {}
[a35b458]832
[6d4c549]833 if ('initialization' in frame_properties[frame]):
[28f4adb]834 print("%s: Initialization protocol for frame '%s' already defined" % (inname, frame))
[6d4c549]835 else:
836 frame_properties[frame]['initialization'] = bp
[a35b458]837
[6d4c549]838 output += "\n%s" % tabs(2)
839 output += parse_bp(inname, bp, 2)
[a35b458]840
[6d4c549]841 context.remove(INITIALIZATION)
842 if (indent == -1):
843 output += "\n%s" % token
844 context.remove(BODY)
845 context.add(NULL)
846 indent = 0
847 continue
848 else:
849 indent = 2
850 else:
851 initialization += token
852 continue
[a35b458]853
[ee5b35a]854 if (PROTOCOL in context):
855 if (token == "{"):
856 indent += 1
857 elif (token == "}"):
858 indent -= 1
[a35b458]859
[6d4c549]860 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
[fed03a3]861 bp = split_bp(protocol)
862 protocol = None
[a35b458]863
[fed03a3]864 if (not frame in frame_properties):
865 frame_properties[frame] = {}
[a35b458]866
[fed03a3]867 if ('protocol' in frame_properties[frame]):
[28f4adb]868 print("%s: Protocol for frame '%s' already defined" % (inname, frame))
[ee5b35a]869 else:
[fed03a3]870 frame_properties[frame]['protocol'] = bp
[a35b458]871
[fed03a3]872 output += "\n%s" % tabs(2)
873 output += parse_bp(inname, bp, 2)
[a35b458]874
[ee5b35a]875 context.remove(PROTOCOL)
[6d4c549]876 if (indent == -1):
877 output += "\n%s" % token
878 context.remove(BODY)
879 context.add(NULL)
880 indent = 0
881 continue
882 else:
883 indent = 2
[ee5b35a]884 else:
885 protocol += token
[6d4c549]886 continue
[a35b458]887
[ee5b35a]888 if (REQUIRES in context):
889 if (FIN in context):
890 if (token != ";"):
[28f4adb]891 print("%s: Expected ';' in frame '%s'" % (inname, frame))
[ee5b35a]892 else:
893 output += "%s" % token
[a35b458]894
[ee5b35a]895 context.remove(FIN)
896 continue
[a35b458]897
[ee5b35a]898 if (VAR in context):
899 if (not identifier(token)):
[28f4adb]900 print("%s: Variable name expected in frame '%s'" % (inname, frame))
[ee5b35a]901 else:
[fed03a3]902 if (not frame in frame_properties):
903 frame_properties[frame] = {}
[a35b458]904
[fed03a3]905 if (not 'requires' in frame_properties[frame]):
906 frame_properties[frame]['requires'] = []
[a35b458]907
[fed03a3]908 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
909 arg0 = None
[a35b458]910
[ee5b35a]911 output += "%s" % token
[a35b458]912
[ee5b35a]913 context.remove(VAR)
914 context.add(FIN)
915 continue
[a35b458]916
[ee5b35a]917 if ((token == "}") or (token[-1] == ":")):
918 context.remove(REQUIRES)
919 else:
920 if (not identifier(token)):
[28f4adb]921 print("%s: Interface name expected in frame '%s'" % (inname, frame))
[ee5b35a]922 else:
[fed03a3]923 arg0 = token
[ee5b35a]924 output += "\n%s%s " % (tabs(indent), token)
[a35b458]925
[ee5b35a]926 context.add(VAR)
927 continue
[a35b458]928
[ee5b35a]929 if (PROVIDES in context):
930 if (FIN in context):
931 if (token != ";"):
[28f4adb]932 print("%s: Expected ';' in frame '%s'" % (inname, frame))
[ee5b35a]933 else:
934 output += "%s" % token
[a35b458]935
[ee5b35a]936 context.remove(FIN)
937 continue
[a35b458]938
[ee5b35a]939 if (VAR in context):
940 if (not identifier(token)):
[28f4adb]941 print("%s: Variable name expected in frame '%s'" % (inname, frame))
[ee5b35a]942 else:
[fed03a3]943 if (not frame in frame_properties):
944 frame_properties[frame] = {}
[a35b458]945
[fed03a3]946 if (not 'provides' in frame_properties[frame]):
947 frame_properties[frame]['provides'] = []
[a35b458]948
[fed03a3]949 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
950 arg0 = None
[a35b458]951
[ee5b35a]952 output += "%s" % token
[a35b458]953
[ee5b35a]954 context.remove(VAR)
955 context.add(FIN)
956 continue
[a35b458]957
[ee5b35a]958 if ((token == "}") or (token[-1] == ":")):
959 context.remove(PROVIDES)
960 else:
961 if (not identifier(token)):
[28f4adb]962 print("%s: Interface name expected in frame '%s'" % (inname, frame))
[ee5b35a]963 else:
[fed03a3]964 arg0 = token
[ee5b35a]965 output += "\n%s%s " % (tabs(indent), token)
[a35b458]966
[ee5b35a]967 context.add(VAR)
968 continue
[a35b458]969
[ee5b35a]970 if (token == "}"):
971 if (indent != 2):
[28f4adb]972 print("%s: Wrong number of parentheses in frame '%s'" % (inname, frame))
[ee5b35a]973 else:
974 indent = 0
975 output += "\n%s" % token
[a35b458]976
[ee5b35a]977 context.remove(BODY)
978 context.add(NULL)
979 continue
[a35b458]980
[ee5b35a]981 if (token == "provides:"):
982 output += "\n%s%s" % (tabs(indent - 1), token)
983 context.add(PROVIDES)
984 continue
[a35b458]985
[ee5b35a]986 if (token == "requires:"):
987 output += "\n%s%s" % (tabs(indent - 1), token)
988 context.add(REQUIRES)
[6d4c549]989 continue
[a35b458]990
[6d4c549]991 if (token == "initialization:"):
992 output += "\n%s%s" % (tabs(indent - 1), token)
993 indent = 0
994 context.add(INITIALIZATION)
995 initialization = ""
996 continue
[a35b458]997
[6d4c549]998 if (token == "finalization:"):
999 output += "\n%s%s" % (tabs(indent - 1), token)
1000 indent = 0
1001 context.add(FINALIZATION)
1002 finalization = ""
[ee5b35a]1003 continue
[a35b458]1004
[ee5b35a]1005 if (token == "protocol:"):
1006 output += "\n%s%s" % (tabs(indent - 1), token)
1007 indent = 0
1008 context.add(PROTOCOL)
1009 protocol = ""
1010 continue
[a35b458]1011
[28f4adb]1012 print("%s: Unknown token '%s' in frame '%s'" % (inname, token, frame))
[2a70672]1013 continue
[a35b458]1014
[ee5b35a]1015 if (HEAD in context):
1016 if (token == "{"):
1017 output += "%s" % token
1018 indent += 2
1019 context.remove(HEAD)
1020 context.add(BODY)
1021 continue
[a35b458]1022
[ee5b35a]1023 if (token == ";"):
1024 output += "%s\n" % token
1025 context.remove(HEAD)
1026 context.remove(FRAME)
1027 continue
[a35b458]1028
[28f4adb]1029 print("%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame))
[a35b458]1030
[ee5b35a]1031 continue
[a35b458]1032
[ee5b35a]1033 if (not identifier(token)):
[28f4adb]1034 print("%s: Expected frame name" % inname)
[ee5b35a]1035 else:
1036 frame = token
1037 output += "%s " % token
[a35b458]1038
[fed03a3]1039 if (not frame in frame_properties):
1040 frame_properties[frame] = {}
[a35b458]1041
[fed03a3]1042 frame_properties[frame]['name'] = frame
[a35b458]1043
[ee5b35a]1044 context.add(HEAD)
1045 continue
[a35b458]1046
[2a70672]1047 # "interface"
[a35b458]1048
[2a70672]1049 if (IFACE in context):
1050 if (NULL in context):
1051 if (token != ";"):
[28f4adb]1052 print("%s: Expected ';' in interface '%s'" % (inname, interface))
[2a70672]1053 else:
1054 output += "%s\n" % token
[a35b458]1055
[2a70672]1056 context.remove(NULL)
1057 context.remove(IFACE)
1058 interface = None
1059 continue
[a35b458]1060
[2a70672]1061 if (BODY in context):
1062 if (PROTOCOL in context):
1063 if (token == "{"):
1064 indent += 1
1065 elif (token == "}"):
1066 indent -= 1
[a35b458]1067
[ee5b35a]1068 if (indent == -1):
[fed03a3]1069 bp = split_bp(protocol)
1070 protocol = None
[a35b458]1071
[fed03a3]1072 if (not interface in iface_properties):
1073 iface_properties[interface] = {}
[a35b458]1074
[fed03a3]1075 if ('protocol' in iface_properties[interface]):
[28f4adb]1076 print("%s: Protocol for interface '%s' already defined" % (inname, interface))
[ee5b35a]1077 else:
[fed03a3]1078 iface_properties[interface]['protocol'] = bp
[a35b458]1079
[ee5b35a]1080 output += "\n%s" % tabs(2)
[fed03a3]1081 output += parse_bp(inname, bp, 2)
[2a70672]1082 output += "\n%s" % token
[ee5b35a]1083 indent = 0
[a35b458]1084
[2a70672]1085 context.remove(PROTOCOL)
1086 context.remove(BODY)
1087 context.add(NULL)
1088 else:
1089 protocol += token
[a35b458]1090
[2a70672]1091 continue
[a35b458]1092
[2a70672]1093 if (PROTOTYPE in context):
1094 if (FIN in context):
1095 if (token != ";"):
[28f4adb]1096 print("%s: Expected ';' in interface '%s'" % (inname, interface))
[2a70672]1097 else:
1098 output += "%s" % token
[a35b458]1099
[2a70672]1100 context.remove(FIN)
1101 context.remove(PROTOTYPE)
1102 continue
[a35b458]1103
[2a70672]1104 if (PAR_RIGHT in context):
1105 if (token == ")"):
1106 output += "%s" % token
1107 context.remove(PAR_RIGHT)
1108 context.add(FIN)
1109 else:
1110 output += " %s" % token
[a35b458]1111
[2a70672]1112 continue
[a35b458]1113
[2a70672]1114 if (SIGNATURE in context):
1115 output += "%s" % token
1116 if (token == ")"):
1117 context.remove(SIGNATURE)
1118 context.add(FIN)
[a35b458]1119
[2a70672]1120 context.remove(SIGNATURE)
1121 context.add(PAR_RIGHT)
1122 continue
[a35b458]1123
[2a70672]1124 if (PAR_LEFT in context):
1125 if (token != "("):
[28f4adb]1126 print("%s: Expected '(' in interface '%s'" % (inname, interface))
[2a70672]1127 else:
1128 output += "%s" % token
[a35b458]1129
[2a70672]1130 context.remove(PAR_LEFT)
1131 context.add(SIGNATURE)
1132 continue
[a35b458]1133
[2a70672]1134 if (not identifier(token)):
[28f4adb]1135 print("%s: Method identifier expected in interface '%s'" % (inname, interface))
[2a70672]1136 else:
1137 output += "%s" % token
[a35b458]1138
[2a70672]1139 context.add(PAR_LEFT)
1140 continue
[a35b458]1141
[2a70672]1142 if (token == "}"):
[ee5b35a]1143 if (indent != 2):
[28f4adb]1144 print("%s: Wrong number of parentheses in interface '%s'" % (inname, interface))
[2a70672]1145 else:
1146 indent = 0
1147 output += "\n%s" % token
[a35b458]1148
[2a70672]1149 context.remove(BODY)
1150 context.add(NULL)
1151 continue
[a35b458]1152
[96b02eb9]1153 if (token == "sysarg_t"):
[2a70672]1154 output += "\n%s%s " % (tabs(indent), token)
1155 context.add(PROTOTYPE)
1156 continue
[a35b458]1157
[2a70672]1158 if (token == "protocol:"):
1159 output += "\n%s%s" % (tabs(indent - 1), token)
[ee5b35a]1160 indent = 0
[2a70672]1161 context.add(PROTOCOL)
1162 protocol = ""
1163 continue
[a35b458]1164
[28f4adb]1165 print("%s: Unknown token '%s' in interface '%s'" % (inname, token, interface))
[2a70672]1166 continue
[a35b458]1167
[2a70672]1168 if (HEAD in context):
[3037384]1169 if (PRE_BODY in context):
1170 if (token == "{"):
1171 output += "%s" % token
1172 indent += 2
1173 context.remove(PRE_BODY)
1174 context.remove(HEAD)
1175 context.add(BODY)
1176 continue
[a35b458]1177
[3037384]1178 if (token == ";"):
1179 output += "%s\n" % token
1180 context.remove(PRE_BODY)
1181 context.remove(HEAD)
1182 context.remove(IFACE)
1183 continue
[a35b458]1184
[28f4adb]1185 print("%s: Expected '{' or ';' in interface head '%s'" % (inname, interface))
[3037384]1186 continue
[a35b458]1187
[3037384]1188 if (EXTENDS in context):
1189 if (not identifier(token)):
[28f4adb]1190 print("%s: Expected inherited interface name in interface head '%s'" % (inname, interface))
[3037384]1191 else:
[6d4c549]1192 output += "%s " % token
[3037384]1193 if (not interface in iface_properties):
1194 iface_properties[interface] = {}
[a35b458]1195
[3037384]1196 iface_properties[interface]['extends'] = token
[a35b458]1197
[3037384]1198 context.remove(EXTENDS)
1199 context.add(PRE_BODY)
1200 continue
[a35b458]1201
[3037384]1202 if (token == "extends"):
[6d4c549]1203 output += "%s " % token
[3037384]1204 context.add(EXTENDS)
1205 continue
[a35b458]1206
[2a70672]1207 if (token == "{"):
1208 output += "%s" % token
1209 indent += 2
1210 context.remove(HEAD)
1211 context.add(BODY)
1212 continue
[a35b458]1213
[2a70672]1214 if (token == ";"):
1215 output += "%s\n" % token
1216 context.remove(HEAD)
[57688fe2]1217 context.remove(IFACE)
[2a70672]1218 continue
[a35b458]1219
[28f4adb]1220 print("%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface))
[2a70672]1221 continue
[a35b458]1222
[2a70672]1223 if (not identifier(token)):
[28f4adb]1224 print("%s: Expected interface name" % inname)
[2a70672]1225 else:
1226 interface = token
1227 output += "%s " % token
[a35b458]1228
[fed03a3]1229 if (not interface in iface_properties):
1230 iface_properties[interface] = {}
[a35b458]1231
[fed03a3]1232 iface_properties[interface]['name'] = interface
[a35b458]1233
[2a70672]1234 context.add(HEAD)
1235 continue
[a35b458]1236
[2a70672]1237 # "architecture"
[a35b458]1238
[2a70672]1239 if (ARCH in context):
1240 if (NULL in context):
1241 if (token != ";"):
[28f4adb]1242 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
[2a70672]1243 else:
1244 output += "%s\n" % token
[a35b458]1245
[2a70672]1246 context.remove(NULL)
1247 context.remove(ARCH)
1248 context.discard(SYSTEM)
1249 architecture = None
1250 continue
[a35b458]1251
[2a70672]1252 if (BODY in context):
[ee5b35a]1253 if (DELEGATE in context):
1254 if (FIN in context):
1255 if (token != ";"):
[28f4adb]1256 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
[ee5b35a]1257 else:
1258 output += "%s" % token
[a35b458]1259
[ee5b35a]1260 context.remove(FIN)
1261 context.remove(DELEGATE)
1262 continue
[a35b458]1263
[ee5b35a]1264 if (VAR in context):
1265 if (not descriptor(token)):
[28f4adb]1266 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
[ee5b35a]1267 else:
[fed03a3]1268 if (not architecture in arch_properties):
1269 arch_properties[architecture] = {}
[a35b458]1270
[fed03a3]1271 if (not 'delegate' in arch_properties[architecture]):
1272 arch_properties[architecture]['delegate'] = []
[a35b458]1273
[fed03a3]1274 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1275 arg0 = None
[a35b458]1276
[ee5b35a]1277 output += "%s" % token
[a35b458]1278
[ee5b35a]1279 context.add(FIN)
1280 context.remove(VAR)
1281 continue
[a35b458]1282
[ee5b35a]1283 if (TO in context):
1284 if (token != "to"):
[28f4adb]1285 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
[ee5b35a]1286 else:
1287 output += "%s " % token
[a35b458]1288
[ee5b35a]1289 context.add(VAR)
1290 context.remove(TO)
1291 continue
[a35b458]1292
[ee5b35a]1293 if (not identifier(token)):
[28f4adb]1294 print("%s: Expected interface name in architecture '%s'" % (inname, architecture))
[ee5b35a]1295 else:
1296 output += "%s " % token
[fed03a3]1297 arg0 = token
[a35b458]1298
[ee5b35a]1299 context.add(TO)
1300 continue
[a35b458]1301
[ee5b35a]1302 if (SUBSUME in context):
1303 if (FIN in context):
1304 if (token != ";"):
[28f4adb]1305 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
[ee5b35a]1306 else:
1307 output += "%s" % token
[a35b458]1308
[ee5b35a]1309 context.remove(FIN)
1310 context.remove(SUBSUME)
1311 continue
[a35b458]1312
[ee5b35a]1313 if (VAR in context):
1314 if (not identifier(token)):
[28f4adb]1315 print("%s: Expected interface name in architecture '%s'" % (inname, architecture))
[ee5b35a]1316 else:
[fed03a3]1317 if (not architecture in arch_properties):
1318 arch_properties[architecture] = {}
[a35b458]1319
[fed03a3]1320 if (not 'subsume' in arch_properties[architecture]):
1321 arch_properties[architecture]['subsume'] = []
[a35b458]1322
[fed03a3]1323 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1324 arg0 = None
[a35b458]1325
[ee5b35a]1326 output += "%s" % token
[a35b458]1327
[ee5b35a]1328 context.add(FIN)
1329 context.remove(VAR)
1330 continue
[a35b458]1331
[ee5b35a]1332 if (TO in context):
1333 if (token != "to"):
[28f4adb]1334 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
[ee5b35a]1335 else:
1336 output += "%s " % token
[a35b458]1337
[ee5b35a]1338 context.add(VAR)
1339 context.remove(TO)
1340 continue
[a35b458]1341
[ee5b35a]1342 if (not descriptor(token)):
[28f4adb]1343 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
[ee5b35a]1344 else:
1345 output += "%s " % token
[fed03a3]1346 arg0 = token
[a35b458]1347
[ee5b35a]1348 context.add(TO)
1349 continue
[a35b458]1350
[2a70672]1351 if (BIND in context):
1352 if (FIN in context):
1353 if (token != ";"):
[28f4adb]1354 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
[2a70672]1355 else:
1356 output += "%s" % token
[a35b458]1357
[2a70672]1358 context.remove(FIN)
1359 context.remove(BIND)
1360 continue
[a35b458]1361
[2a70672]1362 if (VAR in context):
1363 if (not descriptor(token)):
[28f4adb]1364 print("%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture))
[2a70672]1365 else:
[fed03a3]1366 if (not architecture in arch_properties):
1367 arch_properties[architecture] = {}
[a35b458]1368
[fed03a3]1369 if (not 'bind' in arch_properties[architecture]):
1370 arch_properties[architecture]['bind'] = []
[a35b458]1371
[fed03a3]1372 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1373 arg0 = None
[a35b458]1374
[2a70672]1375 output += "%s" % token
[a35b458]1376
[2a70672]1377 context.add(FIN)
1378 context.remove(VAR)
1379 continue
[a35b458]1380
[2a70672]1381 if (TO in context):
1382 if (token != "to"):
[28f4adb]1383 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
[2a70672]1384 else:
1385 output += "%s " % token
[a35b458]1386
[2a70672]1387 context.add(VAR)
1388 context.remove(TO)
1389 continue
[a35b458]1390
[2a70672]1391 if (not descriptor(token)):
[28f4adb]1392 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
[2a70672]1393 else:
1394 output += "%s " % token
[fed03a3]1395 arg0 = token
[a35b458]1396
[2a70672]1397 context.add(TO)
1398 continue
[a35b458]1399
[2a70672]1400 if (INST in context):
1401 if (FIN in context):
1402 if (token != ";"):
[28f4adb]1403 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
[2a70672]1404 else:
1405 output += "%s" % token
[a35b458]1406
[2a70672]1407 context.remove(FIN)
1408 context.remove(INST)
1409 continue
[a35b458]1410
[2a70672]1411 if (VAR in context):
1412 if (not identifier(token)):
[28f4adb]1413 print("%s: Expected instance name in architecture '%s'" % (inname, architecture))
[2a70672]1414 else:
[fed03a3]1415 if (not architecture in arch_properties):
1416 arch_properties[architecture] = {}
[a35b458]1417
[fed03a3]1418 if (not 'inst' in arch_properties[architecture]):
1419 arch_properties[architecture]['inst'] = []
[a35b458]1420
[fed03a3]1421 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1422 arg0 = None
[a35b458]1423
[2a70672]1424 output += "%s" % token
[a35b458]1425
[2a70672]1426 context.add(FIN)
1427 context.remove(VAR)
1428 continue
[a35b458]1429
[2a70672]1430 if (not identifier(token)):
[28f4adb]1431 print("%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture))
[2a70672]1432 else:
1433 output += "%s " % token
[fed03a3]1434 arg0 = token
[a35b458]1435
[2a70672]1436 context.add(VAR)
1437 continue
[a35b458]1438
[2a70672]1439 if (token == "}"):
1440 if (indent != 1):
[28f4adb]1441 print("%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture))
[2a70672]1442 else:
1443 indent -= 1
1444 output += "\n%s" % token
[a35b458]1445
[2a70672]1446 context.remove(BODY)
1447 context.add(NULL)
1448 continue
[a35b458]1449
[2a70672]1450 if (token == "inst"):
1451 output += "\n%s%s " % (tabs(indent), token)
1452 context.add(INST)
1453 continue
[a35b458]1454
[2a70672]1455 if (token == "bind"):
1456 output += "\n%s%s " % (tabs(indent), token)
1457 context.add(BIND)
1458 continue
[a35b458]1459
[ee5b35a]1460 if (token == "subsume"):
1461 output += "\n%s%s " % (tabs(indent), token)
1462 context.add(SUBSUME)
1463 continue
[a35b458]1464
[ee5b35a]1465 if (token == "delegate"):
1466 output += "\n%s%s " % (tabs(indent), token)
1467 context.add(DELEGATE)
1468 continue
[a35b458]1469
[28f4adb]1470 print("%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture))
[2a70672]1471 continue
[a35b458]1472
[2a70672]1473 if (HEAD in context):
1474 if (token == "{"):
1475 output += "%s" % token
1476 indent += 1
1477 context.remove(HEAD)
1478 context.add(BODY)
1479 continue
[a35b458]1480
[2a70672]1481 if (token == ";"):
1482 output += "%s\n" % token
1483 context.remove(HEAD)
1484 context.remove(ARCH)
1485 context.discard(SYSTEM)
1486 continue
[a35b458]1487
[2a70672]1488 if (not word(token)):
[28f4adb]1489 print("%s: Expected word in architecture head '%s'" % (inname, architecture))
[2a70672]1490 else:
1491 output += "%s " % token
[a35b458]1492
[2a70672]1493 continue
[a35b458]1494
[2a70672]1495 if (not identifier(token)):
[28f4adb]1496 print("%s: Expected architecture name" % inname)
[2a70672]1497 else:
1498 architecture = token
1499 output += "%s " % token
[a35b458]1500
[fed03a3]1501 if (not architecture in arch_properties):
1502 arch_properties[architecture] = {}
[a35b458]1503
[fed03a3]1504 arch_properties[architecture]['name'] = architecture
[a35b458]1505
[fed03a3]1506 if (SYSTEM in context):
1507 arch_properties[architecture]['system'] = True
[a35b458]1508
[2a70672]1509 context.add(HEAD)
1510 continue
[a35b458]1511
[2a70672]1512 # "system architecture"
[a35b458]1513
[2a70672]1514 if (SYSTEM in context):
1515 if (token != "architecture"):
[28f4adb]1516 print("%s: Expected 'architecture'" % inname)
[2a70672]1517 else:
1518 output += "%s " % token
[a35b458]1519
[2a70672]1520 context.add(ARCH)
1521 continue
[a35b458]1522
[ee5b35a]1523 if (token == "frame"):
1524 output += "\n%s " % token
1525 context.add(FRAME)
1526 continue
[a35b458]1527
[2a70672]1528 if (token == "interface"):
1529 output += "\n%s " % token
1530 context.add(IFACE)
1531 continue
[a35b458]1532
[2a70672]1533 if (token == "system"):
1534 output += "\n%s " % token
1535 context.add(SYSTEM)
1536 continue
[a35b458]1537
[2a70672]1538 if (token == "architecture"):
1539 output += "\n%s " % token
1540 context.add(ARCH)
1541 continue
[a35b458]1542
[28f4adb]1543 print("%s: Unknown token '%s'" % (inname, token))
[a35b458]1544
[1993f9a]1545 inf.close()
[e742429]1546
[ee5b35a]1547def open_adl(base, root, inname, outdir, outname):
[1993f9a]1548 "Open Architecture Description file"
[a35b458]1549
[ee5b35a]1550 global output
1551 global context
1552 global architecture
1553 global interface
1554 global frame
1555 global protocol
[6d4c549]1556 global initialization
1557 global finalization
[a35b458]1558
[fed03a3]1559 global arg0
[a35b458]1560
[6d4c549]1561 global opt_adl
[a35b458]1562
[ee5b35a]1563 output = ""
1564 context = set()
[2a70672]1565 architecture = None
[ee5b35a]1566 interface = None
1567 frame = None
[2a70672]1568 protocol = None
[6d4c549]1569 initialization = None
1570 finalization = None
[fed03a3]1571 arg0 = None
[a35b458]1572
[ee5b35a]1573 parse_adl(base, root, inname, False, 0)
1574 output = output.strip()
[a35b458]1575
[6d4c549]1576 if ((output != "") and (opt_adl)):
[28f4adb]1577 outf = open(outname, "w")
[ee5b35a]1578 outf.write(output)
1579 outf.close()
[1993f9a]1580
1581def recursion(base, root, output, level):
[e742429]1582 "Recursive directory walk"
[a35b458]1583
[e742429]1584 for name in os.listdir(root):
1585 canon = os.path.join(root, name)
[a35b458]1586
[1993f9a]1587 if (os.path.isfile(canon)):
[e742429]1588 fcomp = split_tokens(canon, ["."])
[1993f9a]1589 cname = canon.split("/")
[a35b458]1590
[2a70672]1591 if (fcomp[-1] == ".adl"):
1592 output_path = os.path.join(output, cname[-1])
[ee5b35a]1593 open_adl(base, root, canon, output, output_path)
[a35b458]1594
[e742429]1595 if (os.path.isdir(canon)):
[1993f9a]1596 recursion(base, canon, output, level + 1)
[e742429]1597
[c123609]1598def merge_dot_frame(prefix, name, frame, outf, indent):
1599 "Dump Dot frame"
[a35b458]1600
[c123609]1601 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1602 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1603 outf.write("%s\tstyle=filled;\n" % tabs(indent))
1604 outf.write("%s\tcolor=red;\n" % tabs(indent))
1605 outf.write("%s\tfillcolor=yellow;\n" % tabs(indent))
1606 outf.write("%s\t\n" % tabs(indent))
[a35b458]1607
[c123609]1608 if ('provides' in frame):
1609 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, style=filled, color=green, fillcolor=yellow];\n" % (tabs(indent), prefix))
[a35b458]1610
[c123609]1611 if ('requires' in frame):
1612 outf.write("%s\t%s__requires [label=\"\", shape=circle, style=filled, color=red, fillcolor=yellow];\n" % (tabs(indent), prefix))
[a35b458]1613
[c123609]1614 outf.write("%s}\n" % tabs(indent))
1615 outf.write("%s\n" % tabs(indent))
[8e21512e]1616
[c123609]1617def merge_dot_arch(prefix, name, arch, outf, indent):
[8e21512e]1618 "Dump Dot subarchitecture"
[a35b458]1619
[8e21512e]1620 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1621 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1622 outf.write("%s\tcolor=red;\n" % tabs(indent))
1623 outf.write("%s\t\n" % tabs(indent))
[a35b458]1624
[8e21512e]1625 if ('inst' in arch):
1626 for inst in arch['inst']:
1627 subarch = get_arch(inst['type'])
1628 if (not subarch is None):
[c123609]1629 merge_dot_arch("%s_%s" % (prefix, inst['var']), inst['var'], subarch, outf, indent + 1)
[8e21512e]1630 else:
1631 subframe = get_frame(inst['type'])
1632 if (not subframe is None):
[c123609]1633 merge_dot_frame("%s_%s" % (prefix, inst['var']), inst['var'], subframe, outf, indent + 1)
[8e21512e]1634 else:
[28f4adb]1635 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
[a35b458]1636
[8e21512e]1637 if ('bind' in arch):
[c123609]1638 labels = {}
1639 for bind in arch['bind']:
1640 if (bind['from'][1] != bind['to'][1]):
1641 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1642 else:
1643 label = bind['from'][1]
[a35b458]1644
[c123609]1645 if (not (bind['from'][0], bind['to'][0]) in labels):
1646 labels[(bind['from'][0], bind['to'][0])] = []
[a35b458]1647
[c123609]1648 labels[(bind['from'][0], bind['to'][0])].append(label)
[a35b458]1649
[8e21512e]1650 for bind in arch['bind']:
[c123609]1651 if (not (bind['from'][0], bind['to'][0]) in labels):
1652 continue
[a35b458]1653
[c123609]1654 attrs = []
[a35b458]1655
[c123609]1656 if (bind['from'][0] != bind['to'][0]):
1657 attrs.append("ltail=cluster_%s_%s" % (prefix, bind['from'][0]))
1658 attrs.append("lhead=cluster_%s_%s" % (prefix, bind['to'][0]))
[a35b458]1659
[c123609]1660 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1661 del labels[(bind['from'][0], bind['to'][0])]
[a35b458]1662
[c123609]1663 outf.write("%s\t%s_%s__requires -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, bind['from'][0], prefix, bind['to'][0], ", ".join(attrs)))
[a35b458]1664
[8e21512e]1665 if ('delegate' in arch):
[c123609]1666 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent), prefix))
[a35b458]1667
[c123609]1668 labels = {}
[8e21512e]1669 for delegate in arch['delegate']:
[c123609]1670 if (delegate['from'] != delegate['to'][1]):
1671 label = "%s:%s" % (delegate['from'], delegate['to'][1])
1672 else:
1673 label = delegate['from']
[a35b458]1674
[c123609]1675 if (not delegate['to'][0] in labels):
1676 labels[delegate['to'][0]] = []
[a35b458]1677
[c123609]1678 labels[delegate['to'][0]].append(label)
[a35b458]1679
[c123609]1680 for delegate in arch['delegate']:
1681 if (not delegate['to'][0] in labels):
1682 continue
[a35b458]1683
[c123609]1684 attrs = []
1685 attrs.append("color=gray")
1686 attrs.append("lhead=cluster_%s_%s" % (prefix, delegate['to'][0]))
1687 attrs.append("label=\"%s\"" % "\\n".join(labels[delegate['to'][0]]))
1688 del labels[delegate['to'][0]]
[a35b458]1689
[c123609]1690 outf.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, prefix, delegate['to'][0], ", ".join(attrs)))
[a35b458]1691
[8e21512e]1692 if ('subsume' in arch):
[c123609]1693 outf.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent), prefix))
[a35b458]1694
[c123609]1695 labels = {}
[8e21512e]1696 for subsume in arch['subsume']:
[c123609]1697 if (subsume['from'][1] != subsume['to']):
1698 label = "%s:%s" % (subsume['from'][1], subsume['to'])
1699 else:
1700 label = subsume['to']
[a35b458]1701
[c123609]1702 if (not subsume['from'][0] in labels):
1703 labels[subsume['from'][0]] = []
[a35b458]1704
[c123609]1705 labels[subsume['from'][0]].append(label)
[a35b458]1706
[c123609]1707 for subsume in arch['subsume']:
1708 if (not subsume['from'][0] in labels):
1709 continue
[a35b458]1710
[c123609]1711 attrs = []
1712 attrs.append("color=gray")
1713 attrs.append("ltail=cluster_%s_%s" % (prefix, subsume['from'][0]))
1714 attrs.append("label=\"%s\"" % "\\n".join(labels[subsume['from'][0]]))
1715 del labels[subsume['from'][0]]
[a35b458]1716
[c123609]1717 outf.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent), prefix, subsume['from'][0], prefix, ", ".join(attrs)))
[a35b458]1718
[8e21512e]1719 outf.write("%s}\n" % tabs(indent))
1720 outf.write("%s\n" % tabs(indent))
1721
1722def dump_dot(outdir):
1723 "Dump Dot architecture"
[a35b458]1724
[8e21512e]1725 global opt_dot
[a35b458]1726
[8e21512e]1727 arch = get_system_arch()
[a35b458]1728
[8e21512e]1729 if (arch is None):
[28f4adb]1730 print("Unable to find system architecture")
[8e21512e]1731 return
[a35b458]1732
[8e21512e]1733 if (opt_dot):
1734 outname = os.path.join(outdir, "%s.dot" % arch['name'])
[28f4adb]1735 outf = open(outname, "w")
[a35b458]1736
[8e21512e]1737 outf.write("digraph {\n")
1738 outf.write("\tlabel=\"%s\";\n" % arch['name'])
1739 outf.write("\tcompound=true;\n")
[c088fd4]1740 outf.write("\tsplines=\"polyline\";\n")
[c123609]1741 outf.write("\tedge [fontsize=8];\n")
[8e21512e]1742 outf.write("\t\n")
[a35b458]1743
[8e21512e]1744 if ('inst' in arch):
1745 for inst in arch['inst']:
1746 subarch = get_arch(inst['type'])
1747 if (not subarch is None):
[c123609]1748 merge_dot_arch(inst['var'], inst['var'], subarch, outf, 1)
[8e21512e]1749 else:
1750 subframe = get_frame(inst['type'])
1751 if (not subframe is None):
[c123609]1752 merge_dot_frame("%s" % inst['var'], inst['var'], subframe, outf, 1)
[8e21512e]1753 else:
[28f4adb]1754 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
[a35b458]1755
[8e21512e]1756 if ('bind' in arch):
[c123609]1757 labels = {}
1758 for bind in arch['bind']:
1759 if (bind['from'][1] != bind['to'][1]):
1760 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1761 else:
1762 label = bind['from'][1]
[a35b458]1763
[c123609]1764 if (not (bind['from'][0], bind['to'][0]) in labels):
1765 labels[(bind['from'][0], bind['to'][0])] = []
[a35b458]1766
[c123609]1767 labels[(bind['from'][0], bind['to'][0])].append(label)
[a35b458]1768
[8e21512e]1769 for bind in arch['bind']:
[c123609]1770 if (not (bind['from'][0], bind['to'][0]) in labels):
1771 continue
[a35b458]1772
[c123609]1773 attrs = []
[a35b458]1774
[c123609]1775 if (bind['from'][0] != bind['to'][0]):
1776 attrs.append("ltail=cluster_%s" % bind['from'][0])
1777 attrs.append("lhead=cluster_%s" % bind['to'][0])
[a35b458]1778
[c123609]1779 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1780 del labels[(bind['from'][0], bind['to'][0])]
[a35b458]1781
[c123609]1782 outf.write("\t%s__requires -> %s__provides [%s];\n" % (bind['from'][0], bind['to'][0], ", ".join(attrs)))
[a35b458]1783
[8e21512e]1784 if ('delegate' in arch):
1785 for delegate in arch['delegate']:
[28f4adb]1786 print("Unable to delegate interface in system architecture")
[8e21512e]1787 break
[a35b458]1788
[8e21512e]1789 if ('subsume' in arch):
1790 for subsume in arch['subsume']:
[28f4adb]1791 print("Unable to subsume interface in system architecture")
[8e21512e]1792 break
[a35b458]1793
[8e21512e]1794 outf.write("}\n")
[a35b458]1795
[8e21512e]1796 outf.close()
1797
[e742429]1798def main():
[fed03a3]1799 global iface_properties
1800 global frame_properties
1801 global arch_properties
[6d4c549]1802 global opt_bp
[100aaf5]1803 global opt_ebp
[6d4c549]1804 global opt_adl
[8e21512e]1805 global opt_dot
[a35b458]1806
[6d4c549]1807 if (len(sys.argv) < 3):
[e742429]1808 usage(sys.argv[0])
1809 return
[a35b458]1810
[6d4c549]1811 opt_bp = False
[100aaf5]1812 opt_ebp = False
[6d4c549]1813 opt_adl = False
[8e21512e]1814 opt_dot = False
[a35b458]1815
[6d4c549]1816 for arg in sys.argv[1:(len(sys.argv) - 1)]:
[100aaf5]1817 if (arg == "--bp"):
[6d4c549]1818 opt_bp = True
[100aaf5]1819 elif (arg == "--ebp"):
1820 opt_ebp = True
1821 elif (arg == "--adl"):
[6d4c549]1822 opt_adl = True
[8e21512e]1823 elif (arg == "--dot"):
1824 opt_dot = True
[100aaf5]1825 elif (arg == "--nop"):
[6d4c549]1826 pass
1827 else:
[28f4adb]1828 print("Error: Unknown command line option '%s'" % arg)
[6d4c549]1829 return
[a35b458]1830
[100aaf5]1831 if ((opt_bp) and (opt_ebp)):
[28f4adb]1832 print("Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols")
[100aaf5]1833 return
[a35b458]1834
[6d4c549]1835 path = os.path.abspath(sys.argv[-1])
[07fdf203]1836 if (not os.path.isdir(path)):
[28f4adb]1837 print("Error: <OUTPUT> is not a directory")
[e742429]1838 return
[a35b458]1839
[fed03a3]1840 iface_properties = {}
1841 frame_properties = {}
1842 arch_properties = {}
[a35b458]1843
[1993f9a]1844 recursion(".", ".", path, 0)
[57688fe2]1845 dump_archbp(path)
[8e21512e]1846 dump_dot(path)
[1993f9a]1847
[e742429]1848if __name__ == '__main__':
1849 main()
Note: See TracBrowser for help on using the repository browser.