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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3037384 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
RevLine 
[e742429]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"""
[07fdf203]30HelenOS Architecture Description Language and Behavior Protocols preprocessor
[e742429]31"""
32
33import sys
34import os
35
[2a70672]36INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
[3037384]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)
[2a70672]40
[e742429]41def usage(prname):
42 "Print usage syntax"
[ee5b35a]43
44 print "%s <OUTPUT>" % prname
[e742429]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")
[1993f9a]56
57 if (token != ""):
[e742429]58 tokens.append(token)
59
60 return tokens
61
[1993f9a]62def split_tokens(string, delimiters, trim = False, separate = False):
[e742429]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
[1993f9a]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
[e742429]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
[2a70672]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
[51d4040]128def tentative_bp(name, tokens):
[ee5b35a]129 "Preprocess tentative statements in Behavior Protocol"
[1993f9a]130
[ee5b35a]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("(")
[51d4040]151 result.extend(tentative_bp(name, tokens[start:(i - 1)]))
[ee5b35a]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:
[51d4040]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
[1993f9a]233 else:
[ee5b35a]234 result.append(tokens[i])
[1993f9a]235
[ee5b35a]236 i += 1
[e742429]237
[ee5b35a]238 return result
239
[fed03a3]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):
[51d4040]246 "Convert interface Behavior Protocol to generic protocol"
[fed03a3]247
[51d4040]248 result = ["("]
[fed03a3]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
[51d4040]268 result.append(")")
269 result.append("*")
270
[fed03a3]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):
[ee5b35a]298 "Parse Behavior Protocol"
299
[51d4040]300 tokens = tentative_bp(name, tokens)
301 tokens = alternative_bp(name, tokens)
[e742429]302
[ee5b35a]303 indent = base_indent
[2a70672]304 output = ""
[e742429]305
306 for token in tokens:
307 if (token == "\n"):
308 continue
309
310 if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
[2a70672]311 output += " %s" % token
[e742429]312 elif (token == "("):
[2a70672]313 output += "\n%s%s" % (tabs(indent), token)
[e742429]314 indent += 1
315 elif (token == ")"):
[ee5b35a]316 if (indent < base_indent):
317 print "%s: Too many parentheses" % name
[1993f9a]318
[e742429]319 indent -= 1
[2a70672]320 output += "\n%s%s" % (tabs(indent), token)
[e742429]321 elif (token == "{"):
[2a70672]322 output += " %s" % token
[e742429]323 indent += 1
324 elif (token == "}"):
[ee5b35a]325 if (indent < base_indent):
326 print "%s: Too many parentheses" % name
[1993f9a]327
[e742429]328 indent -= 1
[2a70672]329 output += "\n%s%s" % (tabs(indent), token)
[e742429]330 elif (token == "*"):
[2a70672]331 output += "%s" % token
[1993f9a]332 elif ((token == "!") or (token == "?") or (token == "NULL")):
[2a70672]333 output += "\n%s%s" % (tabs(indent), token)
[e742429]334 else:
[2a70672]335 output += "%s" % token
[1993f9a]336
[ee5b35a]337 if (indent > base_indent):
338 print "%s: Missing parentheses" % name
339
340 output = output.strip()
341 if (output == ""):
342 return "NULL"
[e742429]343
[2a70672]344 return output
[1993f9a]345
[fed03a3]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
[3037384]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
[57688fe2]372def dump_frame(frame, outdir, var, archf):
[fed03a3]373 "Dump Behavior Protocol of a given frame"
[ee5b35a]374
[57688fe2]375 fname = "%s.bp" % frame['name']
376
377 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
378 outname = os.path.join(outdir, fname)
[ee5b35a]379
[fed03a3]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']))
[3037384]390 for protocol in inherited_protocols(iface):
391 protocols.append(extend_bp(outname, protocol, iface['name']))
[fed03a3]392 else:
393 print "%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface'])
394
[ee5b35a]395 outf = file(outname, "w")
[fed03a3]396 outf.write(parse_bp(outname, merge_bp(protocols), 0))
[ee5b35a]397 outf.close()
398
[fed03a3]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
[ee5b35a]414
[fed03a3]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
[57688fe2]430def create_null_bp(fname, outdir, archf):
[fed03a3]431 "Create null frame protocol"
432
[57688fe2]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()
[fed03a3]439
[f1fb1d1]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
[41eca31]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
[57688fe2]482def merge_subarch(prefix, arch, outdir):
483 "Merge subarchitecture into architexture"
[fed03a3]484
[57688fe2]485 insts = []
486 binds = []
487 delegates = []
488 subsumes = []
[ee5b35a]489
[57688fe2]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'])
[fed03a3]505
[57688fe2]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 = []
[fed03a3]533
534 if ('inst' in arch):
535 for inst in arch['inst']:
536 subarch = get_arch(inst['type'])
537 if (not subarch is None):
[57688fe2]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)
[fed03a3]543 else:
544 subframe = get_frame(inst['type'])
545 if (not subframe is None):
[57688fe2]546 insts.append({'var': inst['var'], 'frame': subframe})
[fed03a3]547 else:
[57688fe2]548 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
[8c73012]549
550 if ('bind' in arch):
551 for bind in arch['bind']:
[57688fe2]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
[41eca31]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))
[fed03a3]576
[ee5b35a]577 outf.close()
578
579def preproc_adl(raw, inarg):
580 "Preprocess %% statements in ADL"
581
582 return raw.replace("%%", inarg)
583
[2a70672]584def parse_adl(base, root, inname, nested, indent):
[1993f9a]585 "Parse Architecture Description Language"
586
[ee5b35a]587 global output
588 global context
589 global architecture
590 global interface
591 global frame
592 global protocol
[fed03a3]593
594 global iface_properties
595 global frame_properties
596 global arch_properties
597
598 global arg0
[ee5b35a]599
[1993f9a]600 if (nested):
[2a70672]601 parts = inname.split("%")
[1993f9a]602
[2a70672]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])
[1993f9a]610 nested_root = os.path.dirname(path)
611 else:
[2a70672]612 path = os.path.join(root, parts[0])
[1993f9a]613 nested_root = root
614
615 if (not os.path.isfile(path)):
[2a70672]616 print "%s: Unable to include file %s" % (inname, path)
617 return ""
[1993f9a]618 else:
619 inarg = "%%"
[2a70672]620 path = inname
[1993f9a]621 nested_root = root
622
[2a70672]623 inf = file(path, "r")
[1993f9a]624
[2a70672]625 raw = preproc_adl(inf.read(), inarg)
626 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
[1993f9a]627
628 for token in tokens:
629
[2a70672]630 # Includes
631
632 if (INC in context):
633 context.remove(INC)
[ee5b35a]634 parse_adl(base, nested_root, token, True, indent)
[2a70672]635 context.add(POST_INC)
[1993f9a]636 continue
637
[2a70672]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
[ee5b35a]673 if (token == "\n"):
674 continue
[2a70672]675
[ee5b35a]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
[2a70672]688 continue
[ee5b35a]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):
[fed03a3]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]):
[ee5b35a]705 print "%s: Protocol for frame '%s' already defined" % (inname, frame)
706 else:
[fed03a3]707 frame_properties[frame]['protocol'] = bp
[ee5b35a]708
[fed03a3]709 output += "\n%s" % tabs(2)
710 output += parse_bp(inname, bp, 2)
[ee5b35a]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)):
[fed03a3]734 print "%s: Variable name expected in frame '%s'" % (inname, frame)
[ee5b35a]735 else:
[fed03a3]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
[ee5b35a]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:
[fed03a3]757 arg0 = token
[ee5b35a]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)):
[fed03a3]775 print "%s: Variable name expected in frame '%s'" % (inname, frame)
[ee5b35a]776 else:
[fed03a3]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
[ee5b35a]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:
[fed03a3]798 arg0 = token
[ee5b35a]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)
[2a70672]835 continue
[ee5b35a]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
[fed03a3]860
861 if (not frame in frame_properties):
862 frame_properties[frame] = {}
863
864 frame_properties[frame]['name'] = frame
[ee5b35a]865
866 context.add(HEAD)
867 continue
[2a70672]868
869 # "interface"
870
871 if (IFACE in context):
872 if (NULL in context):
873 if (token != ";"):
[ee5b35a]874 print "%s: Expected ';' in interface '%s'" % (inname, interface)
[2a70672]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
[ee5b35a]890 if (indent == -1):
[fed03a3]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]):
[ee5b35a]898 print "%s: Protocol for interface '%s' already defined" % (inname, interface)
899 else:
[fed03a3]900 iface_properties[interface]['protocol'] = bp
[ee5b35a]901
902 output += "\n%s" % tabs(2)
[fed03a3]903 output += parse_bp(inname, bp, 2)
[2a70672]904 output += "\n%s" % token
[ee5b35a]905 indent = 0
[2a70672]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 != ";"):
[ee5b35a]918 print "%s: Expected ';' in interface '%s'" % (inname, interface)
[2a70672]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 != "("):
[ee5b35a]948 print "%s: Expected '(' in interface '%s'" % (inname, interface)
[2a70672]949 else:
950 output += "%s" % token
951
952 context.remove(PAR_LEFT)
953 context.add(SIGNATURE)
954 continue
955
956 if (not identifier(token)):
[ee5b35a]957 print "%s: Method identifier expected in interface '%s'" % (inname, interface)
[2a70672]958 else:
959 output += "%s" % token
960
961 context.add(PAR_LEFT)
962 continue
963
964 if (token == "}"):
[ee5b35a]965 if (indent != 2):
966 print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
[2a70672]967 else:
968 indent = 0
969 output += "\n%s" % token
970
971 context.remove(BODY)
972 context.add(NULL)
973 continue
974
[ee5b35a]975 if ((token == "ipcarg_t") or (token == "unative_t")):
[2a70672]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)
[ee5b35a]982 indent = 0
[2a70672]983 context.add(PROTOCOL)
984 protocol = ""
985 continue
986
[ee5b35a]987 print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
[2a70672]988 continue
989
990 if (HEAD in context):
[3037384]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
[2a70672]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)
[57688fe2]1039 context.remove(IFACE)
[2a70672]1040 continue
1041
[3037384]1042 print "%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface)
[2a70672]1043 continue
1044
1045 if (not identifier(token)):
1046 print "%s: Expected interface name" % inname
1047 else:
1048 interface = token
1049 output += "%s " % token
[fed03a3]1050
1051 if (not interface in iface_properties):
1052 iface_properties[interface] = {}
1053
1054 iface_properties[interface]['name'] = interface
[2a70672]1055
1056 context.add(HEAD)
1057 continue
1058
1059 # "architecture"
1060
1061 if (ARCH in context):
1062 if (NULL in context):
1063 if (token != ";"):
[ee5b35a]1064 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
[2a70672]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):
[ee5b35a]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:
[fed03a3]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
[ee5b35a]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
[fed03a3]1119 arg0 = token
[ee5b35a]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:
[fed03a3]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
[ee5b35a]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
[fed03a3]1168 arg0 = token
[ee5b35a]1169
1170 context.add(TO)
1171 continue
1172
[2a70672]1173 if (BIND in context):
1174 if (FIN in context):
1175 if (token != ";"):
[ee5b35a]1176 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
[2a70672]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)):
[ee5b35a]1186 print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
[2a70672]1187 else:
[fed03a3]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
[2a70672]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"):
[ee5b35a]1205 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
[2a70672]1206 else:
1207 output += "%s " % token
1208
1209 context.add(VAR)
1210 context.remove(TO)
1211 continue
1212
1213 if (not descriptor(token)):
[ee5b35a]1214 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
[2a70672]1215 else:
1216 output += "%s " % token
[fed03a3]1217 arg0 = token
[2a70672]1218
1219 context.add(TO)
1220 continue
1221
1222 if (INST in context):
1223 if (FIN in context):
1224 if (token != ";"):
[ee5b35a]1225 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
[2a70672]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)):
[ee5b35a]1235 print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
[2a70672]1236 else:
[fed03a3]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
[2a70672]1246 output += "%s" % token
1247
1248 context.add(FIN)
1249 context.remove(VAR)
1250 continue
1251
1252 if (not identifier(token)):
[ee5b35a]1253 print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
[2a70672]1254 else:
1255 output += "%s " % token
[fed03a3]1256 arg0 = token
[2a70672]1257
1258 context.add(VAR)
1259 continue
1260
1261 if (token == "}"):
1262 if (indent != 1):
[ee5b35a]1263 print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
[2a70672]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
[ee5b35a]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)
[2a70672]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)):
[ee5b35a]1311 print "%s: Expected word in architecture head '%s'" % (inname, architecture)
[2a70672]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
[fed03a3]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
[2a70672]1330
1331 context.add(HEAD)
1332 continue
1333
1334 # "system architecture"
1335
1336 if (SYSTEM in context):
1337 if (token != "architecture"):
[ee5b35a]1338 print "%s: Expected 'architecture'" % inname
[2a70672]1339 else:
1340 output += "%s " % token
1341
1342 context.add(ARCH)
1343 continue
1344
[ee5b35a]1345 if (token == "frame"):
1346 output += "\n%s " % token
1347 context.add(FRAME)
1348 continue
1349
[2a70672]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
[ee5b35a]1365 print "%s: Unknown token '%s'" % (inname, token)
[1993f9a]1366
1367 inf.close()
[e742429]1368
[ee5b35a]1369def open_adl(base, root, inname, outdir, outname):
[1993f9a]1370 "Open Architecture Description file"
1371
[ee5b35a]1372 global output
1373 global context
1374 global architecture
1375 global interface
1376 global frame
1377 global protocol
1378
[fed03a3]1379 global arg0
1380
[ee5b35a]1381 output = ""
1382 context = set()
[2a70672]1383 architecture = None
[ee5b35a]1384 interface = None
1385 frame = None
[2a70672]1386 protocol = None
[fed03a3]1387 arg0 = None
[1993f9a]1388
[ee5b35a]1389 parse_adl(base, root, inname, False, 0)
1390 output = output.strip()
[1993f9a]1391
[ee5b35a]1392 if (output != ""):
1393 outf = file(outname, "w")
1394 outf.write(output)
1395 outf.close()
[1993f9a]1396
1397def recursion(base, root, output, level):
[e742429]1398 "Recursive directory walk"
1399
1400 for name in os.listdir(root):
1401 canon = os.path.join(root, name)
1402
[1993f9a]1403 if (os.path.isfile(canon)):
[e742429]1404 fcomp = split_tokens(canon, ["."])
[1993f9a]1405 cname = canon.split("/")
1406
[2a70672]1407 if (fcomp[-1] == ".adl"):
1408 output_path = os.path.join(output, cname[-1])
[ee5b35a]1409 open_adl(base, root, canon, output, output_path)
[e742429]1410
1411 if (os.path.isdir(canon)):
[1993f9a]1412 recursion(base, canon, output, level + 1)
[e742429]1413
1414def main():
[fed03a3]1415 global iface_properties
1416 global frame_properties
1417 global arch_properties
[ee5b35a]1418
[e742429]1419 if (len(sys.argv) < 2):
1420 usage(sys.argv[0])
1421 return
1422
1423 path = os.path.abspath(sys.argv[1])
[07fdf203]1424 if (not os.path.isdir(path)):
[1993f9a]1425 print "Error: <OUTPUT> is not a directory"
[e742429]1426 return
1427
[fed03a3]1428 iface_properties = {}
1429 frame_properties = {}
1430 arch_properties = {}
[ee5b35a]1431
[1993f9a]1432 recursion(".", ".", path, 0)
[57688fe2]1433 dump_archbp(path)
[1993f9a]1434
[e742429]1435if __name__ == '__main__':
1436 main()
Note: See TracBrowser for help on using the repository browser.