[GCM] Persistence of account mappings.
[chromium-blink-merge.git] / tools / idl_parser / idl_ppapi_parser.py
blob639a8415ba62c4cb74fcd2d8805bfa7965e61a35
1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """ Parser for PPAPI IDL """
9 # IDL Parser
11 # The parser is uses the PLY yacc library to build a set of parsing rules based
12 # on WebIDL.
14 # WebIDL, and WebIDL grammar can be found at:
15 # http://heycam.github.io/webidl/
16 # PLY can be found at:
17 # http://www.dabeaz.com/ply/
19 # The parser generates a tree by recursively matching sets of items against
20 # defined patterns. When a match is made, that set of items is reduced
21 # to a new item. The new item can provide a match for parent patterns.
22 # In this way an AST is built (reduced) depth first.
26 # Disable check for line length and Member as Function due to how grammar rules
27 # are defined with PLY
29 # pylint: disable=R0201
30 # pylint: disable=C0301
32 import sys
34 from idl_ppapi_lexer import IDLPPAPILexer
35 from idl_parser import IDLParser, ListFromConcat, ParseFile
36 from idl_node import IDLNode
38 class IDLPPAPIParser(IDLParser):
40 # We force all input files to start with two comments. The first comment is a
41 # Copyright notice followed by a file comment and finally by file level
42 # productions.
44 # [0] Insert a TOP definition for Copyright and Comments
45 def p_Top(self, p):
46 """Top : COMMENT COMMENT Definitions"""
47 Copyright = self.BuildComment('Copyright', p, 1)
48 Filedoc = self.BuildComment('Comment', p, 2)
49 p[0] = ListFromConcat(Copyright, Filedoc, p[3])
52 #The parser is based on the WebIDL standard. See:
53 # http://heycam.github.io/webidl/#idl-grammar
55 # [1]
56 def p_Definitions(self, p):
57 """Definitions : ExtendedAttributeList Definition Definitions
58 | """
59 if len(p) > 1:
60 p[2].AddChildren(p[1])
61 p[0] = ListFromConcat(p[2], p[3])
63 # [2] Add INLINE definition
64 def p_Definition(self, p):
65 """Definition : CallbackOrInterface
66 | Struct
67 | Partial
68 | Dictionary
69 | Exception
70 | Enum
71 | Typedef
72 | ImplementsStatement
73 | Label
74 | Inline"""
75 p[0] = p[1]
77 def p_Inline(self, p):
78 """Inline : INLINE"""
79 words = p[1].split()
80 name = self.BuildAttribute('NAME', words[1])
81 lines = p[1].split('\n')
82 value = self.BuildAttribute('VALUE', '\n'.join(lines[1:-1]) + '\n')
83 children = ListFromConcat(name, value)
84 p[0] = self.BuildProduction('Inline', p, 1, children)
87 # Label
89 # A label is a special kind of enumeration which allows us to go from a
90 # set of version numbrs to releases
92 def p_Label(self, p):
93 """Label : LABEL identifier '{' LabelList '}' ';'"""
94 p[0] = self.BuildNamed('Label', p, 2, p[4])
96 def p_LabelList(self, p):
97 """LabelList : identifier '=' float LabelCont"""
98 val = self.BuildAttribute('VALUE', p[3])
99 label = self.BuildNamed('LabelItem', p, 1, val)
100 p[0] = ListFromConcat(label, p[4])
102 def p_LabelCont(self, p):
103 """LabelCont : ',' LabelList
104 |"""
105 if len(p) > 1:
106 p[0] = p[2]
108 def p_LabelContError(self, p):
109 """LabelCont : error LabelCont"""
110 p[0] = p[2]
112 # [5.1] Add "struct" style interface
113 def p_Struct(self, p):
114 """Struct : STRUCT identifier Inheritance '{' StructMembers '}' ';'"""
115 p[0] = self.BuildNamed('Struct', p, 2, ListFromConcat(p[3], p[5]))
117 def p_StructMembers(self, p):
118 """StructMembers : StructMember StructMembers
119 |"""
120 if len(p) > 1:
121 p[0] = ListFromConcat(p[1], p[2])
123 def p_StructMember(self, p):
124 """StructMember : ExtendedAttributeList Type identifier ';'"""
125 p[0] = self.BuildNamed('Member', p, 3, ListFromConcat(p[1], p[2]))
127 # [24]
128 def p_Typedef(self, p):
129 """Typedef : TYPEDEF ExtendedAttributeListNoComments Type identifier ';'"""
130 p[0] = self.BuildNamed('Typedef', p, 4, ListFromConcat(p[2], p[3]))
132 # [24.1]
133 def p_TypedefFunc(self, p):
134 """Typedef : TYPEDEF ExtendedAttributeListNoComments ReturnType identifier '(' ArgumentList ')' ';'"""
135 args = self.BuildProduction('Arguments', p, 5, p[6])
136 p[0] = self.BuildNamed('Callback', p, 4, ListFromConcat(p[2], p[3], args))
138 # [27]
139 def p_ConstValue(self, p):
140 """ConstValue : integer
141 | integer LSHIFT integer
142 | integer RSHIFT integer"""
143 val = str(p[1])
144 if len(p) > 2:
145 val = "%s %s %s" % (p[1], p[2], p[3])
146 p[0] = ListFromConcat(self.BuildAttribute('TYPE', 'integer'),
147 self.BuildAttribute('VALUE', val))
149 def p_ConstValueStr(self, p):
150 """ConstValue : string"""
151 p[0] = ListFromConcat(self.BuildAttribute('TYPE', 'string'),
152 self.BuildAttribute('VALUE', p[1]))
154 # Boolean & Float Literals area already BuildAttributes
155 def p_ConstValueLiteral(self, p):
156 """ConstValue : FloatLiteral
157 | BooleanLiteral """
158 p[0] = p[1]
160 # [21]
161 def p_EnumValueList(self, p):
162 """EnumValueList : EnumValue EnumValues"""
163 p[0] = ListFromConcat(p[1], p[2])
165 # [22]
166 def p_EnumValues(self, p):
167 """EnumValues : ',' EnumValue EnumValues
168 |"""
169 if len(p) > 1:
170 p[0] = ListFromConcat(p[2], p[3])
172 def p_EnumValue(self, p):
173 """EnumValue : ExtendedAttributeList identifier
174 | ExtendedAttributeList identifier '=' ConstValue"""
175 p[0] = self.BuildNamed('EnumItem', p, 2, p[1])
176 if len(p) > 3:
177 p[0].AddChildren(p[4])
179 def p_PrimitiveType(self, p):
180 """PrimitiveType : IntegerType
181 | UnsignedIntegerType
182 | FloatType
183 | HandleType
184 | PointerType"""
185 if type(p[1]) == str:
186 p[0] = self.BuildNamed('PrimitiveType', p, 1)
187 else:
188 p[0] = p[1]
190 def p_PointerType(self, p):
191 """PointerType : STR_T
192 | MEM_T
193 | CSTR_T
194 | INTERFACE_T
195 | NULL"""
196 p[0] = p[1]
198 def p_HandleType(self, p):
199 """HandleType : HANDLE_T
200 | PP_FILEHANDLE"""
201 p[0] = p[1]
203 # [66]
204 def p_FloatType(self, p):
205 """FloatType : FLOAT_T
206 | DOUBLE_T"""
207 p[0] = p[1]
209 # [67]
210 def p_UnsignedIntegerType(self, p):
211 """UnsignedIntegerType : UINT8_T
212 | UINT16_T
213 | UINT32_T
214 | UINT64_T"""
215 p[0] = p[1]
218 # [68]
219 def p_IntegerType(self, p):
220 """IntegerType : CHAR
221 | INT8_T
222 | INT16_T
223 | INT32_T
224 | INT64_T"""
225 p[0] = p[1]
227 # These targets are no longer used
228 def p_OptionalLong(self, p):
229 """ """
230 pass
232 def p_UnrestrictedFloatType(self, p):
233 """ """
234 pass
236 def p_null(self, p):
237 """ """
238 pass
240 # We only support:
241 # [ identifier ]
242 # [ identifier = identifier ]
243 # [ identifier ( ArgumentList )]
244 # [ identifier ( ValueList )]
245 # [ identifier = identifier ( ArgumentList )]
246 # [51] map directly to 74-77
247 # [52-54, 56] are unsupported
248 def p_ExtendedAttribute(self, p):
249 """ExtendedAttribute : ExtendedAttributeNoArgs
250 | ExtendedAttributeArgList
251 | ExtendedAttributeValList
252 | ExtendedAttributeIdent
253 | ExtendedAttributeIdentConst
254 | ExtendedAttributeNamedArgList"""
255 p[0] = p[1]
257 def p_ExtendedAttributeValList(self, p):
258 """ExtendedAttributeValList : identifier '(' ValueList ')'"""
259 arguments = self.BuildProduction('Values', p, 2, p[3])
260 p[0] = self.BuildNamed('ExtAttribute', p, 1, arguments)
262 def p_ValueList(self, p):
263 """ValueList : ConstValue ValueListCont"""
264 p[0] = ListFromConcat(p[1], p[2])
266 def p_ValueListCont(self, p):
267 """ValueListCont : ValueList
268 |"""
269 if len(p) > 1:
270 p[0] = p[1]
272 # [76]
273 def p_ExtendedAttributeIdentConst(self, p):
274 """ExtendedAttributeIdentConst : identifier '=' ConstValue"""
275 p[0] = self.BuildNamed('ExtAttribute', p, 1, p[3])
278 def __init__(self, lexer, verbose=False, debug=False, mute_error=False):
279 IDLParser.__init__(self, lexer, verbose, debug, mute_error)
282 def main(argv):
283 nodes = []
284 parser = IDLPPAPIParser(IDLPPAPILexer())
285 errors = 0
287 for filename in argv:
288 filenode = ParseFile(parser, filename)
289 if filenode:
290 errors += filenode.GetProperty('ERRORS')
291 nodes.append(filenode)
293 ast = IDLNode('AST', '__AST__', 0, 0, nodes)
295 print '\n'.join(ast.Tree(accept_props=['PROD', 'TYPE', 'VALUE']))
296 if errors:
297 print '\nFound %d errors.\n' % errors
300 return errors
303 if __name__ == '__main__':
304 sys.exit(main(sys.argv[1:]))