source: mainline/contrib/arch/hadlbppp.py@ b988db0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b988db0 was 100aaf5, checked in by Martin Decky <martin@…>, 16 years ago

add support for generating Extended Bahavior Protocols output

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