| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """ Parser for PPAPI IDL """ | 6 """ Parser for PPAPI IDL """ |
| 7 | 7 |
| 8 # | 8 # |
| 9 # IDL Parser | 9 # IDL Parser |
| 10 # | 10 # |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 """top : COMMENT COMMENT ext_attr_block top_list""" | 216 """top : COMMENT COMMENT ext_attr_block top_list""" |
| 217 | 217 |
| 218 Copyright = self.BuildComment('Copyright', p, 1) | 218 Copyright = self.BuildComment('Copyright', p, 1) |
| 219 Filedoc = self.BuildComment('Comment', p, 2) | 219 Filedoc = self.BuildComment('Comment', p, 2) |
| 220 | 220 |
| 221 p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) | 221 p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) |
| 222 if self.parse_debug: DumpReduction('top', p) | 222 if self.parse_debug: DumpReduction('top', p) |
| 223 | 223 |
| 224 # Build a list of top level items. | 224 # Build a list of top level items. |
| 225 def p_top_list(self, p): | 225 def p_top_list(self, p): |
| 226 """top_list : describe_block top_list | 226 """top_list : callback_decl top_list |
| 227 | describe_block top_list |
| 228 | dictionary_block top_list |
| 227 | enum_block top_list | 229 | enum_block top_list |
| 228 | inline top_list | 230 | inline top_list |
| 229 | interface_block top_list | 231 | interface_block top_list |
| 230 | label_block top_list | 232 | label_block top_list |
| 233 | namespace top_list |
| 231 | struct_block top_list | 234 | struct_block top_list |
| 232 | typedef_decl top_list | 235 | typedef_decl top_list |
| 233 | """ | 236 | """ |
| 234 if len(p) > 2: | 237 if len(p) > 2: |
| 235 p[0] = ListFromConcat(p[1], p[2]) | 238 p[0] = ListFromConcat(p[1], p[2]) |
| 236 if self.parse_debug: DumpReduction('top_list', p) | 239 if self.parse_debug: DumpReduction('top_list', p) |
| 237 | 240 |
| 238 # Recover from error and continue parsing at the next top match. | 241 # Recover from error and continue parsing at the next top match. |
| 239 def p_top_error(self, p): | 242 def p_top_error(self, p): |
| 240 """top_list : error top_list""" | 243 """top_list : error top_list""" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 260 | """ | 263 | """ |
| 261 if len(p) > 1: | 264 if len(p) > 1: |
| 262 child = self.BuildComment('Comment', p, 1) | 265 child = self.BuildComment('Comment', p, 1) |
| 263 p[0] = ListFromConcat(child, p[2]) | 266 p[0] = ListFromConcat(child, p[2]) |
| 264 if self.parse_debug: DumpReduction('comments', p) | 267 if self.parse_debug: DumpReduction('comments', p) |
| 265 else: | 268 else: |
| 266 if self.parse_debug: DumpReduction('no comments', p) | 269 if self.parse_debug: DumpReduction('no comments', p) |
| 267 | 270 |
| 268 | 271 |
| 269 # | 272 # |
| 273 # Namespace |
| 274 # |
| 275 # A namespace provides a named scope to an enclosed top_list. |
| 276 # |
| 277 def p_namespace(self, p): |
| 278 """namespace : modifiers NAMESPACE namespace_name '{' top_list '}' ';'""" |
| 279 children = ListFromConcat(p[1], p[5]) |
| 280 p[0] = self.BuildNamed('Namespace', p, 3, children) |
| 281 |
| 282 # We allow namespace names of the form foo.bar.baz. |
| 283 def p_namespace_name(self, p): |
| 284 """namespace_name : SYMBOL |
| 285 | SYMBOL '.' namespace_name""" |
| 286 p[0] = "".join(p[1:]) |
| 287 |
| 288 |
| 289 # |
| 290 # Dictionary |
| 291 # |
| 292 # A dictionary contains is a named list of optional and required members. |
| 293 # |
| 294 def p_dictionary_block(self, p): |
| 295 """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" |
| 296 p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[5])) |
| 297 |
| 298 # |
| 299 # Callback |
| 300 # |
| 301 # A callback is essentially a single function declaration (outside of an |
| 302 # Interface). |
| 303 # |
| 304 def p_callback_decl(self, p): |
| 305 """callback_decl : modifiers CALLBACK SYMBOL '=' SYMBOL param_list ';'""" |
| 306 children = ListFromConcat(p[1], p[6]) |
| 307 p[0] = self.BuildNamed('Callback', p, 3, children) |
| 308 |
| 309 |
| 310 # |
| 270 # Inline | 311 # Inline |
| 271 # | 312 # |
| 272 # Inline blocks define option code to be emitted based on language tag, | 313 # Inline blocks define option code to be emitted based on language tag, |
| 273 # in the form of: | 314 # in the form of: |
| 274 # #inline <LANGUAGE> | 315 # #inline <LANGUAGE> |
| 275 # <CODE> | 316 # <CODE> |
| 276 # #endinl | 317 # #endinl |
| 277 # | 318 # |
| 278 def p_inline(self, p): | 319 def p_inline(self, p): |
| 279 """inline : modifiers INLINE""" | 320 """inline : modifiers INLINE""" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 p[0] = ListFromConcat(array, p[3]) | 516 p[0] = ListFromConcat(array, p[3]) |
| 476 # If there are 4 tokens plus a return slot it is a fixed array | 517 # If there are 4 tokens plus a return slot it is a fixed array |
| 477 elif len(p) == 5: | 518 elif len(p) == 5: |
| 478 count = self.BuildAttribute('FIXED', p[2]) | 519 count = self.BuildAttribute('FIXED', p[2]) |
| 479 array = self.BuildProduction('Array', p, 2, [count]) | 520 array = self.BuildProduction('Array', p, 2, [count]) |
| 480 p[0] = ListFromConcat(array, p[4]) | 521 p[0] = ListFromConcat(array, p[4]) |
| 481 # If there is only a return slot, do not fill it for this terminator. | 522 # If there is only a return slot, do not fill it for this terminator. |
| 482 elif len(p) == 1: return | 523 elif len(p) == 1: return |
| 483 if self.parse_debug: DumpReduction('arrays', p) | 524 if self.parse_debug: DumpReduction('arrays', p) |
| 484 | 525 |
| 526 |
| 527 # An identifier is a legal value for a parameter or attribute name. Lots of |
| 528 # existing IDL files use "callback" as a parameter/attribute name, so we allow |
| 529 # a SYMBOL or the CALLBACK keyword. |
| 530 def p_identifier(self, p): |
| 531 """identifier : SYMBOL |
| 532 | CALLBACK""" |
| 533 p[0] = p[1] |
| 534 # Save the line number of the underlying token (otherwise it gets |
| 535 # discarded), since we use it in the productions with an identifier in |
| 536 # them. |
| 537 p.set_lineno(0, p.lineno(1)) |
| 538 |
| 485 # | 539 # |
| 486 # Parameter List | 540 # Parameter List |
| 487 # | 541 # |
| 488 # A parameter list is a collection of arguments which are passed to a | 542 # A parameter list is a collection of arguments which are passed to a |
| 489 # function. | 543 # function. |
| 490 # | 544 # |
| 491 def p_param_list(self, p): | 545 def p_param_list(self, p): |
| 492 """param_list : '(' param_item param_cont ')' | 546 """param_list : '(' param_item param_cont ')' |
| 493 | '(' ')' """ | 547 | '(' ')' """ |
| 494 if len(p) > 3: | 548 if len(p) > 3: |
| 495 args = ListFromConcat(p[2], p[3]) | 549 args = ListFromConcat(p[2], p[3]) |
| 496 else: | 550 else: |
| 497 args = [] | 551 args = [] |
| 498 p[0] = self.BuildProduction('Callspec', p, 1, args) | 552 p[0] = self.BuildProduction('Callspec', p, 1, args) |
| 499 if self.parse_debug: DumpReduction('param_list', p) | 553 if self.parse_debug: DumpReduction('param_list', p) |
| 500 | 554 |
| 501 def p_param_item(self, p): | 555 def p_param_item(self, p): |
| 502 """param_item : modifiers SYMBOL arrays SYMBOL""" | 556 """param_item : modifiers optional SYMBOL arrays identifier""" |
| 503 typeref = self.BuildAttribute('TYPEREF', p[2]) | 557 typeref = self.BuildAttribute('TYPEREF', p[3]) |
| 504 children = ListFromConcat(p[1],typeref, p[3]) | 558 children = ListFromConcat(p[1],p[2], typeref, p[4]) |
| 505 p[0] = self.BuildNamed('Param', p, 4, children) | 559 p[0] = self.BuildNamed('Param', p, 5, children) |
| 506 if self.parse_debug: DumpReduction('param_item', p) | 560 if self.parse_debug: DumpReduction('param_item', p) |
| 507 | 561 |
| 562 def p_optional(self, p): |
| 563 """optional : OPTIONAL |
| 564 | """ |
| 565 if len(p) == 2: |
| 566 p[0] = self.BuildAttribute('OPTIONAL', True) |
| 567 |
| 568 |
| 508 def p_param_cont(self, p): | 569 def p_param_cont(self, p): |
| 509 """param_cont : ',' param_item param_cont | 570 """param_cont : ',' param_item param_cont |
| 510 | """ | 571 | """ |
| 511 if len(p) > 1: | 572 if len(p) > 1: |
| 512 p[0] = ListFromConcat(p[2], p[3]) | 573 p[0] = ListFromConcat(p[2], p[3]) |
| 513 if self.parse_debug: DumpReduction('param_cont', p) | 574 if self.parse_debug: DumpReduction('param_cont', p) |
| 514 | 575 |
| 515 def p_param_error(self, p): | 576 def p_param_error(self, p): |
| 516 """param_cont : error param_cont""" | 577 """param_cont : error param_cont""" |
| 517 p[0] = p[2] | 578 p[0] = p[2] |
| 518 | 579 |
| 519 | 580 |
| 520 # | 581 # |
| 521 # Typedef | 582 # Typedef |
| 522 # | 583 # |
| 523 # A typedef creates a new referencable type. The tyepdef can specify an array | 584 # A typedef creates a new referencable type. The typedef can specify an array |
| 524 # definition as well as a function declaration. | 585 # definition as well as a function declaration. |
| 525 # | 586 # |
| 526 def p_typedef_data(self, p): | 587 def p_typedef_data(self, p): |
| 527 """typedef_decl : modifiers TYPEDEF SYMBOL SYMBOL ';' """ | 588 """typedef_decl : modifiers TYPEDEF SYMBOL SYMBOL ';' """ |
| 528 typeref = self.BuildAttribute('TYPEREF', p[3]) | 589 typeref = self.BuildAttribute('TYPEREF', p[3]) |
| 529 children = ListFromConcat(p[1], typeref) | 590 children = ListFromConcat(p[1], typeref) |
| 530 p[0] = self.BuildNamed('Typedef', p, 4, children) | 591 p[0] = self.BuildNamed('Typedef', p, 4, children) |
| 531 if self.parse_debug: DumpReduction('typedef_data', p) | 592 if self.parse_debug: DumpReduction('typedef_data', p) |
| 532 | 593 |
| 533 def p_typedef_array(self, p): | 594 def p_typedef_array(self, p): |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 p[0] = p[2] | 669 p[0] = p[2] |
| 609 if self.parse_debug: DumpReduction('label_error', p) | 670 if self.parse_debug: DumpReduction('label_error', p) |
| 610 | 671 |
| 611 | 672 |
| 612 # | 673 # |
| 613 # Members | 674 # Members |
| 614 # | 675 # |
| 615 # A member attribute or function of a struct or interface. | 676 # A member attribute or function of a struct or interface. |
| 616 # | 677 # |
| 617 def p_member_attribute(self, p): | 678 def p_member_attribute(self, p): |
| 618 """member_attribute : modifiers SYMBOL SYMBOL """ | 679 """member_attribute : modifiers SYMBOL arrays questionmark identifier""" |
| 619 typeref = self.BuildAttribute('TYPEREF', p[2]) | 680 typeref = self.BuildAttribute('TYPEREF', p[2]) |
| 620 children = ListFromConcat(p[1], typeref) | 681 children = ListFromConcat(p[1], typeref, p[3], p[4]) |
| 621 p[0] = self.BuildNamed('Member', p, 3, children) | 682 p[0] = self.BuildNamed('Member', p, 5, children) |
| 622 if self.parse_debug: DumpReduction('attribute', p) | |
| 623 | |
| 624 def p_member_attribute_array(self, p): | |
| 625 """member_attribute : modifiers SYMBOL arrays SYMBOL """ | |
| 626 typeref = self.BuildAttribute('TYPEREF', p[2]) | |
| 627 children = ListFromConcat(p[1], typeref, p[3]) | |
| 628 p[0] = self.BuildNamed('Member', p, 4, children) | |
| 629 if self.parse_debug: DumpReduction('attribute', p) | 683 if self.parse_debug: DumpReduction('attribute', p) |
| 630 | 684 |
| 631 def p_member_function(self, p): | 685 def p_member_function(self, p): |
| 632 """member_function : modifiers SYMBOL SYMBOL param_list""" | 686 """member_function : modifiers static SYMBOL SYMBOL param_list""" |
| 633 typeref = self.BuildAttribute('TYPEREF', p[2]) | 687 typeref = self.BuildAttribute('TYPEREF', p[3]) |
| 634 children = ListFromConcat(p[1], typeref, p[4]) | 688 children = ListFromConcat(p[1], p[2], typeref, p[5]) |
| 635 p[0] = self.BuildNamed('Member', p, 3, children) | 689 p[0] = self.BuildNamed('Member', p, 4, children) |
| 636 if self.parse_debug: DumpReduction('function', p) | 690 if self.parse_debug: DumpReduction('function', p) |
| 637 | 691 |
| 692 def p_static(self, p): |
| 693 """static : STATIC |
| 694 | """ |
| 695 if len(p) == 2: |
| 696 p[0] = self.BuildAttribute('STATIC', True) |
| 697 |
| 698 def p_questionmark(self, p): |
| 699 """questionmark : '?' |
| 700 | """ |
| 701 if len(p) == 2: |
| 702 p[0] = self.BuildAttribute('OPTIONAL', True) |
| 703 |
| 638 # | 704 # |
| 639 # Interface | 705 # Interface |
| 640 # | 706 # |
| 641 # An interface is a named collection of functions. | 707 # An interface is a named collection of functions. |
| 642 # | 708 # |
| 643 def p_interface_block(self, p): | 709 def p_interface_block(self, p): |
| 644 """interface_block : modifiers INTERFACE SYMBOL '{' interface_list '}' ';'""
" | 710 """interface_block : modifiers INTERFACE SYMBOL '{' interface_list '}' ';'""
" |
| 645 p[0] = self.BuildNamed('Interface', p, 3, ListFromConcat(p[1], p[5])) | 711 p[0] = self.BuildNamed('Interface', p, 3, ListFromConcat(p[1], p[5])) |
| 646 if self.parse_debug: DumpReduction('interface_block', p) | 712 if self.parse_debug: DumpReduction('interface_block', p) |
| 647 | 713 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 | 829 |
| 764 def BuildNamed(self, cls, p, index, childlist=None): | 830 def BuildNamed(self, cls, p, index, childlist=None): |
| 765 if not childlist: childlist = [] | 831 if not childlist: childlist = [] |
| 766 childlist.append(self.BuildAttribute('NAME', p[index])) | 832 childlist.append(self.BuildAttribute('NAME', p[index])) |
| 767 return self.BuildProduction(cls, p, index, childlist) | 833 return self.BuildProduction(cls, p, index, childlist) |
| 768 | 834 |
| 769 def BuildComment(self, cls, p, index): | 835 def BuildComment(self, cls, p, index): |
| 770 name = p[index] | 836 name = p[index] |
| 771 | 837 |
| 772 # Remove comment markers | 838 # Remove comment markers |
| 839 lines = [] |
| 773 if name[:2] == '//': | 840 if name[:2] == '//': |
| 774 # For C++ style, remove the preceding '//' | 841 # For C++ style, remove any leading whitespace and the '//' marker from |
| 842 # each line. |
| 775 form = 'cc' | 843 form = 'cc' |
| 776 name = name[2:].rstrip() | 844 for line in name.split('\n'): |
| 845 start = line.find('//') |
| 846 lines.append(line[start+2:]) |
| 777 else: | 847 else: |
| 778 # For C style, remove ending '*/'' | 848 # For C style, remove ending '*/'' |
| 779 form = 'c' | 849 form = 'c' |
| 780 lines = [] | |
| 781 for line in name[:-2].split('\n'): | 850 for line in name[:-2].split('\n'): |
| 782 # Remove characters until start marker for this line '*' if found | 851 # Remove characters until start marker for this line '*' if found |
| 783 # otherwise it should be blank. | 852 # otherwise it should be blank. |
| 784 offs = line.find('*') | 853 offs = line.find('*') |
| 785 if offs >= 0: | 854 if offs >= 0: |
| 786 line = line[offs + 1:].rstrip() | 855 line = line[offs + 1:].rstrip() |
| 787 else: | 856 else: |
| 788 line = '' | 857 line = '' |
| 789 lines.append(line) | 858 lines.append(line) |
| 790 name = '\n'.join(lines) | 859 name = '\n'.join(lines) |
| 791 | 860 |
| 792 childlist = [self.BuildAttribute('NAME', name), | 861 childlist = [self.BuildAttribute('NAME', name), |
| 793 self.BuildAttribute('FORM', form)] | 862 self.BuildAttribute('FORM', form)] |
| 794 return self.BuildProduction(cls, p, index, childlist) | 863 return self.BuildProduction(cls, p, index, childlist) |
| 795 | 864 |
| 796 # | 865 # |
| 797 # BuildAttribute | 866 # BuildAttribute |
| 798 # | 867 # |
| 799 # An ExtendedAttribute is a special production that results in a property | 868 # An ExtendedAttribute is a special production that results in a property |
| 800 # which is applied to the adjacent item. Attributes have no children and | 869 # which is applied to the adjacent item. Attributes have no children and |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 ast = ParseFiles(filenames) | 1117 ast = ParseFiles(filenames) |
| 1049 errs = ast.GetProperty('ERRORS') | 1118 errs = ast.GetProperty('ERRORS') |
| 1050 if errs: | 1119 if errs: |
| 1051 ErrOut.Log('Found %d error(s).' % errs); | 1120 ErrOut.Log('Found %d error(s).' % errs); |
| 1052 InfoOut.Log("%d files processed." % len(filenames)) | 1121 InfoOut.Log("%d files processed." % len(filenames)) |
| 1053 return errs | 1122 return errs |
| 1054 | 1123 |
| 1055 | 1124 |
| 1056 if __name__ == '__main__': | 1125 if __name__ == '__main__': |
| 1057 sys.exit(Main(sys.argv[1:])) | 1126 sys.exit(Main(sys.argv[1:])) |
| OLD | NEW |