Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: ppapi/generators/idl_parser.py

Issue 11235016: Change the way we generate versions (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/generators/idl_node.py ('k') | ppapi/generators/idl_propertynode.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 17 matching lines...) Expand all
28 import re 28 import re
29 import sys 29 import sys
30 import time 30 import time
31 31
32 from idl_ast import IDLAst 32 from idl_ast import IDLAst
33 from idl_log import ErrOut, InfoOut, WarnOut 33 from idl_log import ErrOut, InfoOut, WarnOut
34 from idl_lexer import IDLLexer 34 from idl_lexer import IDLLexer
35 from idl_node import IDLAttribute, IDLFile, IDLNode 35 from idl_node import IDLAttribute, IDLFile, IDLNode
36 from idl_option import GetOption, Option, ParseOptions 36 from idl_option import GetOption, Option, ParseOptions
37 from idl_lint import Lint 37 from idl_lint import Lint
38 from idl_visitor import IDLVisitor
38 39
39 from ply import lex 40 from ply import lex
40 from ply import yacc 41 from ply import yacc
41 42
42 Option('build_debug', 'Debug tree building.') 43 Option('build_debug', 'Debug tree building.')
43 Option('parse_debug', 'Debug parse reduction steps.') 44 Option('parse_debug', 'Debug parse reduction steps.')
44 Option('token_debug', 'Debug token generation.') 45 Option('token_debug', 'Debug token generation.')
45 Option('dump_tree', 'Dump the tree.') 46 Option('dump_tree', 'Dump the tree.')
46 Option('srcroot', 'Working directory.', default=os.path.join('..', 'api')) 47 Option('srcroot', 'Working directory.', default=os.path.join('..', 'api'))
47 Option('include_private', 'Include private IDL directory in default API paths.') 48 Option('include_private', 'Include private IDL directory in default API paths.')
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 """top_list : callback_decl top_list 236 """top_list : callback_decl top_list
236 | describe_block top_list 237 | describe_block top_list
237 | dictionary_block top_list 238 | dictionary_block top_list
238 | enum_block top_list 239 | enum_block top_list
239 | inline top_list 240 | inline top_list
240 | interface_block top_list 241 | interface_block top_list
241 | label_block top_list 242 | label_block top_list
242 | namespace top_list 243 | namespace top_list
243 | struct_block top_list 244 | struct_block top_list
244 | typedef_decl top_list 245 | typedef_decl top_list
246 | bad_decl top_list
245 | """ 247 | """
246 if len(p) > 2: 248 if len(p) > 2:
247 p[0] = ListFromConcat(p[1], p[2]) 249 p[0] = ListFromConcat(p[1], p[2])
248 if self.parse_debug: DumpReduction('top_list', p) 250 if self.parse_debug: DumpReduction('top_list', p)
249 251
250 # Recover from error and continue parsing at the next top match. 252 # Recover from error and continue parsing at the next top match.
251 def p_top_error(self, p): 253 def p_top_error(self, p):
252 """top_list : error top_list""" 254 """top_list : error top_list"""
253 p[0] = p[2] 255 p[0] = p[2]
254 256
257 # Recover from error and continue parsing at the next top match.
258 def p_bad_decl(self, p):
259 """bad_decl : modifiers SYMBOL error '}' ';'"""
260 p[0] = []
261
255 # 262 #
256 # Modifier List 263 # Modifier List
257 # 264 #
258 # 265 #
259 def p_modifiers(self, p): 266 def p_modifiers(self, p):
260 """modifiers : comments ext_attr_block""" 267 """modifiers : comments ext_attr_block"""
261 p[0] = ListFromConcat(p[1], p[2]) 268 p[0] = ListFromConcat(p[1], p[2])
262 if self.parse_debug: DumpReduction('modifiers', p) 269 if self.parse_debug: DumpReduction('modifiers', p)
263 270
264 # 271 #
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 # A describe block is defined at the top level. It provides a mechanism for 443 # A describe block is defined at the top level. It provides a mechanism for
437 # attributing a group of ext_attr to a describe_list. Members of the 444 # attributing a group of ext_attr to a describe_list. Members of the
438 # describe list are language specific 'Type' declarations 445 # describe list are language specific 'Type' declarations
439 # 446 #
440 def p_describe_block(self, p): 447 def p_describe_block(self, p):
441 """describe_block : modifiers DESCRIBE '{' describe_list '}' ';'""" 448 """describe_block : modifiers DESCRIBE '{' describe_list '}' ';'"""
442 children = ListFromConcat(p[1], p[4]) 449 children = ListFromConcat(p[1], p[4])
443 p[0] = self.BuildProduction('Describe', p, 2, children) 450 p[0] = self.BuildProduction('Describe', p, 2, children)
444 if self.parse_debug: DumpReduction('describe_block', p) 451 if self.parse_debug: DumpReduction('describe_block', p)
445 452
453 # Recover from describe error and continue parsing at the next top match.
454 def p_describe_error(self, p):
455 """describe_list : error describe_list"""
456 p[0] = []
457
446 def p_describe_list(self, p): 458 def p_describe_list(self, p):
447 """describe_list : modifiers SYMBOL ';' describe_list 459 """describe_list : modifiers SYMBOL ';' describe_list
448 | modifiers ENUM ';' describe_list 460 | modifiers ENUM ';' describe_list
449 | modifiers STRUCT ';' describe_list 461 | modifiers STRUCT ';' describe_list
450 | modifiers TYPEDEF ';' describe_list 462 | modifiers TYPEDEF ';' describe_list
451 | """ 463 | """
452 if len(p) > 1: 464 if len(p) > 1:
453 Type = self.BuildNamed('Type', p, 2, p[1]) 465 Type = self.BuildNamed('Type', p, 2, p[1])
454 p[0] = ListFromConcat(Type, p[4]) 466 p[0] = ListFromConcat(Type, p[4])
455 467
456 def p_describe_error(self, p):
457 """describe_list : error describe_list"""
458 p[0] = p[2]
459
460 # 468 #
461 # Constant Values (integer, value) 469 # Constant Values (integer, value)
462 # 470 #
463 # Constant values can be found at various levels. A Constant value is returns 471 # Constant values can be found at various levels. A Constant value is returns
464 # as the string value after validated against a FLOAT, HEX, INT, OCT or 472 # as the string value after validated against a FLOAT, HEX, INT, OCT or
465 # STRING pattern as appropriate. 473 # STRING pattern as appropriate.
466 # 474 #
467 def p_value(self, p): 475 def p_value(self, p):
468 """value : FLOAT 476 """value : FLOAT
469 | HEX 477 | HEX
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 # Enumeration 649 # Enumeration
642 # 650 #
643 # An enumeration is a set of named integer constants. An enumeration 651 # An enumeration is a set of named integer constants. An enumeration
644 # is valid type which can be referenced in other definitions. 652 # is valid type which can be referenced in other definitions.
645 # 653 #
646 def p_enum_block(self, p): 654 def p_enum_block(self, p):
647 """enum_block : modifiers ENUM SYMBOL '{' enum_list '}' ';'""" 655 """enum_block : modifiers ENUM SYMBOL '{' enum_list '}' ';'"""
648 p[0] = self.BuildNamed('Enum', p, 3, ListFromConcat(p[1], p[5])) 656 p[0] = self.BuildNamed('Enum', p, 3, ListFromConcat(p[1], p[5]))
649 if self.parse_debug: DumpReduction('enum_block', p) 657 if self.parse_debug: DumpReduction('enum_block', p)
650 658
659 # Recover from enum error and continue parsing at the next top match.
660 def p_enum_errorA(self, p):
661 """enum_block : modifiers ENUM error '{' enum_list '}' ';'"""
662 p[0] = []
663
664 def p_enum_errorB(self, p):
665 """enum_block : modifiers ENUM error ';'"""
666 p[0] = []
667
651 def p_enum_list(self, p): 668 def p_enum_list(self, p):
652 """enum_list : modifiers SYMBOL '=' expression enum_cont 669 """enum_list : modifiers SYMBOL '=' expression enum_cont
653 | modifiers SYMBOL enum_cont""" 670 | modifiers SYMBOL enum_cont"""
654 if len(p) > 4: 671 if len(p) > 4:
655 val = self.BuildAttribute('VALUE', p[4]) 672 val = self.BuildAttribute('VALUE', p[4])
656 enum = self.BuildNamed('EnumItem', p, 2, ListFromConcat(val, p[1])) 673 enum = self.BuildNamed('EnumItem', p, 2, ListFromConcat(val, p[1]))
657 p[0] = ListFromConcat(enum, p[5]) 674 p[0] = ListFromConcat(enum, p[5])
658 else: 675 else:
659 enum = self.BuildNamed('EnumItem', p, 2, p[1]) 676 enum = self.BuildNamed('EnumItem', p, 2, p[1])
660 p[0] = ListFromConcat(enum, p[3]) 677 p[0] = ListFromConcat(enum, p[3])
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 # 753 #
737 # Interface 754 # Interface
738 # 755 #
739 # An interface is a named collection of functions. 756 # An interface is a named collection of functions.
740 # 757 #
741 def p_interface_block(self, p): 758 def p_interface_block(self, p):
742 """interface_block : modifiers INTERFACE SYMBOL '{' interface_list '}' ';'"" " 759 """interface_block : modifiers INTERFACE SYMBOL '{' interface_list '}' ';'"" "
743 p[0] = self.BuildNamed('Interface', p, 3, ListFromConcat(p[1], p[5])) 760 p[0] = self.BuildNamed('Interface', p, 3, ListFromConcat(p[1], p[5]))
744 if self.parse_debug: DumpReduction('interface_block', p) 761 if self.parse_debug: DumpReduction('interface_block', p)
745 762
763 def p_interface_error(self, p):
764 """interface_block : modifiers INTERFACE error '{' interface_list '}' ';'"""
765 p[0] = []
766
746 def p_interface_list(self, p): 767 def p_interface_list(self, p):
747 """interface_list : member_function ';' interface_list 768 """interface_list : member_function ';' interface_list
748 | """ 769 | """
749 if len(p) > 1 : 770 if len(p) > 1 :
750 p[0] = ListFromConcat(p[1], p[3]) 771 p[0] = ListFromConcat(p[1], p[3])
751 if self.parse_debug: DumpReduction('interface_list', p) 772 if self.parse_debug: DumpReduction('interface_list', p)
752 773
753 def p_interface_error(self, p):
754 """interface_list : error interface_list"""
755 p[0] = p[2]
756 774
757 # 775 #
758 # Struct 776 # Struct
759 # 777 #
760 # A struct is a named collection of members which in turn reference other 778 # A struct is a named collection of members which in turn reference other
761 # types. The struct is a referencable type. 779 # types. The struct is a referencable type.
762 # 780 #
763 def p_struct_block(self, p): 781 def p_struct_block(self, p):
764 """struct_block : modifiers STRUCT SYMBOL '{' struct_list '}' ';'""" 782 """struct_block : modifiers STRUCT SYMBOL '{' struct_list '}' ';'"""
765 children = ListFromConcat(p[1], p[5]) 783 children = ListFromConcat(p[1], p[5])
766 p[0] = self.BuildNamed('Struct', p, 3, children) 784 p[0] = self.BuildNamed('Struct', p, 3, children)
767 if self.parse_debug: DumpReduction('struct_block', p) 785 if self.parse_debug: DumpReduction('struct_block', p)
768 786
787 # Recover from struct error and continue parsing at the next top match.
788 def p_struct_error(self, p):
789 """enum_block : modifiers STRUCT error '{' struct_list '}' ';'"""
790 p[0] = []
791
769 def p_struct_list(self, p): 792 def p_struct_list(self, p):
770 """struct_list : member_attribute ';' struct_list 793 """struct_list : member_attribute ';' struct_list
771 | member_function ';' struct_list 794 | member_function ';' struct_list
772 |""" 795 |"""
773 if len(p) > 1: p[0] = ListFromConcat(p[1], p[3]) 796 if len(p) > 1: p[0] = ListFromConcat(p[1], p[3])
774 797
775 def p_struct_error(self, p):
776 """struct_list : error struct_list"""
777 p[0] = p[2]
778 798
779 # 799 #
780 # Parser Errors 800 # Parser Errors
781 # 801 #
782 # p_error is called whenever the parser can not find a pattern match for 802 # p_error is called whenever the parser can not find a pattern match for
783 # a set of items from the current state. The p_error function defined here 803 # a set of items from the current state. The p_error function defined here
784 # is triggered logging an error, and parsing recover happens as the 804 # is triggered logging an error, and parsing recover happens as the
785 # p_<type>_error functions defined above are called. This allows the parser 805 # p_<type>_error functions defined above are called. This allows the parser
786 # to continue so as to capture more than one error per file. 806 # to continue so as to capture more than one error per file.
787 # 807 #
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 ast = ParseFiles(testnames) 1116 ast = ParseFiles(testnames)
1097 InfoOut.SetConsole(True) 1117 InfoOut.SetConsole(True)
1098 1118
1099 errs = ast.GetProperty('ERRORS') 1119 errs = ast.GetProperty('ERRORS')
1100 if errs: 1120 if errs:
1101 ErrOut.Log("Failed namespace test.") 1121 ErrOut.Log("Failed namespace test.")
1102 else: 1122 else:
1103 InfoOut.Log("Passed namespace test.") 1123 InfoOut.Log("Passed namespace test.")
1104 return errs 1124 return errs
1105 1125
1126
1127
1128 def FindVersionError(releases, node):
1129 err_cnt = 0
1130 if node.IsA('Interface', 'Struct'):
1131 comment_list = []
1132 comment = node.GetOneOf('Comment')
1133 if comment:
1134 print comment.GetName()
1135 if comment and comment.GetName()[:4] == 'REL:':
1136 comment_list = comment.GetName()[5:].strip().split(' ')
1137 print comment_list
1138
1139 if len(comment_list) != len(releases):
1140 node.Error("Mismatch size of releases: %s vs %s." % (
1141 comment_list, releases))
1142 err_cnt += 1
1143 else:
1144 first_list = [node.first_release[rel] for rel in releases]
1145 if first_list != comment_list:
1146 node.Error("Mismatch in releases: %s vs %s." % (
1147 comment_list, first_list))
1148 err_cnt += 1
1149
1150 for child in node.GetChildren():
1151 err_cnt += FindVersionError(releases, child)
1152 return err_cnt
1153
1154
1155 def TestVersionFiles(filter):
1156 idldir = os.path.split(sys.argv[0])[0]
1157 idldir = os.path.join(idldir, 'test_version', '*.idl')
1158 filenames = glob.glob(idldir)
1159 testnames = []
1160
1161 for filename in filenames:
1162 if filter and filename not in filter: continue
1163 testnames.append(filename)
1164
1165 # If we have no files to test, then skip this test
1166 if not testnames:
1167 InfoOut.Log('No files to test for version.')
1168 return 0
1169
1170 ast = ParseFiles(testnames)
1171 errs = FindVersionError(ast.releases, ast)
1172
1173 if errs:
1174 ErrOut.Log("Failed version test.")
1175 else:
1176 InfoOut.Log("Passed version test.")
1177 return errs
1178
1179
1106 default_dirs = ['.', 'trusted', 'dev', 'private'] 1180 default_dirs = ['.', 'trusted', 'dev', 'private']
1107 def ParseFiles(filenames): 1181 def ParseFiles(filenames):
1108 parser = IDLParser() 1182 parser = IDLParser()
1109 filenodes = [] 1183 filenodes = []
1110 1184
1111 if not filenames: 1185 if not filenames:
1112 filenames = [] 1186 filenames = []
1113 srcroot = GetOption('srcroot') 1187 srcroot = GetOption('srcroot')
1114 dirs = default_dirs 1188 dirs = default_dirs
1115 if GetOption('include_private'): 1189 if GetOption('include_private'):
(...skipping 17 matching lines...) Expand all
1133 return ast 1207 return ast
1134 1208
1135 1209
1136 def Main(args): 1210 def Main(args):
1137 filenames = ParseOptions(args) 1211 filenames = ParseOptions(args)
1138 1212
1139 # If testing... 1213 # If testing...
1140 if GetOption('test'): 1214 if GetOption('test'):
1141 errs = TestErrorFiles(filenames) 1215 errs = TestErrorFiles(filenames)
1142 errs = TestNamespaceFiles(filenames) 1216 errs = TestNamespaceFiles(filenames)
1217 errs = TestVersionFiles(filenames)
1143 if errs: 1218 if errs:
1144 ErrOut.Log("Parser failed with %d errors." % errs) 1219 ErrOut.Log("Parser failed with %d errors." % errs)
1145 return -1 1220 return -1
1146 return 0 1221 return 0
1147 1222
1148 # Otherwise, build the AST 1223 # Otherwise, build the AST
1149 ast = ParseFiles(filenames) 1224 ast = ParseFiles(filenames)
1150 errs = ast.GetProperty('ERRORS') 1225 errs = ast.GetProperty('ERRORS')
1151 if errs: 1226 if errs:
1152 ErrOut.Log('Found %d error(s).' % errs); 1227 ErrOut.Log('Found %d error(s).' % errs);
1153 InfoOut.Log("%d files processed." % len(filenames)) 1228 InfoOut.Log("%d files processed." % len(filenames))
1154 return errs 1229 return errs
1155 1230
1156 1231
1157 if __name__ == '__main__': 1232 if __name__ == '__main__':
1158 sys.exit(Main(sys.argv[1:])) 1233 sys.exit(Main(sys.argv[1:]))
1234
OLDNEW
« no previous file with comments | « ppapi/generators/idl_node.py ('k') | ppapi/generators/idl_propertynode.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698