source: mainline/contrib/arch/hadlbppp.py@ 51d4040

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

add support for 'alternative' statement in BP
implement interface protocol repetition

  • Property mode set to 100755
File size: 32.3 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 merge_subarch(prefix, arch, outdir):
425 "Merge subarchitecture into architexture"
426
427 insts = []
428 binds = []
429 delegates = []
430 subsumes = []
431
432 if ('inst' in arch):
433 for inst in arch['inst']:
434 subarch = get_arch(inst['type'])
435 if (not subarch is None):
436 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
437 insts.extend(subinsts)
438 binds.extend(subbinds)
439 delegates.extend(subdelegates)
440 subsumes.extend(subsubsumes)
441 else:
442 subframe = get_frame(inst['type'])
443 if (not subframe is None):
444 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
445 else:
446 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
447
448 if ('bind' in arch):
449 for bind in arch['bind']:
450 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
451
452 if ('delegate' in arch):
453 for delegate in arch['delegate']:
454 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
455
456 if ('subsume' in arch):
457 for subsume in arch['subsume']:
458 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
459
460 return (insts, binds, delegates, subsumes)
461
462def dump_archbp(outdir):
463 "Dump system architecture Behavior Protocol"
464
465 arch = get_system_arch()
466
467 if (arch is None):
468 print "Unable to find system architecture"
469 return
470
471 insts = []
472 binds = []
473 delegates = []
474 subsumes = []
475
476 if ('inst' in arch):
477 for inst in arch['inst']:
478 subarch = get_arch(inst['type'])
479 if (not subarch is None):
480 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch(subarch['name'], subarch, outdir)
481 insts.extend(subinsts)
482 binds.extend(subbinds)
483 delegates.extend(subdelegates)
484 subsumes.extend(subsubsumes)
485 else:
486 subframe = get_frame(inst['type'])
487 if (not subframe is None):
488 insts.append({'var': inst['var'], 'frame': subframe})
489 else:
490 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
491
492 if ('bind' in arch):
493 for bind in arch['bind']:
494 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
495
496 if ('delegate' in arch):
497 for delegate in arch['delegate']:
498 print "Unable to delegate interface in system architecture"
499 break
500
501 if ('subsume' in arch):
502 for subsume in arch['subsume']:
503 print "Unable to subsume interface in system architecture"
504 break
505
506 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
507 outf = file(outname, "w")
508
509 create_null_bp("null.bp", outdir, outf)
510
511 for inst in insts:
512 dump_frame(inst['frame'], outdir, inst['var'], outf)
513
514 for bind in binds:
515 for delegate in delegates:
516 if (bind['to'] == delegate['to']):
517 bind['to'] = delegate['rep']
518 break
519
520 for subsume in subsumes:
521 if (bind['from'] == subsume['from']):
522 bind['from'] = subsume['rep']
523 break
524
525 outf.write("bind %s to %s\n" % (bind['from'], bind['to']))
526
527 outf.close()
528
529def preproc_adl(raw, inarg):
530 "Preprocess %% statements in ADL"
531
532 return raw.replace("%%", inarg)
533
534def parse_adl(base, root, inname, nested, indent):
535 "Parse Architecture Description Language"
536
537 global output
538 global context
539 global architecture
540 global interface
541 global frame
542 global protocol
543
544 global iface_properties
545 global frame_properties
546 global arch_properties
547
548 global arg0
549
550 if (nested):
551 parts = inname.split("%")
552
553 if (len(parts) > 1):
554 inarg = parts[1]
555 else:
556 inarg = "%%"
557
558 if (parts[0][0:1] == "/"):
559 path = os.path.join(base, ".%s" % parts[0])
560 nested_root = os.path.dirname(path)
561 else:
562 path = os.path.join(root, parts[0])
563 nested_root = root
564
565 if (not os.path.isfile(path)):
566 print "%s: Unable to include file %s" % (inname, path)
567 return ""
568 else:
569 inarg = "%%"
570 path = inname
571 nested_root = root
572
573 inf = file(path, "r")
574
575 raw = preproc_adl(inf.read(), inarg)
576 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
577
578 for token in tokens:
579
580 # Includes
581
582 if (INC in context):
583 context.remove(INC)
584 parse_adl(base, nested_root, token, True, indent)
585 context.add(POST_INC)
586 continue
587
588 if (POST_INC in context):
589 if (token != "]"):
590 print "%s: Expected ]" % inname
591
592 context.remove(POST_INC)
593 continue
594
595 # Comments and newlines
596
597 if (BLOCK_COMMENT in context):
598 if (token == "*/"):
599 context.remove(BLOCK_COMMENT)
600
601 continue
602
603 if (LINE_COMMENT in context):
604 if (token == "\n"):
605 context.remove(LINE_COMMENT)
606
607 continue
608
609 # Any context
610
611 if (token == "/*"):
612 context.add(BLOCK_COMMENT)
613 continue
614
615 if (token == "#"):
616 context.add(LINE_COMMENT)
617 continue
618
619 if (token == "["):
620 context.add(INC)
621 continue
622
623 if (token == "\n"):
624 continue
625
626 # "frame"
627
628 if (FRAME in context):
629 if (NULL in context):
630 if (token != ";"):
631 print "%s: Expected ';' in frame '%s'" % (inname, frame)
632 else:
633 output += "%s\n" % token
634
635 context.remove(NULL)
636 context.remove(FRAME)
637 frame = None
638 continue
639
640 if (BODY in context):
641 if (PROTOCOL in context):
642 if (token == "{"):
643 indent += 1
644 elif (token == "}"):
645 indent -= 1
646
647 if (indent == -1):
648 bp = split_bp(protocol)
649 protocol = None
650
651 if (not frame in frame_properties):
652 frame_properties[frame] = {}
653
654 if ('protocol' in frame_properties[frame]):
655 print "%s: Protocol for frame '%s' already defined" % (inname, frame)
656 else:
657 frame_properties[frame]['protocol'] = bp
658
659 output += "\n%s" % tabs(2)
660 output += parse_bp(inname, bp, 2)
661 output += "\n%s" % token
662 indent = 0
663
664 context.remove(PROTOCOL)
665 context.remove(BODY)
666 context.add(NULL)
667 else:
668 protocol += token
669
670 continue
671
672 if (REQUIRES in context):
673 if (FIN in context):
674 if (token != ";"):
675 print "%s: Expected ';' in frame '%s'" % (inname, frame)
676 else:
677 output += "%s" % token
678
679 context.remove(FIN)
680 continue
681
682 if (VAR in context):
683 if (not identifier(token)):
684 print "%s: Variable name expected in frame '%s'" % (inname, frame)
685 else:
686 if (not frame in frame_properties):
687 frame_properties[frame] = {}
688
689 if (not 'requires' in frame_properties[frame]):
690 frame_properties[frame]['requires'] = []
691
692 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
693 arg0 = None
694
695 output += "%s" % token
696
697 context.remove(VAR)
698 context.add(FIN)
699 continue
700
701 if ((token == "}") or (token[-1] == ":")):
702 context.remove(REQUIRES)
703 else:
704 if (not identifier(token)):
705 print "%s: Interface name expected in frame '%s'" % (inname, frame)
706 else:
707 arg0 = token
708 output += "\n%s%s " % (tabs(indent), token)
709
710 context.add(VAR)
711 continue
712
713 if (PROVIDES in context):
714 if (FIN in context):
715 if (token != ";"):
716 print "%s: Expected ';' in frame '%s'" % (inname, frame)
717 else:
718 output += "%s" % token
719
720 context.remove(FIN)
721 continue
722
723 if (VAR in context):
724 if (not identifier(token)):
725 print "%s: Variable name expected in frame '%s'" % (inname, frame)
726 else:
727 if (not frame in frame_properties):
728 frame_properties[frame] = {}
729
730 if (not 'provides' in frame_properties[frame]):
731 frame_properties[frame]['provides'] = []
732
733 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
734 arg0 = None
735
736 output += "%s" % token
737
738 context.remove(VAR)
739 context.add(FIN)
740 continue
741
742 if ((token == "}") or (token[-1] == ":")):
743 context.remove(PROVIDES)
744 else:
745 if (not identifier(token)):
746 print "%s: Interface name expected in frame '%s'" % (inname, frame)
747 else:
748 arg0 = token
749 output += "\n%s%s " % (tabs(indent), token)
750
751 context.add(VAR)
752 continue
753
754 if (token == "}"):
755 if (indent != 2):
756 print "%s: Wrong number of parentheses in frame '%s'" % (inname, frame)
757 else:
758 indent = 0
759 output += "\n%s" % token
760
761 context.remove(BODY)
762 context.add(NULL)
763 continue
764
765 if (token == "provides:"):
766 output += "\n%s%s" % (tabs(indent - 1), token)
767 context.add(PROVIDES)
768 protocol = ""
769 continue
770
771 if (token == "requires:"):
772 output += "\n%s%s" % (tabs(indent - 1), token)
773 context.add(REQUIRES)
774 protocol = ""
775 continue
776
777 if (token == "protocol:"):
778 output += "\n%s%s" % (tabs(indent - 1), token)
779 indent = 0
780 context.add(PROTOCOL)
781 protocol = ""
782 continue
783
784 print "%s: Unknown token '%s' in frame '%s'" % (inname, token, frame)
785 continue
786
787 if (HEAD in context):
788 if (token == "{"):
789 output += "%s" % token
790 indent += 2
791 context.remove(HEAD)
792 context.add(BODY)
793 continue
794
795 if (token == ";"):
796 output += "%s\n" % token
797 context.remove(HEAD)
798 context.remove(FRAME)
799 continue
800
801 print "%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame)
802
803 continue
804
805 if (not identifier(token)):
806 print "%s: Expected frame name" % inname
807 else:
808 frame = token
809 output += "%s " % token
810
811 if (not frame in frame_properties):
812 frame_properties[frame] = {}
813
814 frame_properties[frame]['name'] = frame
815
816 context.add(HEAD)
817 continue
818
819 # "interface"
820
821 if (IFACE in context):
822 if (NULL in context):
823 if (token != ";"):
824 print "%s: Expected ';' in interface '%s'" % (inname, interface)
825 else:
826 output += "%s\n" % token
827
828 context.remove(NULL)
829 context.remove(IFACE)
830 interface = None
831 continue
832
833 if (BODY in context):
834 if (PROTOCOL in context):
835 if (token == "{"):
836 indent += 1
837 elif (token == "}"):
838 indent -= 1
839
840 if (indent == -1):
841 bp = split_bp(protocol)
842 protocol = None
843
844 if (not interface in iface_properties):
845 iface_properties[interface] = {}
846
847 if ('protocol' in iface_properties[interface]):
848 print "%s: Protocol for interface '%s' already defined" % (inname, interface)
849 else:
850 iface_properties[interface]['protocol'] = bp
851
852 output += "\n%s" % tabs(2)
853 output += parse_bp(inname, bp, 2)
854 output += "\n%s" % token
855 indent = 0
856
857 context.remove(PROTOCOL)
858 context.remove(BODY)
859 context.add(NULL)
860 else:
861 protocol += token
862
863 continue
864
865 if (PROTOTYPE in context):
866 if (FIN in context):
867 if (token != ";"):
868 print "%s: Expected ';' in interface '%s'" % (inname, interface)
869 else:
870 output += "%s" % token
871
872 context.remove(FIN)
873 context.remove(PROTOTYPE)
874 continue
875
876 if (PAR_RIGHT in context):
877 if (token == ")"):
878 output += "%s" % token
879 context.remove(PAR_RIGHT)
880 context.add(FIN)
881 else:
882 output += " %s" % token
883
884 continue
885
886 if (SIGNATURE in context):
887 output += "%s" % token
888 if (token == ")"):
889 context.remove(SIGNATURE)
890 context.add(FIN)
891
892 context.remove(SIGNATURE)
893 context.add(PAR_RIGHT)
894 continue
895
896 if (PAR_LEFT in context):
897 if (token != "("):
898 print "%s: Expected '(' in interface '%s'" % (inname, interface)
899 else:
900 output += "%s" % token
901
902 context.remove(PAR_LEFT)
903 context.add(SIGNATURE)
904 continue
905
906 if (not identifier(token)):
907 print "%s: Method identifier expected in interface '%s'" % (inname, interface)
908 else:
909 output += "%s" % token
910
911 context.add(PAR_LEFT)
912 continue
913
914 if (token == "}"):
915 if (indent != 2):
916 print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
917 else:
918 indent = 0
919 output += "\n%s" % token
920
921 context.remove(BODY)
922 context.add(NULL)
923 continue
924
925 if ((token == "ipcarg_t") or (token == "unative_t")):
926 output += "\n%s%s " % (tabs(indent), token)
927 context.add(PROTOTYPE)
928 continue
929
930 if (token == "protocol:"):
931 output += "\n%s%s" % (tabs(indent - 1), token)
932 indent = 0
933 context.add(PROTOCOL)
934 protocol = ""
935 continue
936
937 print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
938 continue
939
940 if (HEAD in context):
941 if (token == "{"):
942 output += "%s" % token
943 indent += 2
944 context.remove(HEAD)
945 context.add(BODY)
946 continue
947
948 if (token == ";"):
949 output += "%s\n" % token
950 context.remove(HEAD)
951 context.remove(IFACE)
952 continue
953
954 if (not word(token)):
955 print "%s: Expected word in interface head '%s'" % (inname, interface)
956 else:
957 output += "%s " % token
958
959 continue
960
961 if (not identifier(token)):
962 print "%s: Expected interface name" % inname
963 else:
964 interface = token
965 output += "%s " % token
966
967 if (not interface in iface_properties):
968 iface_properties[interface] = {}
969
970 iface_properties[interface]['name'] = interface
971
972 context.add(HEAD)
973 continue
974
975 # "architecture"
976
977 if (ARCH in context):
978 if (NULL in context):
979 if (token != ";"):
980 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
981 else:
982 output += "%s\n" % token
983
984 context.remove(NULL)
985 context.remove(ARCH)
986 context.discard(SYSTEM)
987 architecture = None
988 continue
989
990 if (BODY in context):
991 if (DELEGATE in context):
992 if (FIN in context):
993 if (token != ";"):
994 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
995 else:
996 output += "%s" % token
997
998 context.remove(FIN)
999 context.remove(DELEGATE)
1000 continue
1001
1002 if (VAR in context):
1003 if (not descriptor(token)):
1004 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1005 else:
1006 if (not architecture in arch_properties):
1007 arch_properties[architecture] = {}
1008
1009 if (not 'delegate' in arch_properties[architecture]):
1010 arch_properties[architecture]['delegate'] = []
1011
1012 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1013 arg0 = None
1014
1015 output += "%s" % token
1016
1017 context.add(FIN)
1018 context.remove(VAR)
1019 continue
1020
1021 if (TO in context):
1022 if (token != "to"):
1023 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1024 else:
1025 output += "%s " % token
1026
1027 context.add(VAR)
1028 context.remove(TO)
1029 continue
1030
1031 if (not identifier(token)):
1032 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1033 else:
1034 output += "%s " % token
1035 arg0 = token
1036
1037 context.add(TO)
1038 continue
1039
1040 if (SUBSUME in context):
1041 if (FIN in context):
1042 if (token != ";"):
1043 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1044 else:
1045 output += "%s" % token
1046
1047 context.remove(FIN)
1048 context.remove(SUBSUME)
1049 continue
1050
1051 if (VAR in context):
1052 if (not identifier(token)):
1053 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1054 else:
1055 if (not architecture in arch_properties):
1056 arch_properties[architecture] = {}
1057
1058 if (not 'subsume' in arch_properties[architecture]):
1059 arch_properties[architecture]['subsume'] = []
1060
1061 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1062 arg0 = None
1063
1064 output += "%s" % token
1065
1066 context.add(FIN)
1067 context.remove(VAR)
1068 continue
1069
1070 if (TO in context):
1071 if (token != "to"):
1072 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1073 else:
1074 output += "%s " % token
1075
1076 context.add(VAR)
1077 context.remove(TO)
1078 continue
1079
1080 if (not descriptor(token)):
1081 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1082 else:
1083 output += "%s " % token
1084 arg0 = token
1085
1086 context.add(TO)
1087 continue
1088
1089 if (BIND in context):
1090 if (FIN in context):
1091 if (token != ";"):
1092 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1093 else:
1094 output += "%s" % token
1095
1096 context.remove(FIN)
1097 context.remove(BIND)
1098 continue
1099
1100 if (VAR in context):
1101 if (not descriptor(token)):
1102 print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
1103 else:
1104 if (not architecture in arch_properties):
1105 arch_properties[architecture] = {}
1106
1107 if (not 'bind' in arch_properties[architecture]):
1108 arch_properties[architecture]['bind'] = []
1109
1110 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1111 arg0 = None
1112
1113 output += "%s" % token
1114
1115 context.add(FIN)
1116 context.remove(VAR)
1117 continue
1118
1119 if (TO in context):
1120 if (token != "to"):
1121 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1122 else:
1123 output += "%s " % token
1124
1125 context.add(VAR)
1126 context.remove(TO)
1127 continue
1128
1129 if (not descriptor(token)):
1130 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1131 else:
1132 output += "%s " % token
1133 arg0 = token
1134
1135 context.add(TO)
1136 continue
1137
1138 if (INST in context):
1139 if (FIN in context):
1140 if (token != ";"):
1141 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1142 else:
1143 output += "%s" % token
1144
1145 context.remove(FIN)
1146 context.remove(INST)
1147 continue
1148
1149 if (VAR in context):
1150 if (not identifier(token)):
1151 print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
1152 else:
1153 if (not architecture in arch_properties):
1154 arch_properties[architecture] = {}
1155
1156 if (not 'inst' in arch_properties[architecture]):
1157 arch_properties[architecture]['inst'] = []
1158
1159 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1160 arg0 = None
1161
1162 output += "%s" % token
1163
1164 context.add(FIN)
1165 context.remove(VAR)
1166 continue
1167
1168 if (not identifier(token)):
1169 print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
1170 else:
1171 output += "%s " % token
1172 arg0 = token
1173
1174 context.add(VAR)
1175 continue
1176
1177 if (token == "}"):
1178 if (indent != 1):
1179 print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
1180 else:
1181 indent -= 1
1182 output += "\n%s" % token
1183
1184 context.remove(BODY)
1185 context.add(NULL)
1186 continue
1187
1188 if (token == "inst"):
1189 output += "\n%s%s " % (tabs(indent), token)
1190 context.add(INST)
1191 continue
1192
1193 if (token == "bind"):
1194 output += "\n%s%s " % (tabs(indent), token)
1195 context.add(BIND)
1196 continue
1197
1198 if (token == "subsume"):
1199 output += "\n%s%s " % (tabs(indent), token)
1200 context.add(SUBSUME)
1201 continue
1202
1203 if (token == "delegate"):
1204 output += "\n%s%s " % (tabs(indent), token)
1205 context.add(DELEGATE)
1206 continue
1207
1208 print "%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture)
1209 continue
1210
1211 if (HEAD in context):
1212 if (token == "{"):
1213 output += "%s" % token
1214 indent += 1
1215 context.remove(HEAD)
1216 context.add(BODY)
1217 continue
1218
1219 if (token == ";"):
1220 output += "%s\n" % token
1221 context.remove(HEAD)
1222 context.remove(ARCH)
1223 context.discard(SYSTEM)
1224 continue
1225
1226 if (not word(token)):
1227 print "%s: Expected word in architecture head '%s'" % (inname, architecture)
1228 else:
1229 output += "%s " % token
1230
1231 continue
1232
1233 if (not identifier(token)):
1234 print "%s: Expected architecture name" % inname
1235 else:
1236 architecture = token
1237 output += "%s " % token
1238
1239 if (not architecture in arch_properties):
1240 arch_properties[architecture] = {}
1241
1242 arch_properties[architecture]['name'] = architecture
1243
1244 if (SYSTEM in context):
1245 arch_properties[architecture]['system'] = True
1246
1247 context.add(HEAD)
1248 continue
1249
1250 # "system architecture"
1251
1252 if (SYSTEM in context):
1253 if (token != "architecture"):
1254 print "%s: Expected 'architecture'" % inname
1255 else:
1256 output += "%s " % token
1257
1258 context.add(ARCH)
1259 continue
1260
1261 if (token == "frame"):
1262 output += "\n%s " % token
1263 context.add(FRAME)
1264 continue
1265
1266 if (token == "interface"):
1267 output += "\n%s " % token
1268 context.add(IFACE)
1269 continue
1270
1271 if (token == "system"):
1272 output += "\n%s " % token
1273 context.add(SYSTEM)
1274 continue
1275
1276 if (token == "architecture"):
1277 output += "\n%s " % token
1278 context.add(ARCH)
1279 continue
1280
1281 print "%s: Unknown token '%s'" % (inname, token)
1282
1283 inf.close()
1284
1285def open_adl(base, root, inname, outdir, outname):
1286 "Open Architecture Description file"
1287
1288 global output
1289 global context
1290 global architecture
1291 global interface
1292 global frame
1293 global protocol
1294
1295 global arg0
1296
1297 output = ""
1298 context = set()
1299 architecture = None
1300 interface = None
1301 frame = None
1302 protocol = None
1303 arg0 = None
1304
1305 parse_adl(base, root, inname, False, 0)
1306 output = output.strip()
1307
1308 if (output != ""):
1309 outf = file(outname, "w")
1310 outf.write(output)
1311 outf.close()
1312
1313def recursion(base, root, output, level):
1314 "Recursive directory walk"
1315
1316 for name in os.listdir(root):
1317 canon = os.path.join(root, name)
1318
1319 if (os.path.isfile(canon)):
1320 fcomp = split_tokens(canon, ["."])
1321 cname = canon.split("/")
1322
1323 if (fcomp[-1] == ".adl"):
1324 output_path = os.path.join(output, cname[-1])
1325 open_adl(base, root, canon, output, output_path)
1326
1327 if (os.path.isdir(canon)):
1328 recursion(base, canon, output, level + 1)
1329
1330def main():
1331 global iface_properties
1332 global frame_properties
1333 global arch_properties
1334
1335 if (len(sys.argv) < 2):
1336 usage(sys.argv[0])
1337 return
1338
1339 path = os.path.abspath(sys.argv[1])
1340 if (not os.path.isdir(path)):
1341 print "Error: <OUTPUT> is not a directory"
1342 return
1343
1344 iface_properties = {}
1345 frame_properties = {}
1346 arch_properties = {}
1347
1348 recursion(".", ".", path, 0)
1349 dump_archbp(path)
1350
1351if __name__ == '__main__':
1352 main()
Note: See TracBrowser for help on using the repository browser.