source: mainline/contrib/arch/hadlbppp.py@ 82cf692

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

support interface inheritance on protocol level

  • Property mode set to 100755
File size: 34.5 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, FRAME, PROVIDES, \
39 REQUIRES = range(27)
40
41def usage(prname):
42 "Print usage syntax"
43
44 print "%s <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 result.append(")")
269 result.append("*")
270
271 return result
272
273def merge_bp(protocols):
274 "Merge several Behavior Protocols"
275
276 if (len(protocols) > 1):
277 result = []
278 first = True
279
280 for protocol in protocols:
281 if (first):
282 first = False
283 else:
284 result.append("|")
285
286 result.append("(")
287 result.extend(protocol)
288 result.append(")")
289
290 return result
291
292 if (len(protocols) == 1):
293 return protocols[0]
294
295 return []
296
297def parse_bp(name, tokens, base_indent):
298 "Parse Behavior Protocol"
299
300 tokens = tentative_bp(name, tokens)
301 tokens = alternative_bp(name, tokens)
302
303 indent = base_indent
304 output = ""
305
306 for token in tokens:
307 if (token == "\n"):
308 continue
309
310 if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
311 output += " %s" % token
312 elif (token == "("):
313 output += "\n%s%s" % (tabs(indent), token)
314 indent += 1
315 elif (token == ")"):
316 if (indent < base_indent):
317 print "%s: Too many parentheses" % name
318
319 indent -= 1
320 output += "\n%s%s" % (tabs(indent), token)
321 elif (token == "{"):
322 output += " %s" % token
323 indent += 1
324 elif (token == "}"):
325 if (indent < base_indent):
326 print "%s: Too many parentheses" % name
327
328 indent -= 1
329 output += "\n%s%s" % (tabs(indent), token)
330 elif (token == "*"):
331 output += "%s" % token
332 elif ((token == "!") or (token == "?") or (token == "NULL")):
333 output += "\n%s%s" % (tabs(indent), token)
334 else:
335 output += "%s" % token
336
337 if (indent > base_indent):
338 print "%s: Missing parentheses" % name
339
340 output = output.strip()
341 if (output == ""):
342 return "NULL"
343
344 return output
345
346def get_iface(name):
347 "Get interface by name"
348
349 global iface_properties
350
351 if (name in iface_properties):
352 return iface_properties[name]
353
354 return None
355
356def inherited_protocols(iface):
357 "Get protocols inherited by an interface"
358
359 result = []
360
361 if ('extends' in iface):
362 supiface = get_iface(iface['extends'])
363 if (not supiface is None):
364 if ('protocol' in supiface):
365 result.append(supiface['protocol'])
366 result.extend(inherited_protocols(supiface))
367 else:
368 print "%s: Extends unknown interface '%s'" % (iface['name'], iface['extends'])
369
370 return result
371
372def dump_frame(frame, outdir, var, archf):
373 "Dump Behavior Protocol of a given frame"
374
375 fname = "%s.bp" % frame['name']
376
377 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
378 outname = os.path.join(outdir, fname)
379
380 protocols = []
381 if ('protocol' in frame):
382 protocols.append(frame['protocol'])
383
384 if ('provides' in frame):
385 for provides in frame['provides']:
386 iface = get_iface(provides['iface'])
387 if (not iface is None):
388 if ('protocol' in iface):
389 protocols.append(extend_bp(outname, iface['protocol'], iface['name']))
390 for protocol in inherited_protocols(iface):
391 protocols.append(extend_bp(outname, protocol, iface['name']))
392 else:
393 print "%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface'])
394
395 outf = file(outname, "w")
396 outf.write(parse_bp(outname, merge_bp(protocols), 0))
397 outf.close()
398
399def get_system_arch():
400 "Get system architecture"
401
402 global arch_properties
403
404 for arch, properties in arch_properties.items():
405 if ('system' in properties):
406 return properties
407
408 return None
409
410def get_arch(name):
411 "Get architecture by name"
412
413 global arch_properties
414
415 if (name in arch_properties):
416 return arch_properties[name]
417
418 return None
419
420def get_frame(name):
421 "Get frame by name"
422
423 global frame_properties
424
425 if (name in frame_properties):
426 return frame_properties[name]
427
428 return None
429
430def create_null_bp(fname, outdir, archf):
431 "Create null frame protocol"
432
433 archf.write("frame \"%s\"\n" % fname)
434 outname = os.path.join(outdir, fname)
435
436 outf = file(outname, "w")
437 outf.write("NULL")
438 outf.close()
439
440def flatten_binds(binds, delegates, subsumes):
441 "Remove bindings which are replaced by delegation or subsumption"
442
443 result = []
444 stable = True
445
446 for bind in binds:
447 keep = True
448
449 for delegate in delegates:
450 if (bind['to'] == delegate['to']):
451 keep = False
452 result.append({'from': bind['from'], 'to': delegate['rep']})
453
454 for subsume in subsumes:
455 if (bind['from'] == subsume['from']):
456 keep = False
457 result.append({'from': subsume['rep'], 'to': bind['to']})
458
459 if (keep):
460 result.append(bind)
461 else:
462 stable = False
463
464 if (stable):
465 return result
466 else:
467 return flatten_binds(result, delegates, subsumes)
468
469def direct_binds(binds):
470 "Convert bindings matrix to set of sources by destination"
471
472 result = {}
473
474 for bind in binds:
475 if (not bind['to'] in result):
476 result[bind['to']] = set()
477
478 result[bind['to']].add(bind['from'])
479
480 return result
481
482def merge_subarch(prefix, arch, outdir):
483 "Merge subarchitecture into architexture"
484
485 insts = []
486 binds = []
487 delegates = []
488 subsumes = []
489
490 if ('inst' in arch):
491 for inst in arch['inst']:
492 subarch = get_arch(inst['type'])
493 if (not subarch is None):
494 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
495 insts.extend(subinsts)
496 binds.extend(subbinds)
497 delegates.extend(subdelegates)
498 subsumes.extend(subsubsumes)
499 else:
500 subframe = get_frame(inst['type'])
501 if (not subframe is None):
502 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
503 else:
504 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
505
506 if ('bind' in arch):
507 for bind in arch['bind']:
508 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
509
510 if ('delegate' in arch):
511 for delegate in arch['delegate']:
512 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
513
514 if ('subsume' in arch):
515 for subsume in arch['subsume']:
516 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
517
518 return (insts, binds, delegates, subsumes)
519
520def dump_archbp(outdir):
521 "Dump system architecture Behavior Protocol"
522
523 arch = get_system_arch()
524
525 if (arch is None):
526 print "Unable to find system architecture"
527 return
528
529 insts = []
530 binds = []
531 delegates = []
532 subsumes = []
533
534 if ('inst' in arch):
535 for inst in arch['inst']:
536 subarch = get_arch(inst['type'])
537 if (not subarch is None):
538 (subinsts, subbinds, subdelegates, subsubsumes) = merge_subarch(subarch['name'], subarch, outdir)
539 insts.extend(subinsts)
540 binds.extend(subbinds)
541 delegates.extend(subdelegates)
542 subsumes.extend(subsubsumes)
543 else:
544 subframe = get_frame(inst['type'])
545 if (not subframe is None):
546 insts.append({'var': inst['var'], 'frame': subframe})
547 else:
548 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
549
550 if ('bind' in arch):
551 for bind in arch['bind']:
552 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
553
554 if ('delegate' in arch):
555 for delegate in arch['delegate']:
556 print "Unable to delegate interface in system architecture"
557 break
558
559 if ('subsume' in arch):
560 for subsume in arch['subsume']:
561 print "Unable to subsume interface in system architecture"
562 break
563
564 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
565 outf = file(outname, "w")
566
567 create_null_bp("null.bp", outdir, outf)
568
569 for inst in insts:
570 dump_frame(inst['frame'], outdir, inst['var'], outf)
571
572 directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
573
574 for dst, src in directed_binds.items():
575 outf.write("bind %s to %s\n" % (", ".join(src), dst))
576
577 outf.close()
578
579def preproc_adl(raw, inarg):
580 "Preprocess %% statements in ADL"
581
582 return raw.replace("%%", inarg)
583
584def parse_adl(base, root, inname, nested, indent):
585 "Parse Architecture Description Language"
586
587 global output
588 global context
589 global architecture
590 global interface
591 global frame
592 global protocol
593
594 global iface_properties
595 global frame_properties
596 global arch_properties
597
598 global arg0
599
600 if (nested):
601 parts = inname.split("%")
602
603 if (len(parts) > 1):
604 inarg = parts[1]
605 else:
606 inarg = "%%"
607
608 if (parts[0][0:1] == "/"):
609 path = os.path.join(base, ".%s" % parts[0])
610 nested_root = os.path.dirname(path)
611 else:
612 path = os.path.join(root, parts[0])
613 nested_root = root
614
615 if (not os.path.isfile(path)):
616 print "%s: Unable to include file %s" % (inname, path)
617 return ""
618 else:
619 inarg = "%%"
620 path = inname
621 nested_root = root
622
623 inf = file(path, "r")
624
625 raw = preproc_adl(inf.read(), inarg)
626 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
627
628 for token in tokens:
629
630 # Includes
631
632 if (INC in context):
633 context.remove(INC)
634 parse_adl(base, nested_root, token, True, indent)
635 context.add(POST_INC)
636 continue
637
638 if (POST_INC in context):
639 if (token != "]"):
640 print "%s: Expected ]" % inname
641
642 context.remove(POST_INC)
643 continue
644
645 # Comments and newlines
646
647 if (BLOCK_COMMENT in context):
648 if (token == "*/"):
649 context.remove(BLOCK_COMMENT)
650
651 continue
652
653 if (LINE_COMMENT in context):
654 if (token == "\n"):
655 context.remove(LINE_COMMENT)
656
657 continue
658
659 # Any context
660
661 if (token == "/*"):
662 context.add(BLOCK_COMMENT)
663 continue
664
665 if (token == "#"):
666 context.add(LINE_COMMENT)
667 continue
668
669 if (token == "["):
670 context.add(INC)
671 continue
672
673 if (token == "\n"):
674 continue
675
676 # "frame"
677
678 if (FRAME in context):
679 if (NULL in context):
680 if (token != ";"):
681 print "%s: Expected ';' in frame '%s'" % (inname, frame)
682 else:
683 output += "%s\n" % token
684
685 context.remove(NULL)
686 context.remove(FRAME)
687 frame = None
688 continue
689
690 if (BODY in context):
691 if (PROTOCOL in context):
692 if (token == "{"):
693 indent += 1
694 elif (token == "}"):
695 indent -= 1
696
697 if (indent == -1):
698 bp = split_bp(protocol)
699 protocol = None
700
701 if (not frame in frame_properties):
702 frame_properties[frame] = {}
703
704 if ('protocol' in frame_properties[frame]):
705 print "%s: Protocol for frame '%s' already defined" % (inname, frame)
706 else:
707 frame_properties[frame]['protocol'] = bp
708
709 output += "\n%s" % tabs(2)
710 output += parse_bp(inname, bp, 2)
711 output += "\n%s" % token
712 indent = 0
713
714 context.remove(PROTOCOL)
715 context.remove(BODY)
716 context.add(NULL)
717 else:
718 protocol += token
719
720 continue
721
722 if (REQUIRES in context):
723 if (FIN in context):
724 if (token != ";"):
725 print "%s: Expected ';' in frame '%s'" % (inname, frame)
726 else:
727 output += "%s" % token
728
729 context.remove(FIN)
730 continue
731
732 if (VAR in context):
733 if (not identifier(token)):
734 print "%s: Variable name expected in frame '%s'" % (inname, frame)
735 else:
736 if (not frame in frame_properties):
737 frame_properties[frame] = {}
738
739 if (not 'requires' in frame_properties[frame]):
740 frame_properties[frame]['requires'] = []
741
742 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
743 arg0 = None
744
745 output += "%s" % token
746
747 context.remove(VAR)
748 context.add(FIN)
749 continue
750
751 if ((token == "}") or (token[-1] == ":")):
752 context.remove(REQUIRES)
753 else:
754 if (not identifier(token)):
755 print "%s: Interface name expected in frame '%s'" % (inname, frame)
756 else:
757 arg0 = token
758 output += "\n%s%s " % (tabs(indent), token)
759
760 context.add(VAR)
761 continue
762
763 if (PROVIDES in context):
764 if (FIN in context):
765 if (token != ";"):
766 print "%s: Expected ';' in frame '%s'" % (inname, frame)
767 else:
768 output += "%s" % token
769
770 context.remove(FIN)
771 continue
772
773 if (VAR in context):
774 if (not identifier(token)):
775 print "%s: Variable name expected in frame '%s'" % (inname, frame)
776 else:
777 if (not frame in frame_properties):
778 frame_properties[frame] = {}
779
780 if (not 'provides' in frame_properties[frame]):
781 frame_properties[frame]['provides'] = []
782
783 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
784 arg0 = None
785
786 output += "%s" % token
787
788 context.remove(VAR)
789 context.add(FIN)
790 continue
791
792 if ((token == "}") or (token[-1] == ":")):
793 context.remove(PROVIDES)
794 else:
795 if (not identifier(token)):
796 print "%s: Interface name expected in frame '%s'" % (inname, frame)
797 else:
798 arg0 = token
799 output += "\n%s%s " % (tabs(indent), token)
800
801 context.add(VAR)
802 continue
803
804 if (token == "}"):
805 if (indent != 2):
806 print "%s: Wrong number of parentheses in frame '%s'" % (inname, frame)
807 else:
808 indent = 0
809 output += "\n%s" % token
810
811 context.remove(BODY)
812 context.add(NULL)
813 continue
814
815 if (token == "provides:"):
816 output += "\n%s%s" % (tabs(indent - 1), token)
817 context.add(PROVIDES)
818 protocol = ""
819 continue
820
821 if (token == "requires:"):
822 output += "\n%s%s" % (tabs(indent - 1), token)
823 context.add(REQUIRES)
824 protocol = ""
825 continue
826
827 if (token == "protocol:"):
828 output += "\n%s%s" % (tabs(indent - 1), token)
829 indent = 0
830 context.add(PROTOCOL)
831 protocol = ""
832 continue
833
834 print "%s: Unknown token '%s' in frame '%s'" % (inname, token, frame)
835 continue
836
837 if (HEAD in context):
838 if (token == "{"):
839 output += "%s" % token
840 indent += 2
841 context.remove(HEAD)
842 context.add(BODY)
843 continue
844
845 if (token == ";"):
846 output += "%s\n" % token
847 context.remove(HEAD)
848 context.remove(FRAME)
849 continue
850
851 print "%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame)
852
853 continue
854
855 if (not identifier(token)):
856 print "%s: Expected frame name" % inname
857 else:
858 frame = token
859 output += "%s " % token
860
861 if (not frame in frame_properties):
862 frame_properties[frame] = {}
863
864 frame_properties[frame]['name'] = frame
865
866 context.add(HEAD)
867 continue
868
869 # "interface"
870
871 if (IFACE in context):
872 if (NULL in context):
873 if (token != ";"):
874 print "%s: Expected ';' in interface '%s'" % (inname, interface)
875 else:
876 output += "%s\n" % token
877
878 context.remove(NULL)
879 context.remove(IFACE)
880 interface = None
881 continue
882
883 if (BODY in context):
884 if (PROTOCOL in context):
885 if (token == "{"):
886 indent += 1
887 elif (token == "}"):
888 indent -= 1
889
890 if (indent == -1):
891 bp = split_bp(protocol)
892 protocol = None
893
894 if (not interface in iface_properties):
895 iface_properties[interface] = {}
896
897 if ('protocol' in iface_properties[interface]):
898 print "%s: Protocol for interface '%s' already defined" % (inname, interface)
899 else:
900 iface_properties[interface]['protocol'] = bp
901
902 output += "\n%s" % tabs(2)
903 output += parse_bp(inname, bp, 2)
904 output += "\n%s" % token
905 indent = 0
906
907 context.remove(PROTOCOL)
908 context.remove(BODY)
909 context.add(NULL)
910 else:
911 protocol += token
912
913 continue
914
915 if (PROTOTYPE in context):
916 if (FIN in context):
917 if (token != ";"):
918 print "%s: Expected ';' in interface '%s'" % (inname, interface)
919 else:
920 output += "%s" % token
921
922 context.remove(FIN)
923 context.remove(PROTOTYPE)
924 continue
925
926 if (PAR_RIGHT in context):
927 if (token == ")"):
928 output += "%s" % token
929 context.remove(PAR_RIGHT)
930 context.add(FIN)
931 else:
932 output += " %s" % token
933
934 continue
935
936 if (SIGNATURE in context):
937 output += "%s" % token
938 if (token == ")"):
939 context.remove(SIGNATURE)
940 context.add(FIN)
941
942 context.remove(SIGNATURE)
943 context.add(PAR_RIGHT)
944 continue
945
946 if (PAR_LEFT in context):
947 if (token != "("):
948 print "%s: Expected '(' in interface '%s'" % (inname, interface)
949 else:
950 output += "%s" % token
951
952 context.remove(PAR_LEFT)
953 context.add(SIGNATURE)
954 continue
955
956 if (not identifier(token)):
957 print "%s: Method identifier expected in interface '%s'" % (inname, interface)
958 else:
959 output += "%s" % token
960
961 context.add(PAR_LEFT)
962 continue
963
964 if (token == "}"):
965 if (indent != 2):
966 print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
967 else:
968 indent = 0
969 output += "\n%s" % token
970
971 context.remove(BODY)
972 context.add(NULL)
973 continue
974
975 if ((token == "ipcarg_t") or (token == "unative_t")):
976 output += "\n%s%s " % (tabs(indent), token)
977 context.add(PROTOTYPE)
978 continue
979
980 if (token == "protocol:"):
981 output += "\n%s%s" % (tabs(indent - 1), token)
982 indent = 0
983 context.add(PROTOCOL)
984 protocol = ""
985 continue
986
987 print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
988 continue
989
990 if (HEAD in context):
991 if (PRE_BODY in context):
992 if (token == "{"):
993 output += "%s" % token
994 indent += 2
995 context.remove(PRE_BODY)
996 context.remove(HEAD)
997 context.add(BODY)
998 continue
999
1000 if (token == ";"):
1001 output += "%s\n" % token
1002 context.remove(PRE_BODY)
1003 context.remove(HEAD)
1004 context.remove(IFACE)
1005 continue
1006
1007 print "%s: Expected '{' or ';' in interface head '%s'" % (inname, interface)
1008 continue
1009
1010 if (EXTENDS in context):
1011 if (not identifier(token)):
1012 print "%s: Expected inherited interface name in interface head '%s'" % (inname, interface)
1013 else:
1014 output += " %s" % token
1015 if (not interface in iface_properties):
1016 iface_properties[interface] = {}
1017
1018 iface_properties[interface]['extends'] = token
1019
1020 context.remove(EXTENDS)
1021 context.add(PRE_BODY)
1022 continue
1023
1024 if (token == "extends"):
1025 output += " %s" % token
1026 context.add(EXTENDS)
1027 continue
1028
1029 if (token == "{"):
1030 output += "%s" % token
1031 indent += 2
1032 context.remove(HEAD)
1033 context.add(BODY)
1034 continue
1035
1036 if (token == ";"):
1037 output += "%s\n" % token
1038 context.remove(HEAD)
1039 context.remove(IFACE)
1040 continue
1041
1042 print "%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface)
1043 continue
1044
1045 if (not identifier(token)):
1046 print "%s: Expected interface name" % inname
1047 else:
1048 interface = token
1049 output += "%s " % token
1050
1051 if (not interface in iface_properties):
1052 iface_properties[interface] = {}
1053
1054 iface_properties[interface]['name'] = interface
1055
1056 context.add(HEAD)
1057 continue
1058
1059 # "architecture"
1060
1061 if (ARCH in context):
1062 if (NULL in context):
1063 if (token != ";"):
1064 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1065 else:
1066 output += "%s\n" % token
1067
1068 context.remove(NULL)
1069 context.remove(ARCH)
1070 context.discard(SYSTEM)
1071 architecture = None
1072 continue
1073
1074 if (BODY in context):
1075 if (DELEGATE in context):
1076 if (FIN in context):
1077 if (token != ";"):
1078 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1079 else:
1080 output += "%s" % token
1081
1082 context.remove(FIN)
1083 context.remove(DELEGATE)
1084 continue
1085
1086 if (VAR in context):
1087 if (not descriptor(token)):
1088 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1089 else:
1090 if (not architecture in arch_properties):
1091 arch_properties[architecture] = {}
1092
1093 if (not 'delegate' in arch_properties[architecture]):
1094 arch_properties[architecture]['delegate'] = []
1095
1096 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1097 arg0 = None
1098
1099 output += "%s" % token
1100
1101 context.add(FIN)
1102 context.remove(VAR)
1103 continue
1104
1105 if (TO in context):
1106 if (token != "to"):
1107 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1108 else:
1109 output += "%s " % token
1110
1111 context.add(VAR)
1112 context.remove(TO)
1113 continue
1114
1115 if (not identifier(token)):
1116 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1117 else:
1118 output += "%s " % token
1119 arg0 = token
1120
1121 context.add(TO)
1122 continue
1123
1124 if (SUBSUME in context):
1125 if (FIN in context):
1126 if (token != ";"):
1127 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1128 else:
1129 output += "%s" % token
1130
1131 context.remove(FIN)
1132 context.remove(SUBSUME)
1133 continue
1134
1135 if (VAR in context):
1136 if (not identifier(token)):
1137 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1138 else:
1139 if (not architecture in arch_properties):
1140 arch_properties[architecture] = {}
1141
1142 if (not 'subsume' in arch_properties[architecture]):
1143 arch_properties[architecture]['subsume'] = []
1144
1145 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1146 arg0 = None
1147
1148 output += "%s" % token
1149
1150 context.add(FIN)
1151 context.remove(VAR)
1152 continue
1153
1154 if (TO in context):
1155 if (token != "to"):
1156 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1157 else:
1158 output += "%s " % token
1159
1160 context.add(VAR)
1161 context.remove(TO)
1162 continue
1163
1164 if (not descriptor(token)):
1165 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1166 else:
1167 output += "%s " % token
1168 arg0 = token
1169
1170 context.add(TO)
1171 continue
1172
1173 if (BIND in context):
1174 if (FIN in context):
1175 if (token != ";"):
1176 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1177 else:
1178 output += "%s" % token
1179
1180 context.remove(FIN)
1181 context.remove(BIND)
1182 continue
1183
1184 if (VAR in context):
1185 if (not descriptor(token)):
1186 print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
1187 else:
1188 if (not architecture in arch_properties):
1189 arch_properties[architecture] = {}
1190
1191 if (not 'bind' in arch_properties[architecture]):
1192 arch_properties[architecture]['bind'] = []
1193
1194 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1195 arg0 = None
1196
1197 output += "%s" % token
1198
1199 context.add(FIN)
1200 context.remove(VAR)
1201 continue
1202
1203 if (TO in context):
1204 if (token != "to"):
1205 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1206 else:
1207 output += "%s " % token
1208
1209 context.add(VAR)
1210 context.remove(TO)
1211 continue
1212
1213 if (not descriptor(token)):
1214 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1215 else:
1216 output += "%s " % token
1217 arg0 = token
1218
1219 context.add(TO)
1220 continue
1221
1222 if (INST in context):
1223 if (FIN in context):
1224 if (token != ";"):
1225 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1226 else:
1227 output += "%s" % token
1228
1229 context.remove(FIN)
1230 context.remove(INST)
1231 continue
1232
1233 if (VAR in context):
1234 if (not identifier(token)):
1235 print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
1236 else:
1237 if (not architecture in arch_properties):
1238 arch_properties[architecture] = {}
1239
1240 if (not 'inst' in arch_properties[architecture]):
1241 arch_properties[architecture]['inst'] = []
1242
1243 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1244 arg0 = None
1245
1246 output += "%s" % token
1247
1248 context.add(FIN)
1249 context.remove(VAR)
1250 continue
1251
1252 if (not identifier(token)):
1253 print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
1254 else:
1255 output += "%s " % token
1256 arg0 = token
1257
1258 context.add(VAR)
1259 continue
1260
1261 if (token == "}"):
1262 if (indent != 1):
1263 print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
1264 else:
1265 indent -= 1
1266 output += "\n%s" % token
1267
1268 context.remove(BODY)
1269 context.add(NULL)
1270 continue
1271
1272 if (token == "inst"):
1273 output += "\n%s%s " % (tabs(indent), token)
1274 context.add(INST)
1275 continue
1276
1277 if (token == "bind"):
1278 output += "\n%s%s " % (tabs(indent), token)
1279 context.add(BIND)
1280 continue
1281
1282 if (token == "subsume"):
1283 output += "\n%s%s " % (tabs(indent), token)
1284 context.add(SUBSUME)
1285 continue
1286
1287 if (token == "delegate"):
1288 output += "\n%s%s " % (tabs(indent), token)
1289 context.add(DELEGATE)
1290 continue
1291
1292 print "%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture)
1293 continue
1294
1295 if (HEAD in context):
1296 if (token == "{"):
1297 output += "%s" % token
1298 indent += 1
1299 context.remove(HEAD)
1300 context.add(BODY)
1301 continue
1302
1303 if (token == ";"):
1304 output += "%s\n" % token
1305 context.remove(HEAD)
1306 context.remove(ARCH)
1307 context.discard(SYSTEM)
1308 continue
1309
1310 if (not word(token)):
1311 print "%s: Expected word in architecture head '%s'" % (inname, architecture)
1312 else:
1313 output += "%s " % token
1314
1315 continue
1316
1317 if (not identifier(token)):
1318 print "%s: Expected architecture name" % inname
1319 else:
1320 architecture = token
1321 output += "%s " % token
1322
1323 if (not architecture in arch_properties):
1324 arch_properties[architecture] = {}
1325
1326 arch_properties[architecture]['name'] = architecture
1327
1328 if (SYSTEM in context):
1329 arch_properties[architecture]['system'] = True
1330
1331 context.add(HEAD)
1332 continue
1333
1334 # "system architecture"
1335
1336 if (SYSTEM in context):
1337 if (token != "architecture"):
1338 print "%s: Expected 'architecture'" % inname
1339 else:
1340 output += "%s " % token
1341
1342 context.add(ARCH)
1343 continue
1344
1345 if (token == "frame"):
1346 output += "\n%s " % token
1347 context.add(FRAME)
1348 continue
1349
1350 if (token == "interface"):
1351 output += "\n%s " % token
1352 context.add(IFACE)
1353 continue
1354
1355 if (token == "system"):
1356 output += "\n%s " % token
1357 context.add(SYSTEM)
1358 continue
1359
1360 if (token == "architecture"):
1361 output += "\n%s " % token
1362 context.add(ARCH)
1363 continue
1364
1365 print "%s: Unknown token '%s'" % (inname, token)
1366
1367 inf.close()
1368
1369def open_adl(base, root, inname, outdir, outname):
1370 "Open Architecture Description file"
1371
1372 global output
1373 global context
1374 global architecture
1375 global interface
1376 global frame
1377 global protocol
1378
1379 global arg0
1380
1381 output = ""
1382 context = set()
1383 architecture = None
1384 interface = None
1385 frame = None
1386 protocol = None
1387 arg0 = None
1388
1389 parse_adl(base, root, inname, False, 0)
1390 output = output.strip()
1391
1392 if (output != ""):
1393 outf = file(outname, "w")
1394 outf.write(output)
1395 outf.close()
1396
1397def recursion(base, root, output, level):
1398 "Recursive directory walk"
1399
1400 for name in os.listdir(root):
1401 canon = os.path.join(root, name)
1402
1403 if (os.path.isfile(canon)):
1404 fcomp = split_tokens(canon, ["."])
1405 cname = canon.split("/")
1406
1407 if (fcomp[-1] == ".adl"):
1408 output_path = os.path.join(output, cname[-1])
1409 open_adl(base, root, canon, output, output_path)
1410
1411 if (os.path.isdir(canon)):
1412 recursion(base, canon, output, level + 1)
1413
1414def main():
1415 global iface_properties
1416 global frame_properties
1417 global arch_properties
1418
1419 if (len(sys.argv) < 2):
1420 usage(sys.argv[0])
1421 return
1422
1423 path = os.path.abspath(sys.argv[1])
1424 if (not os.path.isdir(path)):
1425 print "Error: <OUTPUT> is not a directory"
1426 return
1427
1428 iface_properties = {}
1429 frame_properties = {}
1430 arch_properties = {}
1431
1432 recursion(".", ".", path, 0)
1433 dump_archbp(path)
1434
1435if __name__ == '__main__':
1436 main()
Note: See TracBrowser for help on using the repository browser.