source: mainline/contrib/arch/hadlbppp.py@ 77578e8

Last change on this file since 77578e8 was 4dd3912, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update python scripts

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