3 # Copyright (c) 2009 Martin Decky
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
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.
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.
30 HelenOS Architecture Description Language and Behavior Protocols preprocessor
36 INC
, POST_INC
, BLOCK_COMMENT
, LINE_COMMENT
, SYSTEM
, ARCH
, HEAD
, BODY
, NULL
, \
37 INST
, VAR
, FIN
, BIND
, TO
, SUBSUME
, DELEGATE
, IFACE
, EXTENDS
, PRE_BODY
, \
38 PROTOTYPE
, PAR_LEFT
, PAR_RIGHT
, SIGNATURE
, PROTOCOL
, INITIALIZATION
, \
39 FINALIZATION
, FRAME
, PROVIDES
, REQUIRES
= range(29)
44 print("%s <--bp|--ebp|--adl|--dot|--nop>+ <OUTPUT>" % prname
)
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)")
54 "Return given number of tabs"
58 def cond_append(tokens
, token
, trim
):
59 "Conditionally append token to tokens with trim"
62 token
= token
.strip(" \t")
69 def split_tokens(string
, delimiters
, trim
= False, separate
= False):
70 "Split string to tokens by delimiters, keep the delimiters"
76 while (i
< len(string
)):
77 for delim
in delimiters
:
80 if (string
[i
:(i
+ len(delim
))] == delim
):
82 tokens
= cond_append(tokens
, string
[last
:i
], trim
)
83 tokens
= cond_append(tokens
, delim
, trim
)
86 tokens
= cond_append(tokens
, string
[last
:i
], trim
)
94 tokens
= cond_append(tokens
, string
[last
:len(string
)], trim
)
98 def identifier(token
):
99 "Check whether the token is an identifier"
101 if (len(token
) == 0):
104 for i
, char
in enumerate(token
):
106 if ((not char
.isalpha()) and (char
!= "_")):
109 if ((not char
.isalnum()) and (char
!= "_")):
114 def descriptor(token
):
115 "Check whether the token is an interface descriptor"
117 parts
= token
.split(":")
118 if (len(parts
) != 2):
121 return (identifier(parts
[0]) and identifier(parts
[1]))
124 "Check whether the token is a word"
126 if (len(token
) == 0):
129 for i
, char
in enumerate(token
):
130 if ((not char
.isalnum()) and (char
!= "_") and (char
!= ".")):
135 def tentative_bp(name
, tokens
):
136 "Preprocess tentative statements in Behavior Protocol"
141 while (i
< len(tokens
)):
142 if (tokens
[i
] == "tentative"):
143 if ((i
+ 1 < len(tokens
)) and (tokens
[i
+ 1] == "{")):
148 while ((i
< len(tokens
)) and (level
> 0)):
149 if (tokens
[i
] == "{"):
151 elif (tokens
[i
] == "}"):
158 result
.extend(tentative_bp(name
, tokens
[start
:(i
- 1)]))
161 result
.append("NULL")
162 if (i
< len(tokens
)):
163 result
.append(tokens
[i
])
165 print("%s: Syntax error in tentative statement" % name
)
167 print("%s: Expected '{' for tentative statement" % name
)
169 result
.append(tokens
[i
])
175 def alternative_bp(name
, tokens
):
176 "Preprocess alternative statements in Behavior Protocol"
181 while (i
< len(tokens
)):
182 if (tokens
[i
] == "alternative"):
183 if ((i
+ 1 < len(tokens
)) and (tokens
[i
+ 1] == "(")):
187 while ((i
< len(tokens
)) and (tokens
[i
] != ")")):
188 reps
.append(tokens
[i
])
189 if ((i
+ 1 < len(tokens
)) and (tokens
[i
+ 1] == ";")):
195 if ((i
+ 1 < len(tokens
)) and (tokens
[i
+ 1] == "{")):
201 while ((i
< len(tokens
)) and (level
> 0)):
202 if (tokens
[i
] == "{"):
204 elif (tokens
[i
] == "}"):
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]))
219 retokens
.append(token
)
227 result
.extend(alternative_bp(name
, retokens
))
230 if (i
< len(tokens
)):
231 result
.append(tokens
[i
])
233 print("%s: Syntax error in alternative statement" % name
)
235 print("%s: Expected '{' for alternative statement body" % name
)
237 print("%s: At least one pattern and one replacement required for alternative statement" % name
)
239 print("%s: Expected '(' for alternative statement head" % name
)
241 result
.append(tokens
[i
])
247 def split_bp(protocol
):
248 "Convert Behavior Protocol to tokens"
250 return split_tokens(protocol
, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
252 def extend_bp(name
, tokens
, iface
):
253 "Convert interface Behavior Protocol to generic protocol"
258 while (i
< len(tokens
)):
259 result
.append(tokens
[i
])
261 if (tokens
[i
] == "?"):
262 if (i
+ 1 < len(tokens
)):
264 parts
= tokens
[i
].split(".")
266 if (len(parts
) == 1):
267 result
.append("%s.%s" % (iface
, tokens
[i
]))
269 result
.append(tokens
[i
])
271 print("%s: Unexpected end of protocol" % name
)
277 def merge_bp(initialization
, finalization
, protocols
):
278 "Merge several Behavior Protocols"
282 if (len(protocols
) > 1):
285 for protocol
in protocols
:
292 indep
.extend(protocol
)
294 elif (len(protocols
) == 1):
299 if (initialization
!= None):
302 inited
.extend(initialization
)
309 inited
= initialization
315 if (finalization
!= None):
316 if (len(inited
) > 0):
318 finited
.extend(inited
)
322 finited
.extend(finalization
)
325 finited
= finalization
331 def parse_bp(name
, tokens
, base_indent
):
332 "Parse Behavior Protocol"
334 tokens
= tentative_bp(name
, tokens
)
335 tokens
= alternative_bp(name
, tokens
)
344 if ((token
== ";") or (token
== "+") or (token
== "||") or (token
== "|")):
345 output
+= " %s" % token
347 output
+= "\n%s%s" % (tabs(indent
), token
)
350 if (indent
< base_indent
):
351 print("%s: Too many parentheses" % name
)
354 output
+= "\n%s%s" % (tabs(indent
), token
)
356 output
+= " %s" % token
359 if (indent
< base_indent
):
360 print("%s: Too many parentheses" % name
)
363 output
+= "\n%s%s" % (tabs(indent
), token
)
365 output
+= "%s" % token
366 elif ((token
== "!") or (token
== "?") or (token
== "NULL")):
367 output
+= "\n%s%s" % (tabs(indent
), token
)
369 output
+= "%s" % token
371 if (indent
> base_indent
):
372 print("%s: Missing parentheses" % name
)
374 output
= output
.strip()
380 def parse_ebp(component
, name
, tokens
, base_indent
):
381 "Parse Behavior Protocol and generate Extended Behavior Protocol output"
383 return "component %s {\n\tbehavior {\n\t\t%s\n\t}\n}" % (component
, parse_bp(name
, tokens
, base_indent
+ 2))
386 "Get interface by name"
388 global iface_properties
390 if (name
in iface_properties
):
391 return iface_properties
[name
]
395 def inherited_protocols(iface
):
396 "Get protocols inherited by an interface"
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
))
407 print("%s: Extends unknown interface '%s'" % (iface
['name'], iface
['extends']))
411 def dump_frame(directed_binds
, frame
, outdir
, var
, archf
):
412 "Dump Behavior Protocol of a given frame"
418 fname
= "%s.ebp" % frame
['name']
420 fname
= "%s.bp" % frame
['name']
423 archf
.write("instantiate %s from \"%s\"\n" % (var
, fname
))
425 outname
= os
.path
.join(outdir
, fname
)
428 if ('protocol' in frame
):
429 protocols
.append(frame
['protocol'])
431 if ('initialization' in frame
):
432 initialization
= frame
['initialization']
434 initialization
= None
436 if ('finalization' in frame
):
437 finalization
= frame
['finalization']
441 if ('provides' in frame
):
442 for provides
in frame
['provides']:
443 iface
= get_iface(provides
['iface'])
444 if (not iface
is None):
445 binds
= directed_binds
['%s.%s' % (var
, provides
['iface'])]
446 if (not binds
is None):
451 if ('protocol' in iface
):
452 proto
= extend_bp(outname
, iface
['protocol'], iface
['name'])
453 for _
in range(0, cnt
):
454 protocols
.append(proto
)
456 for protocol
in inherited_protocols(iface
):
457 proto
= extend_bp(outname
, protocol
, iface
['name'])
458 for _
in range(0, cnt
):
459 protocols
.append(proto
)
461 print("%s: Provided interface '%s' is undefined" % (frame
['name'], provides
['iface']))
464 outf
= open(outname
, "w")
465 outf
.write(parse_bp(outname
, merge_bp(initialization
, finalization
, protocols
), 0))
469 outf
= open(outname
, "w")
470 outf
.write(parse_ebp(frame
['name'], outname
, merge_bp(initialization
, finalization
, protocols
), 0))
473 def get_system_arch():
474 "Get system architecture"
476 global arch_properties
478 for arch
, properties
in arch_properties
.items():
479 if ('system' in properties
):
485 "Get architecture by name"
487 global arch_properties
489 if (name
in arch_properties
):
490 return arch_properties
[name
]
497 global frame_properties
499 if (name
in frame_properties
):
500 return frame_properties
[name
]
504 def create_null_bp(fname
, outdir
, archf
):
505 "Create null frame protocol"
511 archf
.write("frame \"%s\"\n" % fname
)
513 outname
= os
.path
.join(outdir
, fname
)
516 outf
= open(outname
, "w")
521 outf
= open(outname
, "w")
522 outf
.write("component null {\n\tbehavior {\n\t\tNULL\n\t}\n}")
525 def flatten_binds(binds
, delegates
, subsumes
):
526 "Remove bindings which are replaced by delegation or subsumption"
534 for delegate
in delegates
:
535 if (bind
['to'] == delegate
['to']):
537 result
.append({'from': bind
['from'], 'to': delegate
['rep']})
539 for subsume
in subsumes
:
540 if (bind
['from'] == subsume
['from']):
542 result
.append({'from': subsume
['rep'], 'to': bind
['to']})
552 return flatten_binds(result
, delegates
, subsumes
)
554 def direct_binds(binds
):
555 "Convert bindings matrix to set of sources by destination"
560 if (not bind
['to'] in result
):
561 result
[bind
['to']] = set()
563 result
[bind
['to']].add(bind
['from'])
567 def merge_arch(prefix
, arch
, outdir
):
568 "Merge subarchitecture into architecture"
576 for inst
in arch
['inst']:
577 subarch
= get_arch(inst
['type'])
578 if (not subarch
is None):
579 (subinsts
, subbinds
, subdelegates
, subsubsumes
) = merge_arch("%s_%s" % (prefix
, subarch
['name']), subarch
, outdir
)
580 insts
.extend(subinsts
)
581 binds
.extend(subbinds
)
582 delegates
.extend(subdelegates
)
583 subsumes
.extend(subsubsumes
)
585 subframe
= get_frame(inst
['type'])
586 if (not subframe
is None):
587 insts
.append({'var': "%s_%s" % (prefix
, inst
['var']), 'frame': subframe
})
589 print("%s: '%s' is neither an architecture nor a frame" % (arch
['name'], inst
['type']))
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])})
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])})
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])})
603 return (insts
, binds
, delegates
, subsumes
)
605 def dump_archbp(outdir
):
606 "Dump system architecture Behavior Protocol"
611 arch
= get_system_arch()
614 print("Unable to find system architecture")
623 for inst
in arch
['inst']:
624 subarch
= get_arch(inst
['type'])
625 if (not subarch
is None):
626 (subinsts
, subbinds
, subdelegates
, subsubsumes
) = merge_arch(subarch
['name'], subarch
, outdir
)
627 insts
.extend(subinsts
)
628 binds
.extend(subbinds
)
629 delegates
.extend(subdelegates
)
630 subsumes
.extend(subsubsumes
)
632 subframe
= get_frame(inst
['type'])
633 if (not subframe
is None):
634 insts
.append({'var': inst
['var'], 'frame': subframe
})
636 print("%s: '%s' is neither an architecture nor a frame" % (arch
['name'], inst
['type']))
639 for bind
in arch
['bind']:
640 binds
.append({'from': "%s.%s" % (bind
['from'][0], bind
['from'][1]), 'to': "%s.%s" % (bind
['to'][0], bind
['to'][1])})
642 if ('delegate' in arch
):
643 for delegate
in arch
['delegate']:
644 print("Unable to delegate interface in system architecture")
647 if ('subsume' in arch
):
648 for subsume
in arch
['subsume']:
649 print("Unable to subsume interface in system architecture")
652 directed_binds
= direct_binds(flatten_binds(binds
, delegates
, subsumes
))
654 outname
= os
.path
.join(outdir
, "%s.archbp" % arch
['name'])
655 if ((opt_bp
) or (opt_ebp
)):
656 outf
= open(outname
, "w")
660 create_null_bp("null.bp", outdir
, outf
)
663 dump_frame(directed_binds
, inst
['frame'], outdir
, inst
['var'], outf
)
665 for dst
, src
in directed_binds
.items():
667 outf
.write("bind %s to %s\n" % (", ".join(src
), dst
))
672 def preproc_adl(raw
, inarg
):
673 "Preprocess %% statements in ADL"
675 return raw
.replace("%%", inarg
)
677 def parse_adl(base
, root
, inname
, nested
, indent
):
678 "Parse Architecture Description Language"
686 global initialization
689 global iface_properties
690 global frame_properties
691 global arch_properties
696 parts
= inname
.split("%")
703 if (parts
[0][0:1] == "/"):
704 path
= os
.path
.join(base
, ".%s" % parts
[0])
705 nested_root
= os
.path
.dirname(path
)
707 path
= os
.path
.join(root
, parts
[0])
710 if (not os
.path
.isfile(path
)):
711 print("%s: Unable to include file %s" % (inname
, path
))
718 inf
= open(path
, "r")
720 raw
= preproc_adl(inf
.read(), inarg
)
721 tokens
= split_tokens(raw
, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
729 parse_adl(base
, nested_root
, token
, True, indent
)
730 context
.add(POST_INC
)
733 if (POST_INC
in context
):
735 print("%s: Expected ]" % inname
)
737 context
.remove(POST_INC
)
740 # Comments and newlines
742 if (BLOCK_COMMENT
in context
):
744 context
.remove(BLOCK_COMMENT
)
748 if (LINE_COMMENT
in context
):
750 context
.remove(LINE_COMMENT
)
757 context
.add(BLOCK_COMMENT
)
761 context
.add(LINE_COMMENT
)
773 if (FRAME
in context
):
774 if (NULL
in context
):
776 print("%s: Expected ';' in frame '%s'" % (inname
, frame
))
778 output
+= "%s\n" % token
781 context
.remove(FRAME
)
785 if (BODY
in context
):
786 if (FINALIZATION
in context
):
792 if (((token
[-1] == ":") and (indent
== 0)) or (indent
== -1)):
793 bp
= split_bp(finalization
)
796 if (not frame
in frame_properties
):
797 frame_properties
[frame
] = {}
799 if ('finalization' in frame_properties
[frame
]):
800 print("%s: Finalization protocol for frame '%s' already defined" % (inname
, frame
))
802 frame_properties
[frame
]['finalization'] = bp
804 output
+= "\n%s" % tabs(2)
805 output
+= parse_bp(inname
, bp
, 2)
807 context
.remove(FINALIZATION
)
809 output
+= "\n%s" % token
817 finalization
+= token
820 if (INITIALIZATION
in context
):
826 if (((token
[-1] == ":") and (indent
== 0)) or (indent
== -1)):
827 bp
= split_bp(initialization
)
828 initialization
= None
830 if (not frame
in frame_properties
):
831 frame_properties
[frame
] = {}
833 if ('initialization' in frame_properties
[frame
]):
834 print("%s: Initialization protocol for frame '%s' already defined" % (inname
, frame
))
836 frame_properties
[frame
]['initialization'] = bp
838 output
+= "\n%s" % tabs(2)
839 output
+= parse_bp(inname
, bp
, 2)
841 context
.remove(INITIALIZATION
)
843 output
+= "\n%s" % token
851 initialization
+= token
854 if (PROTOCOL
in context
):
860 if (((token
[-1] == ":") and (indent
== 0)) or (indent
== -1)):
861 bp
= split_bp(protocol
)
864 if (not frame
in frame_properties
):
865 frame_properties
[frame
] = {}
867 if ('protocol' in frame_properties
[frame
]):
868 print("%s: Protocol for frame '%s' already defined" % (inname
, frame
))
870 frame_properties
[frame
]['protocol'] = bp
872 output
+= "\n%s" % tabs(2)
873 output
+= parse_bp(inname
, bp
, 2)
875 context
.remove(PROTOCOL
)
877 output
+= "\n%s" % token
888 if (REQUIRES
in context
):
891 print("%s: Expected ';' in frame '%s'" % (inname
, frame
))
893 output
+= "%s" % token
899 if (not identifier(token
)):
900 print("%s: Variable name expected in frame '%s'" % (inname
, frame
))
902 if (not frame
in frame_properties
):
903 frame_properties
[frame
] = {}
905 if (not 'requires' in frame_properties
[frame
]):
906 frame_properties
[frame
]['requires'] = []
908 frame_properties
[frame
]['requires'].append({'iface': arg0
, 'var': token
})
911 output
+= "%s" % token
917 if ((token
== "}") or (token
[-1] == ":")):
918 context
.remove(REQUIRES
)
920 if (not identifier(token
)):
921 print("%s: Interface name expected in frame '%s'" % (inname
, frame
))
924 output
+= "\n%s%s " % (tabs(indent
), token
)
929 if (PROVIDES
in context
):
932 print("%s: Expected ';' in frame '%s'" % (inname
, frame
))
934 output
+= "%s" % token
940 if (not identifier(token
)):
941 print("%s: Variable name expected in frame '%s'" % (inname
, frame
))
943 if (not frame
in frame_properties
):
944 frame_properties
[frame
] = {}
946 if (not 'provides' in frame_properties
[frame
]):
947 frame_properties
[frame
]['provides'] = []
949 frame_properties
[frame
]['provides'].append({'iface': arg0
, 'var': token
})
952 output
+= "%s" % token
958 if ((token
== "}") or (token
[-1] == ":")):
959 context
.remove(PROVIDES
)
961 if (not identifier(token
)):
962 print("%s: Interface name expected in frame '%s'" % (inname
, frame
))
965 output
+= "\n%s%s " % (tabs(indent
), token
)
972 print("%s: Wrong number of parentheses in frame '%s'" % (inname
, frame
))
975 output
+= "\n%s" % token
981 if (token
== "provides:"):
982 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
983 context
.add(PROVIDES
)
986 if (token
== "requires:"):
987 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
988 context
.add(REQUIRES
)
991 if (token
== "initialization:"):
992 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
994 context
.add(INITIALIZATION
)
998 if (token
== "finalization:"):
999 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
1001 context
.add(FINALIZATION
)
1005 if (token
== "protocol:"):
1006 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
1008 context
.add(PROTOCOL
)
1012 print("%s: Unknown token '%s' in frame '%s'" % (inname
, token
, frame
))
1015 if (HEAD
in context
):
1017 output
+= "%s" % token
1019 context
.remove(HEAD
)
1024 output
+= "%s\n" % token
1025 context
.remove(HEAD
)
1026 context
.remove(FRAME
)
1029 print("%s: Unknown token '%s' in frame head '%s'" % (inname
, token
, frame
))
1033 if (not identifier(token
)):
1034 print("%s: Expected frame name" % inname
)
1037 output
+= "%s " % token
1039 if (not frame
in frame_properties
):
1040 frame_properties
[frame
] = {}
1042 frame_properties
[frame
]['name'] = frame
1049 if (IFACE
in context
):
1050 if (NULL
in context
):
1052 print("%s: Expected ';' in interface '%s'" % (inname
, interface
))
1054 output
+= "%s\n" % token
1056 context
.remove(NULL
)
1057 context
.remove(IFACE
)
1061 if (BODY
in context
):
1062 if (PROTOCOL
in context
):
1065 elif (token
== "}"):
1069 bp
= split_bp(protocol
)
1072 if (not interface
in iface_properties
):
1073 iface_properties
[interface
] = {}
1075 if ('protocol' in iface_properties
[interface
]):
1076 print("%s: Protocol for interface '%s' already defined" % (inname
, interface
))
1078 iface_properties
[interface
]['protocol'] = bp
1080 output
+= "\n%s" % tabs(2)
1081 output
+= parse_bp(inname
, bp
, 2)
1082 output
+= "\n%s" % token
1085 context
.remove(PROTOCOL
)
1086 context
.remove(BODY
)
1093 if (PROTOTYPE
in context
):
1094 if (FIN
in context
):
1096 print("%s: Expected ';' in interface '%s'" % (inname
, interface
))
1098 output
+= "%s" % token
1101 context
.remove(PROTOTYPE
)
1104 if (PAR_RIGHT
in context
):
1106 output
+= "%s" % token
1107 context
.remove(PAR_RIGHT
)
1110 output
+= " %s" % token
1114 if (SIGNATURE
in context
):
1115 output
+= "%s" % token
1117 context
.remove(SIGNATURE
)
1120 context
.remove(SIGNATURE
)
1121 context
.add(PAR_RIGHT
)
1124 if (PAR_LEFT
in context
):
1126 print("%s: Expected '(' in interface '%s'" % (inname
, interface
))
1128 output
+= "%s" % token
1130 context
.remove(PAR_LEFT
)
1131 context
.add(SIGNATURE
)
1134 if (not identifier(token
)):
1135 print("%s: Method identifier expected in interface '%s'" % (inname
, interface
))
1137 output
+= "%s" % token
1139 context
.add(PAR_LEFT
)
1144 print("%s: Wrong number of parentheses in interface '%s'" % (inname
, interface
))
1147 output
+= "\n%s" % token
1149 context
.remove(BODY
)
1153 if (token
== "sysarg_t"):
1154 output
+= "\n%s%s " % (tabs(indent
), token
)
1155 context
.add(PROTOTYPE
)
1158 if (token
== "protocol:"):
1159 output
+= "\n%s%s" % (tabs(indent
- 1), token
)
1161 context
.add(PROTOCOL
)
1165 print("%s: Unknown token '%s' in interface '%s'" % (inname
, token
, interface
))
1168 if (HEAD
in context
):
1169 if (PRE_BODY
in context
):
1171 output
+= "%s" % token
1173 context
.remove(PRE_BODY
)
1174 context
.remove(HEAD
)
1179 output
+= "%s\n" % token
1180 context
.remove(PRE_BODY
)
1181 context
.remove(HEAD
)
1182 context
.remove(IFACE
)
1185 print("%s: Expected '{' or ';' in interface head '%s'" % (inname
, interface
))
1188 if (EXTENDS
in context
):
1189 if (not identifier(token
)):
1190 print("%s: Expected inherited interface name in interface head '%s'" % (inname
, interface
))
1192 output
+= "%s " % token
1193 if (not interface
in iface_properties
):
1194 iface_properties
[interface
] = {}
1196 iface_properties
[interface
]['extends'] = token
1198 context
.remove(EXTENDS
)
1199 context
.add(PRE_BODY
)
1202 if (token
== "extends"):
1203 output
+= "%s " % token
1204 context
.add(EXTENDS
)
1208 output
+= "%s" % token
1210 context
.remove(HEAD
)
1215 output
+= "%s\n" % token
1216 context
.remove(HEAD
)
1217 context
.remove(IFACE
)
1220 print("%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname
, interface
))
1223 if (not identifier(token
)):
1224 print("%s: Expected interface name" % inname
)
1227 output
+= "%s " % token
1229 if (not interface
in iface_properties
):
1230 iface_properties
[interface
] = {}
1232 iface_properties
[interface
]['name'] = interface
1239 if (ARCH
in context
):
1240 if (NULL
in context
):
1242 print("%s: Expected ';' in architecture '%s'" % (inname
, architecture
))
1244 output
+= "%s\n" % token
1246 context
.remove(NULL
)
1247 context
.remove(ARCH
)
1248 context
.discard(SYSTEM
)
1252 if (BODY
in context
):
1253 if (DELEGATE
in context
):
1254 if (FIN
in context
):
1256 print("%s: Expected ';' in architecture '%s'" % (inname
, architecture
))
1258 output
+= "%s" % token
1261 context
.remove(DELEGATE
)
1264 if (VAR
in context
):
1265 if (not descriptor(token
)):
1266 print("%s: Expected interface descriptor in architecture '%s'" % (inname
, architecture
))
1268 if (not architecture
in arch_properties
):
1269 arch_properties
[architecture
] = {}
1271 if (not 'delegate' in arch_properties
[architecture
]):
1272 arch_properties
[architecture
]['delegate'] = []
1274 arch_properties
[architecture
]['delegate'].append({'from': arg0
, 'to': token
.split(":")})
1277 output
+= "%s" % token
1285 print("%s: Expected 'to' in architecture '%s'" % (inname
, architecture
))
1287 output
+= "%s " % token
1293 if (not identifier(token
)):
1294 print("%s: Expected interface name in architecture '%s'" % (inname
, architecture
))
1296 output
+= "%s " % token
1302 if (SUBSUME
in context
):
1303 if (FIN
in context
):
1305 print("%s: Expected ';' in architecture '%s'" % (inname
, architecture
))
1307 output
+= "%s" % token
1310 context
.remove(SUBSUME
)
1313 if (VAR
in context
):
1314 if (not identifier(token
)):
1315 print("%s: Expected interface name in architecture '%s'" % (inname
, architecture
))
1317 if (not architecture
in arch_properties
):
1318 arch_properties
[architecture
] = {}
1320 if (not 'subsume' in arch_properties
[architecture
]):
1321 arch_properties
[architecture
]['subsume'] = []
1323 arch_properties
[architecture
]['subsume'].append({'from': arg0
.split(":"), 'to': token
})
1326 output
+= "%s" % token
1334 print("%s: Expected 'to' in architecture '%s'" % (inname
, architecture
))
1336 output
+= "%s " % token
1342 if (not descriptor(token
)):
1343 print("%s: Expected interface descriptor in architecture '%s'" % (inname
, architecture
))
1345 output
+= "%s " % token
1351 if (BIND
in context
):
1352 if (FIN
in context
):
1354 print("%s: Expected ';' in architecture '%s'" % (inname
, architecture
))
1356 output
+= "%s" % token
1359 context
.remove(BIND
)
1362 if (VAR
in context
):
1363 if (not descriptor(token
)):
1364 print("%s: Expected second interface descriptor in architecture '%s'" % (inname
, architecture
))
1366 if (not architecture
in arch_properties
):
1367 arch_properties
[architecture
] = {}
1369 if (not 'bind' in arch_properties
[architecture
]):
1370 arch_properties
[architecture
]['bind'] = []
1372 arch_properties
[architecture
]['bind'].append({'from': arg0
.split(":"), 'to': token
.split(":")})
1375 output
+= "%s" % token
1383 print("%s: Expected 'to' in architecture '%s'" % (inname
, architecture
))
1385 output
+= "%s " % token
1391 if (not descriptor(token
)):
1392 print("%s: Expected interface descriptor in architecture '%s'" % (inname
, architecture
))
1394 output
+= "%s " % token
1400 if (INST
in context
):
1401 if (FIN
in context
):
1403 print("%s: Expected ';' in architecture '%s'" % (inname
, architecture
))
1405 output
+= "%s" % token
1408 context
.remove(INST
)
1411 if (VAR
in context
):
1412 if (not identifier(token
)):
1413 print("%s: Expected instance name in architecture '%s'" % (inname
, architecture
))
1415 if (not architecture
in arch_properties
):
1416 arch_properties
[architecture
] = {}
1418 if (not 'inst' in arch_properties
[architecture
]):
1419 arch_properties
[architecture
]['inst'] = []
1421 arch_properties
[architecture
]['inst'].append({'type': arg0
, 'var': token
})
1424 output
+= "%s" % token
1430 if (not identifier(token
)):
1431 print("%s: Expected frame/architecture type in architecture '%s'" % (inname
, architecture
))
1433 output
+= "%s " % token
1441 print("%s: Wrong number of parentheses in architecture '%s'" % (inname
, architecture
))
1444 output
+= "\n%s" % token
1446 context
.remove(BODY
)
1450 if (token
== "inst"):
1451 output
+= "\n%s%s " % (tabs(indent
), token
)
1455 if (token
== "bind"):
1456 output
+= "\n%s%s " % (tabs(indent
), token
)
1460 if (token
== "subsume"):
1461 output
+= "\n%s%s " % (tabs(indent
), token
)
1462 context
.add(SUBSUME
)
1465 if (token
== "delegate"):
1466 output
+= "\n%s%s " % (tabs(indent
), token
)
1467 context
.add(DELEGATE
)
1470 print("%s: Unknown token '%s' in architecture '%s'" % (inname
, token
, architecture
))
1473 if (HEAD
in context
):
1475 output
+= "%s" % token
1477 context
.remove(HEAD
)
1482 output
+= "%s\n" % token
1483 context
.remove(HEAD
)
1484 context
.remove(ARCH
)
1485 context
.discard(SYSTEM
)
1488 if (not word(token
)):
1489 print("%s: Expected word in architecture head '%s'" % (inname
, architecture
))
1491 output
+= "%s " % token
1495 if (not identifier(token
)):
1496 print("%s: Expected architecture name" % inname
)
1498 architecture
= token
1499 output
+= "%s " % token
1501 if (not architecture
in arch_properties
):
1502 arch_properties
[architecture
] = {}
1504 arch_properties
[architecture
]['name'] = architecture
1506 if (SYSTEM
in context
):
1507 arch_properties
[architecture
]['system'] = True
1512 # "system architecture"
1514 if (SYSTEM
in context
):
1515 if (token
!= "architecture"):
1516 print("%s: Expected 'architecture'" % inname
)
1518 output
+= "%s " % token
1523 if (token
== "frame"):
1524 output
+= "\n%s " % token
1528 if (token
== "interface"):
1529 output
+= "\n%s " % token
1533 if (token
== "system"):
1534 output
+= "\n%s " % token
1538 if (token
== "architecture"):
1539 output
+= "\n%s " % token
1543 print("%s: Unknown token '%s'" % (inname
, token
))
1547 def open_adl(base
, root
, inname
, outdir
, outname
):
1548 "Open Architecture Description file"
1556 global initialization
1569 initialization
= None
1573 parse_adl(base
, root
, inname
, False, 0)
1574 output
= output
.strip()
1576 if ((output
!= "") and (opt_adl
)):
1577 outf
= open(outname
, "w")
1581 def recursion(base
, root
, output
, level
):
1582 "Recursive directory walk"
1584 for name
in os
.listdir(root
):
1585 canon
= os
.path
.join(root
, name
)
1587 if (os
.path
.isfile(canon
)):
1588 fcomp
= split_tokens(canon
, ["."])
1589 cname
= canon
.split("/")
1591 if (fcomp
[-1] == ".adl"):
1592 output_path
= os
.path
.join(output
, cname
[-1])
1593 open_adl(base
, root
, canon
, output
, output_path
)
1595 if (os
.path
.isdir(canon
)):
1596 recursion(base
, canon
, output
, level
+ 1)
1598 def merge_dot_frame(prefix
, name
, frame
, outf
, indent
):
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
))
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
))
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
))
1614 outf
.write("%s}\n" % tabs(indent
))
1615 outf
.write("%s\n" % tabs(indent
))
1617 def merge_dot_arch(prefix
, name
, arch
, outf
, indent
):
1618 "Dump Dot subarchitecture"
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
))
1625 if ('inst' in arch
):
1626 for inst
in arch
['inst']:
1627 subarch
= get_arch(inst
['type'])
1628 if (not subarch
is None):
1629 merge_dot_arch("%s_%s" % (prefix
, inst
['var']), inst
['var'], subarch
, outf
, indent
+ 1)
1631 subframe
= get_frame(inst
['type'])
1632 if (not subframe
is None):
1633 merge_dot_frame("%s_%s" % (prefix
, inst
['var']), inst
['var'], subframe
, outf
, indent
+ 1)
1635 print("%s: '%s' is neither an architecture nor a frame" % (arch
['name'], inst
['type']))
1637 if ('bind' in arch
):
1639 for bind
in arch
['bind']:
1640 if (bind
['from'][1] != bind
['to'][1]):
1641 label
= "%s:%s" % (bind
['from'][1], bind
['to'][1])
1643 label
= bind
['from'][1]
1645 if (not (bind
['from'][0], bind
['to'][0]) in labels
):
1646 labels
[(bind
['from'][0], bind
['to'][0])] = []
1648 labels
[(bind
['from'][0], bind
['to'][0])].append(label
)
1650 for bind
in arch
['bind']:
1651 if (not (bind
['from'][0], bind
['to'][0]) in labels
):
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]))
1660 attrs
.append("label=\"%s\"" % "\\n".join(labels
[(bind
['from'][0], bind
['to'][0])]))
1661 del labels
[(bind
['from'][0], bind
['to'][0])]
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
)))
1665 if ('delegate' in arch
):
1666 outf
.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent
), prefix
))
1669 for delegate
in arch
['delegate']:
1670 if (delegate
['from'] != delegate
['to'][1]):
1671 label
= "%s:%s" % (delegate
['from'], delegate
['to'][1])
1673 label
= delegate
['from']
1675 if (not delegate
['to'][0] in labels
):
1676 labels
[delegate
['to'][0]] = []
1678 labels
[delegate
['to'][0]].append(label
)
1680 for delegate
in arch
['delegate']:
1681 if (not delegate
['to'][0] in labels
):
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]]
1690 outf
.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent
), prefix
, prefix
, delegate
['to'][0], ", ".join(attrs
)))
1692 if ('subsume' in arch
):
1693 outf
.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent
), prefix
))
1696 for subsume
in arch
['subsume']:
1697 if (subsume
['from'][1] != subsume
['to']):
1698 label
= "%s:%s" % (subsume
['from'][1], subsume
['to'])
1700 label
= subsume
['to']
1702 if (not subsume
['from'][0] in labels
):
1703 labels
[subsume
['from'][0]] = []
1705 labels
[subsume
['from'][0]].append(label
)
1707 for subsume
in arch
['subsume']:
1708 if (not subsume
['from'][0] in labels
):
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]]
1717 outf
.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent
), prefix
, subsume
['from'][0], prefix
, ", ".join(attrs
)))
1719 outf
.write("%s}\n" % tabs(indent
))
1720 outf
.write("%s\n" % tabs(indent
))
1722 def dump_dot(outdir
):
1723 "Dump Dot architecture"
1727 arch
= get_system_arch()
1730 print("Unable to find system architecture")
1734 outname
= os
.path
.join(outdir
, "%s.dot" % arch
['name'])
1735 outf
= open(outname
, "w")
1737 outf
.write("digraph {\n")
1738 outf
.write("\tlabel=\"%s\";\n" % arch
['name'])
1739 outf
.write("\tcompound=true;\n")
1740 outf
.write("\tsplines=\"polyline\";\n")
1741 outf
.write("\tedge [fontsize=8];\n")
1744 if ('inst' in arch
):
1745 for inst
in arch
['inst']:
1746 subarch
= get_arch(inst
['type'])
1747 if (not subarch
is None):
1748 merge_dot_arch(inst
['var'], inst
['var'], subarch
, outf
, 1)
1750 subframe
= get_frame(inst
['type'])
1751 if (not subframe
is None):
1752 merge_dot_frame("%s" % inst
['var'], inst
['var'], subframe
, outf
, 1)
1754 print("%s: '%s' is neither an architecture nor a frame" % (arch
['name'], inst
['type']))
1756 if ('bind' in arch
):
1758 for bind
in arch
['bind']:
1759 if (bind
['from'][1] != bind
['to'][1]):
1760 label
= "%s:%s" % (bind
['from'][1], bind
['to'][1])
1762 label
= bind
['from'][1]
1764 if (not (bind
['from'][0], bind
['to'][0]) in labels
):
1765 labels
[(bind
['from'][0], bind
['to'][0])] = []
1767 labels
[(bind
['from'][0], bind
['to'][0])].append(label
)
1769 for bind
in arch
['bind']:
1770 if (not (bind
['from'][0], bind
['to'][0]) in labels
):
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])
1779 attrs
.append("label=\"%s\"" % "\\n".join(labels
[(bind
['from'][0], bind
['to'][0])]))
1780 del labels
[(bind
['from'][0], bind
['to'][0])]
1782 outf
.write("\t%s__requires -> %s__provides [%s];\n" % (bind
['from'][0], bind
['to'][0], ", ".join(attrs
)))
1784 if ('delegate' in arch
):
1785 for delegate
in arch
['delegate']:
1786 print("Unable to delegate interface in system architecture")
1789 if ('subsume' in arch
):
1790 for subsume
in arch
['subsume']:
1791 print("Unable to subsume interface in system architecture")
1799 global iface_properties
1800 global frame_properties
1801 global arch_properties
1807 if (len(sys
.argv
) < 3):
1816 for arg
in sys
.argv
[1:(len(sys
.argv
) - 1)]:
1819 elif (arg
== "--ebp"):
1821 elif (arg
== "--adl"):
1823 elif (arg
== "--dot"):
1825 elif (arg
== "--nop"):
1828 print("Error: Unknown command line option '%s'" % arg
)
1831 if ((opt_bp
) and (opt_ebp
)):
1832 print("Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols")
1835 path
= os
.path
.abspath(sys
.argv
[-1])
1836 if (not os
.path
.isdir(path
)):
1837 print("Error: <OUTPUT> is not a directory")
1840 iface_properties
= {}
1841 frame_properties
= {}
1842 arch_properties
= {}
1844 recursion(".", ".", path
, 0)
1848 if __name__
== '__main__':