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

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

flattening of bindings has to be done interatively until there is anything left

  • Property mode set to 100755
File size: 32.8 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
36# TODO:
37# - interface inheritance
38
39INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
40 INST, VAR, FIN, BIND, TO, SUBSUME, DELEGATE, IFACE, PROTOTYPE, PAR_LEFT, \
41 PAR_RIGHT, SIGNATURE, PROTOCOL, FRAME, PROVIDES, REQUIRES = range(25)
42
43def usage(prname):
44 "Print usage syntax"
45
46 print "%s <OUTPUT>" % prname
47
48def tabs(cnt):
49 "Return given number of tabs"
50
51 return ("\t" * cnt)
52
53def cond_append(tokens, token, trim):
54 "Conditionally append token to tokens with trim"
55
56 if (trim):
57 token = token.strip(" \t")
58
59 if (token != ""):
60 tokens.append(token)
61
62 return tokens
63
64def split_tokens(string, delimiters, trim = False, separate = False):
65 "Split string to tokens by delimiters, keep the delimiters"
66
67 tokens = []
68 last = 0
69 i = 0
70
71 while (i < len(string)):
72 for delim in delimiters:
73 if (len(delim) > 0):
74
75 if (string[i:(i + len(delim))] == delim):
76 if (separate):
77 tokens = cond_append(tokens, string[last:i], trim)
78 tokens = cond_append(tokens, delim, trim)
79 last = i + len(delim)
80 elif (i > 0):
81 tokens = cond_append(tokens, string[last:i], trim)
82 last = i
83
84 i += len(delim) - 1
85 break
86
87 i += 1
88
89 tokens = cond_append(tokens, string[last:len(string)], trim)
90
91 return tokens
92
93def identifier(token):
94 "Check whether the token is an identifier"
95
96 if (len(token) == 0):
97 return False
98
99 for i, char in enumerate(token):
100 if (i == 0):
101 if ((not char.isalpha()) and (char != "_")):
102 return False
103 else:
104 if ((not char.isalnum()) and (char != "_")):
105 return False
106
107 return True
108
109def descriptor(token):
110 "Check whether the token is an interface descriptor"
111
112 parts = token.split(":")
113 if (len(parts) != 2):
114 return False
115
116 return (identifier(parts[0]) and identifier(parts[1]))
117
118def word(token):
119 "Check whether the token is a word"
120
121 if (len(token) == 0):
122 return False
123
124 for i, char in enumerate(token):
125 if ((not char.isalnum()) and (char != "_") and (char != ".")):
126 return False
127
128 return True
129
130def tentative_bp(name, tokens):
131 "Preprocess tentative statements in Behavior Protocol"
132
133 result = []
134 i = 0
135
136 while (i < len(tokens)):
137 if (tokens[i] == "tentative"):
138 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
139 i += 2
140 start = i
141 level = 1
142
143 while ((i < len(tokens)) and (level > 0)):
144 if (tokens[i] == "{"):
145 level += 1
146 elif (tokens[i] == "}"):
147 level -= 1
148
149 i += 1
150
151 if (level == 0):
152 result.append("(")
153 result.extend(tentative_bp(name, tokens[start:(i - 1)]))
154 result.append(")")
155 result.append("+")
156 result.append("NULL")
157 if (i < len(tokens)):
158 result.append(tokens[i])
159 else:
160 print "%s: Syntax error in tentative statement" % name
161 else:
162 print "%s: Expected '{' for tentative statement" % name
163 else:
164 result.append(tokens[i])
165
166 i += 1
167
168 return result
169
170def alternative_bp(name, tokens):
171 "Preprocess alternative statements in Behavior Protocol"
172
173 result = []
174 i = 0
175
176 while (i < len(tokens)):
177 if (tokens[i] == "alternative"):
178 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "(")):
179 i += 2
180 reps = []
181
182 while ((i < len(tokens)) and (tokens[i] != ")")):
183 reps.append(tokens[i])
184 if ((i + 1 < len(tokens)) and (tokens[i + 1] == ";")):
185 i += 2
186 else:
187 i += 1
188
189 if (len(reps) >= 2):
190 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
191 i += 2
192
193 start = i
194 level = 1
195
196 while ((i < len(tokens)) and (level > 0)):
197 if (tokens[i] == "{"):
198 level += 1
199 elif (tokens[i] == "}"):
200 level -= 1
201
202 i += 1
203
204 if (level == 0):
205 first = True
206
207 for rep in reps[1:]:
208 retokens = []
209 for token in tokens[start:(i - 1)]:
210 parts = token.split(".")
211 if ((len(parts) == 2) and (parts[0] == reps[0])):
212 retokens.append("%s.%s" % (rep, parts[1]))
213 else:
214 retokens.append(token)
215
216 if (first):
217 first = False
218 else:
219 result.append("+")
220
221 result.append("(")
222 result.extend(alternative_bp(name, retokens))
223 result.append(")")
224
225 if (i < len(tokens)):
226 result.append(tokens[i])
227 else:
228 print "%s: Syntax error in alternative statement" % name
229 else:
230 print "%s: Expected '{' for alternative statement body" % name
231 else:
232 print "%s: At least one pattern and one replacement required for alternative statement" % name
233 else:
234 print "%s: Expected '(' for alternative statement head" % name
235 else:
236 result.append(tokens[i])
237
238 i += 1
239
240 return result
241
242def split_bp(protocol):
243 "Convert Behavior Protocol to tokens"
244
245 return split_tokens(protocol, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
246
247def extend_bp(name, tokens, iface):
248 "Convert interface Behavior Protocol to generic protocol"
249
250 result = ["("]
251 i = 0
252
253 while (i < len(tokens)):
254 result.append(tokens[i])
255
256 if (tokens[i] == "?"):
257 if (i + 1 < len(tokens)):
258 i += 1
259 parts = tokens[i].split(".")
260
261 if (len(parts) == 1):
262 result.append("%s.%s" % (iface, tokens[i]))
263 else:
264 result.append(tokens[i])
265 else:
266 print "%s: Unexpected end of protocol" % name
267
268 i += 1
269
270 result.append(")")
271 result.append("*")
272
273 return result
274
275def merge_bp(protocols):
276 "Merge several Behavior Protocols"
277
278 if (len(protocols) > 1):
279 result = []
280 first = True
281
282 for protocol in protocols:
283 if (first):
284 first = False
285 else:
286 result.append("|")
287
288 result.append("(")
289 result.extend(protocol)
290 result.append(")")
291
292 return result
293
294 if (len(protocols) == 1):
295 return protocols[0]
296
297 return []
298
299def parse_bp(name, tokens, base_indent):
300 "Parse Behavior Protocol"
301
302 tokens = tentative_bp(name, tokens)
303 tokens = alternative_bp(name, tokens)
304
305 indent = base_indent
306 output = ""
307
308 for token in tokens:
309 if (token == "\n"):
310 continue
311
312 if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
313 output += " %s" % token
314 elif (token == "("):
315 output += "\n%s%s" % (tabs(indent), token)
316 indent += 1
317 elif (token == ")"):
318 if (indent < base_indent):
319 print "%s: Too many parentheses" % name
320
321 indent -= 1
322 output += "\n%s%s" % (tabs(indent), token)
323 elif (token == "{"):
324 output += " %s" % token
325 indent += 1
326 elif (token == "}"):
327 if (indent < base_indent):
328 print "%s: Too many parentheses" % name
329
330 indent -= 1
331 output += "\n%s%s" % (tabs(indent), token)
332 elif (token == "*"):
333 output += "%s" % token
334 elif ((token == "!") or (token == "?") or (token == "NULL")):
335 output += "\n%s%s" % (tabs(indent), token)
336 else:
337 output += "%s" % token
338
339 if (indent > base_indent):
340 print "%s: Missing parentheses" % name
341
342 output = output.strip()
343 if (output == ""):
344 return "NULL"
345
346 return output
347
348def get_iface(name):
349 "Get interface by name"
350
351 global iface_properties
352
353 if (name in iface_properties):
354 return iface_properties[name]
355
356 return None
357
358def dump_frame(frame, outdir, var, archf):
359 "Dump Behavior Protocol of a given frame"
360
361 fname = "%s.bp" % frame['name']
362
363 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
364 outname = os.path.join(outdir, fname)
365
366 protocols = []
367 if ('protocol' in frame):
368 protocols.append(frame['protocol'])
369
370 if ('provides' in frame):
371 for provides in frame['provides']:
372 iface = get_iface(provides['iface'])
373 if (not iface is None):
374 if ('protocol' in iface):
375 protocols.append(extend_bp(outname, iface['protocol'], iface['name']))
376 else:
377 print "%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface'])
378
379 outf = file(outname, "w")
380 outf.write(parse_bp(outname, merge_bp(protocols), 0))
381 outf.close()
382
383def get_system_arch():
384 "Get system architecture"
385
386 global arch_properties
387
388 for arch, properties in arch_properties.items():
389 if ('system' in properties):
390 return properties
391
392 return None
393
394def get_arch(name):
395 "Get architecture by name"
396
397 global arch_properties
398
399 if (name in arch_properties):
400 return arch_properties[name]
401
402 return None
403
404def get_frame(name):
405 "Get frame by name"
406
407 global frame_properties
408
409 if (name in frame_properties):
410 return frame_properties[name]
411
412 return None
413
414def create_null_bp(fname, outdir, archf):
415 "Create null frame protocol"
416
417 archf.write("frame \"%s\"\n" % fname)
418 outname = os.path.join(outdir, fname)
419
420 outf = file(outname, "w")
421 outf.write("NULL")
422 outf.close()
423
424def flatten_binds(binds, delegates, subsumes):
425 "Remove bindings which are replaced by delegation or subsumption"
426
427 result = []
428 stable = True
429
430 for bind in binds:
431 keep = True
432
433 for delegate in delegates:
434 if (bind['to'] == delegate['to']):
435 keep = False
436 result.append({'from': bind['from'], 'to': delegate['rep']})
437
438 for subsume in subsumes:
439 if (bind['from'] == subsume['from']):
440 keep = False
441 result.append({'from': subsume['rep'], 'to': bind['to']})
442
443 if (keep):
444 result.append(bind)
445 else:
446 stable = False
447
448 if (stable):
449 return result
450 else:
451 return flatten_binds(result, delegates, subsumes)
452
453def merge_subarch(prefix, arch, outdir):
454 "Merge subarchitecture into architexture"
455
456 insts = []
457 binds = []
458 delegates = []
459 subsumes = []
460
461 if ('inst' in arch):
462 for inst in arch['inst']:
463 subarch = get_arch(inst['type'])
464 if (not subarch is None):
465 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
466 insts.extend(subinsts)
467 binds.extend(subbinds)
468 delegates.extend(subdelegates)
469 subsumes.extend(subsubsumes)
470 else:
471 subframe = get_frame(inst['type'])
472 if (not subframe is None):
473 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
474 else:
475 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
476
477 if ('bind' in arch):
478 for bind in arch['bind']:
479 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
480
481 if ('delegate' in arch):
482 for delegate in arch['delegate']:
483 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
484
485 if ('subsume' in arch):
486 for subsume in arch['subsume']:
487 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
488
489 return (insts, binds, delegates, subsumes)
490
491def dump_archbp(outdir):
492 "Dump system architecture Behavior Protocol"
493
494 arch = get_system_arch()
495
496 if (arch is None):
497 print "Unable to find system architecture"
498 return
499
500 insts = []
501 binds = []
502 delegates = []
503 subsumes = []
504
505 if ('inst' in arch):
506 for inst in arch['inst']:
507 subarch = get_arch(inst['type'])
508 if (not subarch is None):
509 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch(subarch['name'], subarch, outdir)
510 insts.extend(subinsts)
511 binds.extend(subbinds)
512 delegates.extend(subdelegates)
513 subsumes.extend(subsubsumes)
514 else:
515 subframe = get_frame(inst['type'])
516 if (not subframe is None):
517 insts.append({'var': inst['var'], 'frame': subframe})
518 else:
519 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
520
521 if ('bind' in arch):
522 for bind in arch['bind']:
523 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
524
525 if ('delegate' in arch):
526 for delegate in arch['delegate']:
527 print "Unable to delegate interface in system architecture"
528 break
529
530 if ('subsume' in arch):
531 for subsume in arch['subsume']:
532 print "Unable to subsume interface in system architecture"
533 break
534
535 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
536 outf = file(outname, "w")
537
538 create_null_bp("null.bp", outdir, outf)
539
540 for inst in insts:
541 dump_frame(inst['frame'], outdir, inst['var'], outf)
542
543 for bind in flatten_binds(binds, delegates, subsumes):
544 outf.write("bind %s to %s\n" % (bind['from'], bind['to']))
545
546 outf.close()
547
548def preproc_adl(raw, inarg):
549 "Preprocess %% statements in ADL"
550
551 return raw.replace("%%", inarg)
552
553def parse_adl(base, root, inname, nested, indent):
554 "Parse Architecture Description Language"
555
556 global output
557 global context
558 global architecture
559 global interface
560 global frame
561 global protocol
562
563 global iface_properties
564 global frame_properties
565 global arch_properties
566
567 global arg0
568
569 if (nested):
570 parts = inname.split("%")
571
572 if (len(parts) > 1):
573 inarg = parts[1]
574 else:
575 inarg = "%%"
576
577 if (parts[0][0:1] == "/"):
578 path = os.path.join(base, ".%s" % parts[0])
579 nested_root = os.path.dirname(path)
580 else:
581 path = os.path.join(root, parts[0])
582 nested_root = root
583
584 if (not os.path.isfile(path)):
585 print "%s: Unable to include file %s" % (inname, path)
586 return ""
587 else:
588 inarg = "%%"
589 path = inname
590 nested_root = root
591
592 inf = file(path, "r")
593
594 raw = preproc_adl(inf.read(), inarg)
595 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
596
597 for token in tokens:
598
599 # Includes
600
601 if (INC in context):
602 context.remove(INC)
603 parse_adl(base, nested_root, token, True, indent)
604 context.add(POST_INC)
605 continue
606
607 if (POST_INC in context):
608 if (token != "]"):
609 print "%s: Expected ]" % inname
610
611 context.remove(POST_INC)
612 continue
613
614 # Comments and newlines
615
616 if (BLOCK_COMMENT in context):
617 if (token == "*/"):
618 context.remove(BLOCK_COMMENT)
619
620 continue
621
622 if (LINE_COMMENT in context):
623 if (token == "\n"):
624 context.remove(LINE_COMMENT)
625
626 continue
627
628 # Any context
629
630 if (token == "/*"):
631 context.add(BLOCK_COMMENT)
632 continue
633
634 if (token == "#"):
635 context.add(LINE_COMMENT)
636 continue
637
638 if (token == "["):
639 context.add(INC)
640 continue
641
642 if (token == "\n"):
643 continue
644
645 # "frame"
646
647 if (FRAME in context):
648 if (NULL in context):
649 if (token != ";"):
650 print "%s: Expected ';' in frame '%s'" % (inname, frame)
651 else:
652 output += "%s\n" % token
653
654 context.remove(NULL)
655 context.remove(FRAME)
656 frame = None
657 continue
658
659 if (BODY in context):
660 if (PROTOCOL in context):
661 if (token == "{"):
662 indent += 1
663 elif (token == "}"):
664 indent -= 1
665
666 if (indent == -1):
667 bp = split_bp(protocol)
668 protocol = None
669
670 if (not frame in frame_properties):
671 frame_properties[frame] = {}
672
673 if ('protocol' in frame_properties[frame]):
674 print "%s: Protocol for frame '%s' already defined" % (inname, frame)
675 else:
676 frame_properties[frame]['protocol'] = bp
677
678 output += "\n%s" % tabs(2)
679 output += parse_bp(inname, bp, 2)
680 output += "\n%s" % token
681 indent = 0
682
683 context.remove(PROTOCOL)
684 context.remove(BODY)
685 context.add(NULL)
686 else:
687 protocol += token
688
689 continue
690
691 if (REQUIRES in context):
692 if (FIN in context):
693 if (token != ";"):
694 print "%s: Expected ';' in frame '%s'" % (inname, frame)
695 else:
696 output += "%s" % token
697
698 context.remove(FIN)
699 continue
700
701 if (VAR in context):
702 if (not identifier(token)):
703 print "%s: Variable name expected in frame '%s'" % (inname, frame)
704 else:
705 if (not frame in frame_properties):
706 frame_properties[frame] = {}
707
708 if (not 'requires' in frame_properties[frame]):
709 frame_properties[frame]['requires'] = []
710
711 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
712 arg0 = None
713
714 output += "%s" % token
715
716 context.remove(VAR)
717 context.add(FIN)
718 continue
719
720 if ((token == "}") or (token[-1] == ":")):
721 context.remove(REQUIRES)
722 else:
723 if (not identifier(token)):
724 print "%s: Interface name expected in frame '%s'" % (inname, frame)
725 else:
726 arg0 = token
727 output += "\n%s%s " % (tabs(indent), token)
728
729 context.add(VAR)
730 continue
731
732 if (PROVIDES in context):
733 if (FIN in context):
734 if (token != ";"):
735 print "%s: Expected ';' in frame '%s'" % (inname, frame)
736 else:
737 output += "%s" % token
738
739 context.remove(FIN)
740 continue
741
742 if (VAR in context):
743 if (not identifier(token)):
744 print "%s: Variable name expected in frame '%s'" % (inname, frame)
745 else:
746 if (not frame in frame_properties):
747 frame_properties[frame] = {}
748
749 if (not 'provides' in frame_properties[frame]):
750 frame_properties[frame]['provides'] = []
751
752 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
753 arg0 = None
754
755 output += "%s" % token
756
757 context.remove(VAR)
758 context.add(FIN)
759 continue
760
761 if ((token == "}") or (token[-1] == ":")):
762 context.remove(PROVIDES)
763 else:
764 if (not identifier(token)):
765 print "%s: Interface name expected in frame '%s'" % (inname, frame)
766 else:
767 arg0 = token
768 output += "\n%s%s " % (tabs(indent), token)
769
770 context.add(VAR)
771 continue
772
773 if (token == "}"):
774 if (indent != 2):
775 print "%s: Wrong number of parentheses in frame '%s'" % (inname, frame)
776 else:
777 indent = 0
778 output += "\n%s" % token
779
780 context.remove(BODY)
781 context.add(NULL)
782 continue
783
784 if (token == "provides:"):
785 output += "\n%s%s" % (tabs(indent - 1), token)
786 context.add(PROVIDES)
787 protocol = ""
788 continue
789
790 if (token == "requires:"):
791 output += "\n%s%s" % (tabs(indent - 1), token)
792 context.add(REQUIRES)
793 protocol = ""
794 continue
795
796 if (token == "protocol:"):
797 output += "\n%s%s" % (tabs(indent - 1), token)
798 indent = 0
799 context.add(PROTOCOL)
800 protocol = ""
801 continue
802
803 print "%s: Unknown token '%s' in frame '%s'" % (inname, token, frame)
804 continue
805
806 if (HEAD in context):
807 if (token == "{"):
808 output += "%s" % token
809 indent += 2
810 context.remove(HEAD)
811 context.add(BODY)
812 continue
813
814 if (token == ";"):
815 output += "%s\n" % token
816 context.remove(HEAD)
817 context.remove(FRAME)
818 continue
819
820 print "%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame)
821
822 continue
823
824 if (not identifier(token)):
825 print "%s: Expected frame name" % inname
826 else:
827 frame = token
828 output += "%s " % token
829
830 if (not frame in frame_properties):
831 frame_properties[frame] = {}
832
833 frame_properties[frame]['name'] = frame
834
835 context.add(HEAD)
836 continue
837
838 # "interface"
839
840 if (IFACE in context):
841 if (NULL in context):
842 if (token != ";"):
843 print "%s: Expected ';' in interface '%s'" % (inname, interface)
844 else:
845 output += "%s\n" % token
846
847 context.remove(NULL)
848 context.remove(IFACE)
849 interface = None
850 continue
851
852 if (BODY in context):
853 if (PROTOCOL in context):
854 if (token == "{"):
855 indent += 1
856 elif (token == "}"):
857 indent -= 1
858
859 if (indent == -1):
860 bp = split_bp(protocol)
861 protocol = None
862
863 if (not interface in iface_properties):
864 iface_properties[interface] = {}
865
866 if ('protocol' in iface_properties[interface]):
867 print "%s: Protocol for interface '%s' already defined" % (inname, interface)
868 else:
869 iface_properties[interface]['protocol'] = bp
870
871 output += "\n%s" % tabs(2)
872 output += parse_bp(inname, bp, 2)
873 output += "\n%s" % token
874 indent = 0
875
876 context.remove(PROTOCOL)
877 context.remove(BODY)
878 context.add(NULL)
879 else:
880 protocol += token
881
882 continue
883
884 if (PROTOTYPE in context):
885 if (FIN in context):
886 if (token != ";"):
887 print "%s: Expected ';' in interface '%s'" % (inname, interface)
888 else:
889 output += "%s" % token
890
891 context.remove(FIN)
892 context.remove(PROTOTYPE)
893 continue
894
895 if (PAR_RIGHT in context):
896 if (token == ")"):
897 output += "%s" % token
898 context.remove(PAR_RIGHT)
899 context.add(FIN)
900 else:
901 output += " %s" % token
902
903 continue
904
905 if (SIGNATURE in context):
906 output += "%s" % token
907 if (token == ")"):
908 context.remove(SIGNATURE)
909 context.add(FIN)
910
911 context.remove(SIGNATURE)
912 context.add(PAR_RIGHT)
913 continue
914
915 if (PAR_LEFT in context):
916 if (token != "("):
917 print "%s: Expected '(' in interface '%s'" % (inname, interface)
918 else:
919 output += "%s" % token
920
921 context.remove(PAR_LEFT)
922 context.add(SIGNATURE)
923 continue
924
925 if (not identifier(token)):
926 print "%s: Method identifier expected in interface '%s'" % (inname, interface)
927 else:
928 output += "%s" % token
929
930 context.add(PAR_LEFT)
931 continue
932
933 if (token == "}"):
934 if (indent != 2):
935 print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
936 else:
937 indent = 0
938 output += "\n%s" % token
939
940 context.remove(BODY)
941 context.add(NULL)
942 continue
943
944 if ((token == "ipcarg_t") or (token == "unative_t")):
945 output += "\n%s%s " % (tabs(indent), token)
946 context.add(PROTOTYPE)
947 continue
948
949 if (token == "protocol:"):
950 output += "\n%s%s" % (tabs(indent - 1), token)
951 indent = 0
952 context.add(PROTOCOL)
953 protocol = ""
954 continue
955
956 print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
957 continue
958
959 if (HEAD in context):
960 if (token == "{"):
961 output += "%s" % token
962 indent += 2
963 context.remove(HEAD)
964 context.add(BODY)
965 continue
966
967 if (token == ";"):
968 output += "%s\n" % token
969 context.remove(HEAD)
970 context.remove(IFACE)
971 continue
972
973 if (not word(token)):
974 print "%s: Expected word in interface head '%s'" % (inname, interface)
975 else:
976 output += "%s " % token
977
978 continue
979
980 if (not identifier(token)):
981 print "%s: Expected interface name" % inname
982 else:
983 interface = token
984 output += "%s " % token
985
986 if (not interface in iface_properties):
987 iface_properties[interface] = {}
988
989 iface_properties[interface]['name'] = interface
990
991 context.add(HEAD)
992 continue
993
994 # "architecture"
995
996 if (ARCH in context):
997 if (NULL in context):
998 if (token != ";"):
999 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1000 else:
1001 output += "%s\n" % token
1002
1003 context.remove(NULL)
1004 context.remove(ARCH)
1005 context.discard(SYSTEM)
1006 architecture = None
1007 continue
1008
1009 if (BODY in context):
1010 if (DELEGATE in context):
1011 if (FIN in context):
1012 if (token != ";"):
1013 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1014 else:
1015 output += "%s" % token
1016
1017 context.remove(FIN)
1018 context.remove(DELEGATE)
1019 continue
1020
1021 if (VAR in context):
1022 if (not descriptor(token)):
1023 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1024 else:
1025 if (not architecture in arch_properties):
1026 arch_properties[architecture] = {}
1027
1028 if (not 'delegate' in arch_properties[architecture]):
1029 arch_properties[architecture]['delegate'] = []
1030
1031 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1032 arg0 = None
1033
1034 output += "%s" % token
1035
1036 context.add(FIN)
1037 context.remove(VAR)
1038 continue
1039
1040 if (TO in context):
1041 if (token != "to"):
1042 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1043 else:
1044 output += "%s " % token
1045
1046 context.add(VAR)
1047 context.remove(TO)
1048 continue
1049
1050 if (not identifier(token)):
1051 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1052 else:
1053 output += "%s " % token
1054 arg0 = token
1055
1056 context.add(TO)
1057 continue
1058
1059 if (SUBSUME in context):
1060 if (FIN in context):
1061 if (token != ";"):
1062 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1063 else:
1064 output += "%s" % token
1065
1066 context.remove(FIN)
1067 context.remove(SUBSUME)
1068 continue
1069
1070 if (VAR in context):
1071 if (not identifier(token)):
1072 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1073 else:
1074 if (not architecture in arch_properties):
1075 arch_properties[architecture] = {}
1076
1077 if (not 'subsume' in arch_properties[architecture]):
1078 arch_properties[architecture]['subsume'] = []
1079
1080 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1081 arg0 = None
1082
1083 output += "%s" % token
1084
1085 context.add(FIN)
1086 context.remove(VAR)
1087 continue
1088
1089 if (TO in context):
1090 if (token != "to"):
1091 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1092 else:
1093 output += "%s " % token
1094
1095 context.add(VAR)
1096 context.remove(TO)
1097 continue
1098
1099 if (not descriptor(token)):
1100 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1101 else:
1102 output += "%s " % token
1103 arg0 = token
1104
1105 context.add(TO)
1106 continue
1107
1108 if (BIND in context):
1109 if (FIN in context):
1110 if (token != ";"):
1111 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1112 else:
1113 output += "%s" % token
1114
1115 context.remove(FIN)
1116 context.remove(BIND)
1117 continue
1118
1119 if (VAR in context):
1120 if (not descriptor(token)):
1121 print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
1122 else:
1123 if (not architecture in arch_properties):
1124 arch_properties[architecture] = {}
1125
1126 if (not 'bind' in arch_properties[architecture]):
1127 arch_properties[architecture]['bind'] = []
1128
1129 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1130 arg0 = None
1131
1132 output += "%s" % token
1133
1134 context.add(FIN)
1135 context.remove(VAR)
1136 continue
1137
1138 if (TO in context):
1139 if (token != "to"):
1140 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1141 else:
1142 output += "%s " % token
1143
1144 context.add(VAR)
1145 context.remove(TO)
1146 continue
1147
1148 if (not descriptor(token)):
1149 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1150 else:
1151 output += "%s " % token
1152 arg0 = token
1153
1154 context.add(TO)
1155 continue
1156
1157 if (INST in context):
1158 if (FIN in context):
1159 if (token != ";"):
1160 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1161 else:
1162 output += "%s" % token
1163
1164 context.remove(FIN)
1165 context.remove(INST)
1166 continue
1167
1168 if (VAR in context):
1169 if (not identifier(token)):
1170 print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
1171 else:
1172 if (not architecture in arch_properties):
1173 arch_properties[architecture] = {}
1174
1175 if (not 'inst' in arch_properties[architecture]):
1176 arch_properties[architecture]['inst'] = []
1177
1178 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1179 arg0 = None
1180
1181 output += "%s" % token
1182
1183 context.add(FIN)
1184 context.remove(VAR)
1185 continue
1186
1187 if (not identifier(token)):
1188 print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
1189 else:
1190 output += "%s " % token
1191 arg0 = token
1192
1193 context.add(VAR)
1194 continue
1195
1196 if (token == "}"):
1197 if (indent != 1):
1198 print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
1199 else:
1200 indent -= 1
1201 output += "\n%s" % token
1202
1203 context.remove(BODY)
1204 context.add(NULL)
1205 continue
1206
1207 if (token == "inst"):
1208 output += "\n%s%s " % (tabs(indent), token)
1209 context.add(INST)
1210 continue
1211
1212 if (token == "bind"):
1213 output += "\n%s%s " % (tabs(indent), token)
1214 context.add(BIND)
1215 continue
1216
1217 if (token == "subsume"):
1218 output += "\n%s%s " % (tabs(indent), token)
1219 context.add(SUBSUME)
1220 continue
1221
1222 if (token == "delegate"):
1223 output += "\n%s%s " % (tabs(indent), token)
1224 context.add(DELEGATE)
1225 continue
1226
1227 print "%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture)
1228 continue
1229
1230 if (HEAD in context):
1231 if (token == "{"):
1232 output += "%s" % token
1233 indent += 1
1234 context.remove(HEAD)
1235 context.add(BODY)
1236 continue
1237
1238 if (token == ";"):
1239 output += "%s\n" % token
1240 context.remove(HEAD)
1241 context.remove(ARCH)
1242 context.discard(SYSTEM)
1243 continue
1244
1245 if (not word(token)):
1246 print "%s: Expected word in architecture head '%s'" % (inname, architecture)
1247 else:
1248 output += "%s " % token
1249
1250 continue
1251
1252 if (not identifier(token)):
1253 print "%s: Expected architecture name" % inname
1254 else:
1255 architecture = token
1256 output += "%s " % token
1257
1258 if (not architecture in arch_properties):
1259 arch_properties[architecture] = {}
1260
1261 arch_properties[architecture]['name'] = architecture
1262
1263 if (SYSTEM in context):
1264 arch_properties[architecture]['system'] = True
1265
1266 context.add(HEAD)
1267 continue
1268
1269 # "system architecture"
1270
1271 if (SYSTEM in context):
1272 if (token != "architecture"):
1273 print "%s: Expected 'architecture'" % inname
1274 else:
1275 output += "%s " % token
1276
1277 context.add(ARCH)
1278 continue
1279
1280 if (token == "frame"):
1281 output += "\n%s " % token
1282 context.add(FRAME)
1283 continue
1284
1285 if (token == "interface"):
1286 output += "\n%s " % token
1287 context.add(IFACE)
1288 continue
1289
1290 if (token == "system"):
1291 output += "\n%s " % token
1292 context.add(SYSTEM)
1293 continue
1294
1295 if (token == "architecture"):
1296 output += "\n%s " % token
1297 context.add(ARCH)
1298 continue
1299
1300 print "%s: Unknown token '%s'" % (inname, token)
1301
1302 inf.close()
1303
1304def open_adl(base, root, inname, outdir, outname):
1305 "Open Architecture Description file"
1306
1307 global output
1308 global context
1309 global architecture
1310 global interface
1311 global frame
1312 global protocol
1313
1314 global arg0
1315
1316 output = ""
1317 context = set()
1318 architecture = None
1319 interface = None
1320 frame = None
1321 protocol = None
1322 arg0 = None
1323
1324 parse_adl(base, root, inname, False, 0)
1325 output = output.strip()
1326
1327 if (output != ""):
1328 outf = file(outname, "w")
1329 outf.write(output)
1330 outf.close()
1331
1332def recursion(base, root, output, level):
1333 "Recursive directory walk"
1334
1335 for name in os.listdir(root):
1336 canon = os.path.join(root, name)
1337
1338 if (os.path.isfile(canon)):
1339 fcomp = split_tokens(canon, ["."])
1340 cname = canon.split("/")
1341
1342 if (fcomp[-1] == ".adl"):
1343 output_path = os.path.join(output, cname[-1])
1344 open_adl(base, root, canon, output, output_path)
1345
1346 if (os.path.isdir(canon)):
1347 recursion(base, canon, output, level + 1)
1348
1349def main():
1350 global iface_properties
1351 global frame_properties
1352 global arch_properties
1353
1354 if (len(sys.argv) < 2):
1355 usage(sys.argv[0])
1356 return
1357
1358 path = os.path.abspath(sys.argv[1])
1359 if (not os.path.isdir(path)):
1360 print "Error: <OUTPUT> is not a directory"
1361 return
1362
1363 iface_properties = {}
1364 frame_properties = {}
1365 arch_properties = {}
1366
1367 recursion(".", ".", path, 0)
1368 dump_archbp(path)
1369
1370if __name__ == '__main__':
1371 main()
Note: See TracBrowser for help on using the repository browser.