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

Side by Side Diff: client/dom/scripts/idlparser.py

Issue 9845043: Rename client/{dom,html} to lib/{dom,html} . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months 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 | « client/dom/scripts/idlparser.dart ('k') | client/dom/scripts/idlparser_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file.
5
6 import re
7 import subprocess
8 import tempfile
9
10 from pegparser import *
11
12 # IDL grammar variants.
13 WEBIDL_SYNTAX = 0
14 WEBKIT_SYNTAX = 1
15 FREMONTCUT_SYNTAX = 2
16
17
18 class IDLParser(object):
19 """IDLParser is a PEG based IDL files parser."""
20
21 def __init__(self, syntax=WEBIDL_SYNTAX):
22 """Constructor.
23
24 Initializes the IDLParser by defining the grammar and initializing
25 a PEGParserinstance.
26
27 Args:
28 syntax -- supports either WEBIDL_SYNTAX (0) or WEBKIT_SYNTAX (1)
29 """
30 self._syntax = syntax
31 self._pegparser = PegParser(self._idl_grammar(),
32 self._whitespace_grammar(),
33 strings_are_tokens=True)
34
35 def _idl_grammar(self):
36 """Returns the PEG grammar for IDL parsing."""
37
38 # utilities:
39 def syntax_switch(w3c_syntax, webkit_syntax, fremontcut_syntax=None):
40 """Returns w3c_syntax or web_syntax, depending on the current
41 configuration.
42 """
43 if self._syntax == WEBIDL_SYNTAX:
44 return w3c_syntax
45 elif self._syntax == WEBKIT_SYNTAX:
46 return webkit_syntax
47 elif self._syntax == FREMONTCUT_SYNTAX:
48 if fremontcut_syntax is not None:
49 return fremontcut_syntax
50 return w3c_syntax
51 else:
52 raise RuntimeError('unsupported IDL syntax %s' % syntax)
53
54 # The following grammar is based on the Web IDL's LL(1) grammar
55 # (specified in: http://dev.w3.org/2006/webapi/WebIDL/#idl-grammar).
56 # It is adjusted to PEG grammar, as well as to also support
57 # WebKit IDL and FremontCut grammar.
58
59 ###################### BEGIN GRAMMAR #####################
60
61 def Id():
62 return re.compile(r'[\w\_]+')
63
64 def _Definitions():
65 return MAYBE(MANY(_Definition))
66
67 def _Definition():
68 return syntax_switch(
69 # Web IDL:
70 OR(Module, Interface, ExceptionDef, TypeDef, ImplStmt,
71 ValueTypeDef, Const),
72 # WebKit:
73 OR(Module, Interface))
74
75 def Module():
76 return syntax_switch(
77 # Web IDL:
78 [MAYBE(ExtAttrs), 'module', Id, '{', _Definitions, '}',
79 MAYBE(';')],
80 # WebKit:
81 ['module', MAYBE(ExtAttrs), Id, '{', _Definitions, '}',
82 MAYBE(';')],
83 # FremontCut:
84 [MAYBE(_Annotations), MAYBE(ExtAttrs), 'module', Id,
85 '{', _Definitions, '}', MAYBE(';')])
86
87 def Interface():
88 return syntax_switch(
89 # Web IDL:
90 [MAYBE(ExtAttrs), 'interface', Id, MAYBE(_ParentInterfaces),
91 MAYBE(['{', MAYBE(MANY(_Member)), '}']), ';'],
92 # WebKit:
93 ['interface', MAYBE(ExtAttrs), Id, MAYBE(_ParentInterfaces),
94 MAYBE(['{', MAYBE(MANY(_Member)), '}']), MAYBE(';')],
95 # FremontCut:
96 [MAYBE(_Annotations), MAYBE(ExtAttrs), 'interface',
97 Id, MAYBE(_ParentInterfaces), MAYBE(['{', MAYBE(MANY(_Member)),
98 '}']), ';'])
99
100 def _Member():
101 return syntax_switch(
102 # Web IDL:
103 OR(Const, Attribute, Operation, ExtAttrs),
104 # WebKit:
105 OR(Const, Attribute, Operation),
106 # FremontCut:
107 OR(Const, Attribute, Operation))
108
109 # Interface inheritance:
110 def _ParentInterfaces():
111 return [':', MANY(ParentInterface, separator=',')]
112
113 def ParentInterface():
114 return syntax_switch(
115 # Web IDL:
116 [InterfaceType],
117 # WebKit:
118 [InterfaceType],
119 # FremontCut:
120 [MAYBE(_Annotations), InterfaceType])
121
122 # TypeDef (Web IDL):
123 def TypeDef():
124 return ['typedef', Type, Id, ';']
125
126 # TypeDef (Old-school W3C IDLs)
127 def ValueTypeDef():
128 return ['valuetype', Id, Type, ';']
129
130 # Implements Statement (Web IDL):
131 def ImplStmt():
132 return [ImplStmtImplementor, 'implements', ImplStmtImplemented,
133 ';']
134
135 def ImplStmtImplementor():
136 return ScopedName
137
138 def ImplStmtImplemented():
139 return ScopedName
140
141 # Constants:
142 def Const():
143 return syntax_switch(
144 # Web IDL:
145 [MAYBE(ExtAttrs), 'const', Type, Id, '=', ConstExpr, ';'],
146 # WebKit:
147 [MAYBE(ExtAttrs), 'const', Type, Id, '=', ConstExpr, ';'],
148 # FremontCut:
149 [MAYBE(_Annotations), MAYBE(ExtAttrs), 'const', Type, Id, '=',
150 ConstExpr, ';'])
151
152 def ConstExpr():
153 return OR(_BooleanLiteral,
154 _IntegerLiteral,
155 _FloatLiteral)
156
157 def _BooleanLiteral():
158 return re.compile(r'true|false')
159
160 def _IntegerLiteral():
161 return OR(re.compile(r'(0x)?[0-9ABCDEF]+'),
162 re.compile(r'[0-9]+'))
163
164 def _FloatLiteral():
165 return re.compile(r'[0-9]+\.[0-9]*')
166
167 # Attributes:
168 def Attribute():
169 return syntax_switch(
170 # Web IDL:
171 [MAYBE(ExtAttrs), MAYBE(Stringifier), MAYBE(ReadOnly),
172 'attribute', Type, Id, MAYBE(_AttrRaises), ';'],
173 # WebKit:
174 [MAYBE(Stringifier), MAYBE(ReadOnly), 'attribute',
175 MAYBE(ExtAttrs), Type, Id, MAYBE(_AttrRaises), ';'],
176 # FremontCut:
177 [MAYBE(_Annotations), MAYBE(ExtAttrs),
178 MAYBE(_AttrGetterSetter), MAYBE(Stringifier), MAYBE(ReadOnly),
179 'attribute', Type, Id, MAYBE(_AttrRaises), ';'])
180
181 def _AttrRaises():
182 return syntax_switch(
183 # Web IDL:
184 MANY(OR(GetRaises, SetRaises)),
185 # WebKit:
186 MANY(OR(GetRaises, SetRaises, Raises), separator=','))
187
188 # Special fremontcut feature:
189 def _AttrGetterSetter():
190 return OR(AttrGetter, AttrSetter)
191
192 def AttrGetter():
193 return 'getter'
194
195 def AttrSetter():
196 return 'setter'
197
198 def ReadOnly():
199 return 'readonly'
200
201 def GetRaises():
202 return syntax_switch(
203 # Web IDL:
204 ['getraises', '(', _ScopedNames, ')'],
205 # WebKit:
206 ['getter', 'raises', '(', _ScopedNames, ')'])
207
208 def SetRaises():
209 return syntax_switch(
210 # Web IDL:
211 ['setraises', '(', _ScopedNames, ')'],
212 # WebKit:
213 ['setter', 'raises', '(', _ScopedNames, ')'])
214
215 # Operation:
216 def Operation():
217 return syntax_switch(
218 # Web IDL:
219 [MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier), MAYBE(_Specials),
220 ReturnType, MAYBE(Id), '(', _Arguments, ')', MAYBE(Raises),
221 ';'],
222 # WebKit:
223 [MAYBE(ExtAttrs), MAYBE(Static),
224 ReturnType, MAYBE(Id), '(', _Arguments, ')',
225 MAYBE(Raises), ';'],
226 # FremontCut:
227 [MAYBE(_Annotations), MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier) ,
228 MAYBE(_Specials), ReturnType, MAYBE(Id), '(', _Arguments, ')',
229 MAYBE(Raises), ';'])
230
231 def Static():
232 return 'static'
233
234 def _Specials():
235 return MANY(Special)
236
237 def Special():
238 return re.compile(r'getter|setter|creator|deleter|caller')
239
240 def Stringifier():
241 return 'stringifier'
242
243 def Raises():
244 return ['raises', '(', _ScopedNames, ')']
245
246 # Operation arguments:
247 def _Arguments():
248 return MAYBE(MANY(Argument, ','))
249
250 def Argument():
251 return syntax_switch(
252 # Web IDL:
253 [MAYBE(ExtAttrs), MAYBE(Optional), MAYBE('in'),
254 MAYBE(Optional), Type, MAYBE(AnEllipsis), Id],
255 # WebKit:
256 [MAYBE(Optional), MAYBE('in'), MAYBE(Optional),
257 MAYBE(ExtAttrs), Type, Id])
258
259 def Optional():
260 return 'optional'
261
262 def AnEllipsis():
263 return '...'
264
265 # Exceptions (Web IDL).
266 def ExceptionDef():
267 return ['exception', Id, '{', MAYBE(MANY(_ExceptionMember)), '}',
268 ';']
269
270 def _ExceptionMember():
271 return OR(Const, ExceptionField, ExtAttrs)
272
273 def ExceptionField():
274 return [Type, Id, ';']
275
276 # Types:
277 def Type():
278 return _Type
279
280 def ReturnType():
281 return OR(VoidType, _Type)
282
283 def InterfaceType():
284 return ScopedName
285
286 def _Type():
287 return OR(AnyArrayType, AnyType, ObjectType, _NullableType)
288
289 def _NullableType():
290 return [OR(_IntegerType, BooleanType, OctetType, FloatType,
291 DoubleType, SequenceType, DOMStringArrayType, ScopedName),
292 MAYBE(Nullable)]
293
294 def Nullable():
295 return '?'
296
297 def SequenceType():
298 return ['sequence', '<', Type, '>']
299
300 def AnyType():
301 return 'any'
302
303 def AnyArrayType():
304 # TODO(sra): Do more general handling of array types.
305 return 'any[]'
306
307 def ObjectType():
308 return re.compile(r'(object|Object)\b') # both spellings.
309
310 def VoidType():
311 return 'void'
312
313 def _IntegerType():
314 return [MAYBE(Unsigned), OR(ByteType, IntType, LongLongType,
315 LongType, OctetType, ShortType)]
316
317 def Unsigned():
318 return 'unsigned'
319
320 def ShortType():
321 return 'short'
322
323 def LongLongType():
324 return ['long', 'long']
325
326 def LongType():
327 return 'long'
328
329 def IntType():
330 return 'int'
331
332 def ByteType():
333 return 'byte'
334
335 def OctetType():
336 return 'octet'
337
338 def BooleanType():
339 return 'boolean'
340
341 def FloatType():
342 return 'float'
343
344 def DoubleType():
345 return 'double'
346
347 def _ScopedNames():
348 return MANY(ScopedName, separator=',')
349
350 def ScopedName():
351 return re.compile(r'[\w\_\:\.\<\>]+')
352
353 def DOMStringArrayType():
354 return 'DOMString[]'
355
356 # Extended Attributes:
357 def ExtAttrs():
358 return ['[', MAYBE(MANY(ExtAttr, ',')), ']']
359
360 def ExtAttr():
361 return [Id, MAYBE(OR(['=', ExtAttrValue], ExtAttrArgList))]
362
363 def ExtAttrValue():
364 return OR(ExtAttrFunctionValue, re.compile(r'[\w&0-9:\-\|]+'))
365
366 def ExtAttrFunctionValue():
367 return [Id, ExtAttrArgList]
368
369 def ExtAttrArgList():
370 return ['(', MAYBE(MANY(Argument, ',')), ')']
371
372 # Annotations - used in the FremontCut IDL grammar:
373 def _Annotations():
374 return MANY(Annotation)
375
376 def Annotation():
377 return ['@', Id, MAYBE(_AnnotationBody)]
378
379 def _AnnotationBody():
380 return ['(', MAYBE(MANY(AnnotationArg, ',')), ')']
381
382 def AnnotationArg():
383 return [Id, MAYBE(['=', AnnotationArgValue])]
384
385 def AnnotationArgValue():
386 return re.compile(r'[\w&0-9:/\-\.]+')
387
388 ###################### END GRAMMAR #####################
389
390 # Return the grammar's root rule:
391 return MANY(_Definition)
392
393 def _whitespace_grammar(self):
394 return OR(re.compile(r'\s+'),
395 re.compile(r'//.*'),
396 re.compile(r'#.*'),
397 re.compile(r'/\*.*?\*/', re.S))
398
399 def _pre_process(self, content, defines, includePaths):
400 """Pre-processes the content using gcc.
401
402 WebKit IDLs require pre-processing by gcc. This is done by invoking
403 gcc in a sub-process and capturing the results.
404
405 Returns:
406 The result of running gcc on the content.
407
408 Args:
409 content -- text to process.
410 defines -- an array of pre-processor defines.
411 includePaths -- an array of path strings.
412 """
413 # FIXME: Handle gcc not found, or any other processing errors
414 gcc = 'gcc'
415 cmd = [gcc, '-E', '-P', '-C', '-x', 'c++'];
416 for define in defines:
417 cmd.append('-D%s' % define)
418 cmd.append('-')
419 pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
420 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
421 (content, stderr) = pipe.communicate(content)
422 return content
423
424 def parse(self, content, defines=[], includePaths=[]):
425 """Parse the give content string.
426
427 The WebKit IDL syntax also allows gcc pre-processing instructions.
428 Lists of defined variables and include paths can be provided.
429
430 Returns:
431 An abstract syntax tree (AST).
432
433 Args:
434 content -- text to parse.
435 defines -- an array of pre-processor defines.
436 includePaths -- an array of path strings used by the
437 gcc pre-processor.
438 """
439 if self._syntax == WEBKIT_SYNTAX:
440 content = self._pre_process(content, defines, includePaths)
441
442 return self._pegparser.parse(content)
OLDNEW
« no previous file with comments | « client/dom/scripts/idlparser.dart ('k') | client/dom/scripts/idlparser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698