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

Side by Side Diff: sdk/lib/html/scripts/idlparser.py

Issue 11691009: Moved most of html lib generating scripts into tools. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 12 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 | « sdk/lib/html/scripts/idlparser.dart ('k') | sdk/lib/html/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 [MAYBE(ExtAttrs), OR('interface', 'exception'), MAYBE(ExtAttrs), Id, MAY BE(_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 [
175 MAYBE(Stringifier),
176 MAYBE(ExtAttrs), MAYBE(Static), MAYBE(ReadOnly), 'attribute', MAYBE(Ex tAttrs),
177 Type, Id, MAYBE(_AttrRaises), ';'],
178 # FremontCut:
179 [MAYBE(_Annotations), MAYBE(ExtAttrs),
180 MAYBE(_AttrGetterSetter), MAYBE(Stringifier), MAYBE(ReadOnly),
181 'attribute', Type, Id, MAYBE(_AttrRaises), ';'])
182
183 def _AttrRaises():
184 return syntax_switch(
185 # Web IDL:
186 MANY(OR(GetRaises, SetRaises)),
187 # WebKit:
188 MANY(OR(GetRaises, SetRaises, Raises), separator=','))
189
190 # Special fremontcut feature:
191 def _AttrGetterSetter():
192 return OR(AttrGetter, AttrSetter)
193
194 def AttrGetter():
195 return 'getter'
196
197 def AttrSetter():
198 return 'setter'
199
200 def ReadOnly():
201 return 'readonly'
202
203 def GetRaises():
204 return syntax_switch(
205 # Web IDL:
206 ['getraises', '(', _ScopedNames, ')'],
207 # WebKit:
208 ['getter', 'raises', '(', _ScopedNames, ')'])
209
210 def SetRaises():
211 return syntax_switch(
212 # Web IDL:
213 ['setraises', '(', _ScopedNames, ')'],
214 # WebKit:
215 ['setter', 'raises', '(', _ScopedNames, ')'])
216
217 # Operation:
218 def Operation():
219 return syntax_switch(
220 # Web IDL:
221 [MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier), MAYBE(_Specials),
222 ReturnType, MAYBE(Id), '(', _Arguments, ')', MAYBE(Raises),
223 ';'],
224 # WebKit:
225 [MAYBE(ExtAttrs), MAYBE(Static),
226 ReturnType, MAYBE(Id), '(', _Arguments, ')',
227 MAYBE(Raises), ';'],
228 # FremontCut:
229 [MAYBE(_Annotations), MAYBE(ExtAttrs), MAYBE(Static), MAYBE(Stringifier) ,
230 MAYBE(_Specials), ReturnType, MAYBE(Id), '(', _Arguments, ')',
231 MAYBE(Raises), ';'])
232
233 def Static():
234 return 'static'
235
236 def _Specials():
237 return MANY(Special)
238
239 def Special():
240 return re.compile(r'getter|setter|creator|deleter|caller')
241
242 def Stringifier():
243 return 'stringifier'
244
245 def Raises():
246 return ['raises', '(', _ScopedNames, ')']
247
248 # Operation arguments:
249 def _Arguments():
250 return MAYBE(MANY(Argument, ','))
251
252 def Argument():
253 return syntax_switch(
254 # Web IDL:
255 [MAYBE(ExtAttrs), MAYBE(Optional), MAYBE('in'),
256 MAYBE(Optional), Type, MAYBE(AnEllipsis), Id],
257 # WebKit:
258 [MAYBE(Optional), MAYBE('in'), MAYBE(Optional),
259 MAYBE(ExtAttrs), Type, Id])
260
261 def Optional():
262 return 'optional'
263
264 def AnEllipsis():
265 return '...'
266
267 # Exceptions (Web IDL).
268 def ExceptionDef():
269 return ['exception', Id, '{', MAYBE(MANY(_ExceptionMember)), '}',
270 ';']
271
272 def _ExceptionMember():
273 return OR(Const, ExceptionField, ExtAttrs)
274
275 def ExceptionField():
276 return [Type, Id, ';']
277
278 # Types:
279 def Type():
280 return _Type
281
282 def ReturnType():
283 return OR(VoidType, _Type)
284
285 def InterfaceType():
286 return ScopedName
287
288 def ArrayModifiers():
289 return re.compile(r'(\[\])+')
290
291 def _Type():
292 return OR(
293 [OR(AnyType, ObjectType), MAYBE([ArrayModifiers, MAYBE(Nullable)])],
294 [_NullableNonArrayType(), MAYBE(ArrayModifiers), MAYBE(Nullable)])
295
296 def _NullableNonArrayType():
297 return [OR(_IntegerType, BooleanType, OctetType, FloatType,
298 DoubleType, SequenceType, ScopedName)]
299
300 def Nullable():
301 return '?'
302
303 def SequenceType():
304 return ['sequence', '<', Type, '>']
305
306 def AnyType():
307 return 'any'
308
309 def ObjectType():
310 return re.compile(r'(object|Object)\b') # both spellings.
311
312 def VoidType():
313 return 'void'
314
315 def _IntegerType():
316 return [MAYBE(Unsigned), OR(ByteType, IntType, LongLongType,
317 LongType, OctetType, ShortType)]
318
319 def Unsigned():
320 return 'unsigned'
321
322 def ShortType():
323 return 'short'
324
325 def LongLongType():
326 return ['long', 'long']
327
328 def LongType():
329 return 'long'
330
331 def IntType():
332 return 'int'
333
334 def ByteType():
335 return 'byte'
336
337 def OctetType():
338 return 'octet'
339
340 def BooleanType():
341 return 'boolean'
342
343 def FloatType():
344 return 'float'
345
346 def DoubleType():
347 return 'double'
348
349 def _ScopedNames():
350 return MANY(ScopedName, separator=',')
351
352 def ScopedName():
353 return re.compile(r'[\w\_\:\.\<\>]+')
354
355 # Extended Attributes:
356 def ExtAttrs():
357 return ['[', MAYBE(MANY(ExtAttr, ',')), ']']
358
359 def ExtAttr():
360 return [Id, MAYBE(OR(['=', ExtAttrValue], ExtAttrArgList))]
361
362 def ExtAttrValue():
363 return OR(ExtAttrFunctionValue, re.compile(r'[\w&0-9:\-\| ]+'))
364
365 def ExtAttrFunctionValue():
366 return [Id, ExtAttrArgList]
367
368 def ExtAttrArgList():
369 return ['(', MAYBE(MANY(Argument, ',')), ')']
370
371 # Annotations - used in the FremontCut IDL grammar:
372 def _Annotations():
373 return MANY(Annotation)
374
375 def Annotation():
376 return ['@', Id, MAYBE(_AnnotationBody)]
377
378 def _AnnotationBody():
379 return ['(', MAYBE(MANY(AnnotationArg, ',')), ')']
380
381 def AnnotationArg():
382 return [Id, MAYBE(['=', AnnotationArgValue])]
383
384 def AnnotationArgValue():
385 return re.compile(r'[\w&0-9:/\-\.]+')
386
387 ###################### END GRAMMAR #####################
388
389 # Return the grammar's root rule:
390 return MANY(_Definition)
391
392 def _whitespace_grammar(self):
393 return OR(re.compile(r'\s+'),
394 re.compile(r'//.*'),
395 re.compile(r'#.*'),
396 re.compile(r'/\*.*?\*/', re.S))
397
398 def _pre_process(self, content, defines, includePaths):
399 """Pre-processes the content using gcc.
400
401 WebKit IDLs require pre-processing by gcc. This is done by invoking
402 gcc in a sub-process and capturing the results.
403
404 Returns:
405 The result of running gcc on the content.
406
407 Args:
408 content -- text to process.
409 defines -- an array of pre-processor defines.
410 includePaths -- an array of path strings.
411 """
412 # FIXME: Handle gcc not found, or any other processing errors
413 gcc = 'gcc'
414 cmd = [gcc, '-E', '-P', '-C', '-x', 'c++']
415 for define in defines:
416 cmd.append('-D%s' % define)
417 cmd.append('-')
418 pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
419 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
420 (content, stderr) = pipe.communicate(content)
421 return content
422
423 def parse(self, content, defines=[], includePaths=[]):
424 """Parse the give content string.
425
426 The WebKit IDL syntax also allows gcc pre-processing instructions.
427 Lists of defined variables and include paths can be provided.
428
429 Returns:
430 An abstract syntax tree (AST).
431
432 Args:
433 content -- text to parse.
434 defines -- an array of pre-processor defines.
435 includePaths -- an array of path strings used by the
436 gcc pre-processor.
437 """
438 if self._syntax == WEBKIT_SYNTAX:
439 content = self._pre_process(content, defines, includePaths)
440
441 return self._pegparser.parse(content)
OLDNEW
« no previous file with comments | « sdk/lib/html/scripts/idlparser.dart ('k') | sdk/lib/html/scripts/idlparser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698