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

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

Issue 8404031: IDL parser (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add copyright Created 9 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 | « no previous file | client/dom/scripts/idlparser_test.dart » ('j') | utils/peg/pegparser.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 // IDL grammar variants.
6 final int WEBIDL_SYNTAX = 0;
7 final int WEBKIT_SYNTAX = 1;
8 final int FREMONTCUT_SYNTAX = 2;
Jennifer Messerly 2011/10/28 01:21:10 new name for this?
9
10 /**
11 * IDLFile is the top-level node in each IDL file. It may contain modules or
12 * interfaces.
13 */
14 class IDLFile extends IDLNode {
15
16 String filename;
17 List<IDLModule> modules;
18 List<IDLInterface> interfaces;
19
20 IDLFile(this.filename, this.modules, this.interfaces);
21 }
22
23 /**
24 * IDLModule has an id, and may contain interfaces, type defs andimplements
25 * statements.
26 */
27 class IDLModule extends IDLNode {
28 String id;
29 List interfaces;
30 List typedefs;
31 List implementsStatements;
32
33 IDLModule(String this.id, IDLExtAttrs extAttrs, IDLAnnotations annotations,
34 List<IDLNode> elements) {
35 setExtAttrs(extAttrs);
36 this.annotations = annotations;
Jennifer Messerly 2011/10/28 01:21:10 you can use "this.annotations" in the arg list
37 this.interfaces = elements.filter((e) => e is IDLInterface);
Jennifer Messerly 2011/10/28 01:21:10 shouldn't need "this."
38 this.typedefs = elements.filter((e) => e is IDLTypeDef);
39 this.implementsStatements =
40 elements.filter((e) => e is IDLImplementsStatement);
41 }
42
43 toString() => '<IDLModule $id $extAttrs $annotations>';
44 }
45
46 class IDLNode {
47 IDLExtAttrs extAttrs;
48 IDLAnnotations annotations;
49 IDLNode();
50
51 setExtAttrs(IDLExtAttrs ea) {
52 assert(ea != null);
53 this.extAttrs = ea != null ? ea : new IDLExtAttrs();
54 }
Jennifer Messerly 2011/10/28 01:21:10 indent +2
sra1 2011/10/28 05:06:25 Done.
55 }
56
57 class IDLType extends IDLNode {
58 String id;
59 IDLType parameter;
60 bool nullable = false;
61 IDLType(String this.id, [IDLType this.parameter, bool this.nullable = false]);
62 //IDLType.nullable(IDLType base) {
Jennifer Messerly 2011/10/28 01:21:10 remove or add TODO?
sra1 2011/10/28 05:06:25 Done.
63 // print('IDLType.nullable($base)');
64 // return new IDLType(base.id, base.parameter, true);
65 //}
66
67 //String toString() => '<IDLType $nullable $id $parameter>';
68 String toString() {
69 String nullableTag = nullable ? '?' : '';
70 return '<IDLType $id${parameter == null ? '' : ' $parameter'}$nullableTag>';
71 }
72 }
73
74 class IDLTypeDef extends IDLNode {
75 String id;
76 IDLType type;
77 IDLTypeDef(String this.id, IDLType this.type);
78
79 toString() => '<IDLTypeDef $id $type>';
80 }
81
82 class IDLImplementsStatement extends IDLNode {
83 }
84
85 class IDLInterface extends IDLNode {
86 String id;
87 List parents;
88 List operations;
89 List attributes;
90 List constants;
91 List snippets;
92
93 bool isSupplemental;
94 bool isNoInterfaceObject;
95 bool isFcSuppressed;
96
97 IDLInterface(String this.id, IDLExtAttrs ea, IDLAnnotations ann,
98 List this.parents, List members) {
99 setExtAttrs(ea);
100 this.annotations = ann;
101 if (this.parents == null) this.parents = [];
102
103 operations = members.filter((e) => e is IDLOperation);
104 attributes = members.filter((e) => e is IDLAttribute);
105 constants = members.filter((e) => e is IDLConstant);
106 snippets = members.filter((e) => e is IDLSnippet);
107
108 isSupplemental = extAttrs.has('Supplemental');
109 isNoInterfaceObject = extAttrs.has('NoInterfaceObject');
110 isFcSuppressed = extAttrs.has('Suppressed');
111 }
112
113 toString() => '<IDLInterface $id $extAttrs $annotations>';
114 }
115
116 class IDLMember extends IDLNode {
117 String id;
118 IDLType type;
119 bool isFcSuppressed;
120
121 IDLMember(String this.id, IDLType this.type, IDLExtAttrs ea, IDLAnnotations an n) {
122 setExtAttrs(ea);
123 this.annotations = ann;
124
125 isFcSuppressed = extAttrs.has('Suppressed');
126 }
127 }
128
129 class IDLOperation extends IDLMember {
130 List arguments;
131
132 // Ignore all forms of raises for now.
133 List specials;
134 bool isStringifier;
135
136 IDLOperation(String id, IDLType type, IDLExtAttrs ea, IDLAnnotations ann,
137 List this.arguments, List this.specials, bool this.isStringifier)
138 : super(id, type, ea, ann) {
139 }
140
141 toString() => '<IDLOperation $type $id ${printList(arguments)}>';
142 }
143
144 class IDLAttribute extends IDLMember {
145 }
146
147 class IDLConstant extends IDLMember {
148 var value;
149 IDLConstant(String id, IDLType type, IDLExtAttrs ea, IDLAnnotations ann,
150 var this.value)
151 : super(id, type, ea, ann);
152 }
153
154 class IDLSnippet extends IDLMember {
155 String text;
156 IDLSnippet(IDLAnnotations ann, String this.text)
157 : super(null, null, new IDLExtAttrs(), ann);
158 }
159
160 /** Maps string to something. */
161 class IDLDictNode {
162 Map<String, Object> map;
163 IDLDictNode() {
164 map = new Map<String, Object>();
165 }
166
167 setMap(List associationList) {
168 if (associationList == null) return;
169 for (var element in associationList) {
170 var name = element[0];
171 var value = element[1];
172 map[name] = value;
173 }
174 }
175
176 bool has(String key) => map.containsKey(key);
177
178 formatMap() {
179 if (map.isEmpty())
180 return '';
181 StringBuffer sb = new StringBuffer();
182 map.forEach((k, v) {
183 sb.add(' $k');
184 if (v != null) {
185 sb.add('=$v');
186 }
187 });
188 return sb.toString();
189 }
190
191 }
192
193 class IDLExtAttrs extends IDLDictNode {
194 IDLExtAttrs([List attrs = const []]) {
195 setMap(attrs);
196 }
197
198 toString() => '<IDLExtAttrs${formatMap()}>';
199 }
200
201 class IDLArgument extends IDLNode {
202 String id;
203 IDLType type;
204 bool isOptional;
205 bool isIn;
206 bool hasElipsis;
207 IDLArgument(String this.id, IDLType this.type, IDLExtAttrs extAttrs,
208 bool this.isOptional, bool this.isIn, bool this.hasElipsis) {
209 setExtAttrs(extAttrs);
210 }
211
212 toString() => '<IDLArgument $id>';
213 }
214
215 class IDLAnnotations extends IDLDictNode {
216 IDLAnnotations(List annotations) {
217 for (var annotation in annotations) {
218 map[annotation.id] = annotation;
219 }
220 }
221
222 toString() => '<IDLAnnotations${formatMap()}>';
223 }
224
225 class IDLAnnotation extends IDLDictNode {
226 String id;
227 IDLAnnotation(String this.id, List args) {
228 setMap(args);
229 }
230
231 toString() => '<IDLAnnotation $id${formatMap()}>';
232 }
233
234 class IDLExtAttrFunctionValue extends IDLNode {
235 String name;
236 List arguments;
237 IDLExtAttrFunctionValue(String this.name, this.arguments);
238
239 toString() => '<IDLExtAttrFunctionValue $name(${arguments.length})>';
240 }
241
242 class IDLParentInterface extends IDLNode {}
243
244 ////////////////////////////////////////////////////////////////////////////////
245
246 class IDLParser {
247 final int syntax;
248 Grammar grammar;
249 var axiom;
250
251 IDLParser([syntax=WEBIDL_SYNTAX]) : syntax = syntax {
252 grammar = new Grammar();
253 axiom = _makeParser();
254 }
255
256 _makeParser() {
257 Grammar g = grammar;
258
259 syntax_switch([WebIDL, WebKit, FremontCut]) {
260 assert(WebIDL != null && WebKit != null); // Not options, just want names .
261 if (syntax == WEBIDL_SYNTAX)
262 return WebIDL;
263 if (syntax == WEBKIT_SYNTAX)
264 return WebKit;
265 if (syntax == FREMONTCUT_SYNTAX)
266 return FremontCut == null ? WebIDL : FremontCut;
267 throw new Exception('unsupported IDL syntax $syntax');
268 }
269
270 var idStartCharSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_' ;
271 var idNextCharSet = idStartCharSet + '0123456789';
272 var hexCharSet = '0123456789ABCDEFabcdef';
273
274 var idStartChar = CHAR(idStartCharSet);
275 var idNextChar = CHAR(idNextCharSet);
276
277 var digit = CHAR('0123456789');
278
279 var Id = TEXT(LEX('an identifier',[idStartChar, MANY(idNextChar, min:0)]));
280
281 var IN = SKIP(LEX("'in'", ['in',NOT(idNextChar)]));
282
283 var BooleanLiteral = OR(['true', 'false']);
284 var IntegerLiteral = TEXT(LEX('hex-literal', OR([['0x', MANY(CHAR(hexCharSet ))],
285 [MANY(digit)]])));
286 var FloatLiteral = TEXT(LEX('float-literal', [MANY(digit), '.', MANY(digit, min:0)]));
287
288
289 var Argument = g['Argument'];
290 var Module = g['Module'];
291 var Member = g['Member'];
292 var Interface = g['Interface'];
293 var ExceptionDef = g['ExceptionDef'];
294 var Type = g['Type'];
295 var TypeDef = g['TypeDef'];
296 var ImplStmt = g['ImplStmt'];
297 var ValueTypeDef = g['ValueTypeDef'];
298 var Const = g['Const'];
299 var Attribute = g['Attribute'];
300 var Operation = g['Operation'];
301 var Snippet = g['Snippet'];
302 var ExtAttrs = g['ExtAttrs'];
303 var MaybeExtAttrs = g['MaybeExtAttrs'];
304 var MaybeAnnotations = g['MaybeAnnotations'];
305 var ParentInterfaces = g['ParentInterfaces'];
306
307
308 final ScopedName = TEXT(LEX('scoped-name', MANY(CHAR(idStartCharSet + '_:.<> '))));
309
310 final ScopedNames = MANY(ScopedName, separator:',');
311
312 // Types
313
314 final IntegerTypeName = OR([
315 ['byte', () => 'byte'],
316 ['int', () => 'int'],
317 ['long', 'long', () => 'long long'],
318 ['long', () => 'long'],
319 ['octet', () => 'octet'],
320 ['short', () => 'short']]);
321
322 final IntegerType = OR([
323 ['unsigned', IntegerTypeName, (name) => new IDLType('unsigned $name')],
324 [IntegerTypeName, (name) => new IDLType(name)]]);
325
326 final BooleanType = ['boolean', () => new IDLType('boolean')];
327 final OctetType = ['octet', () => new IDLType('octet')];
328 final FloatType = ['float', () => new IDLType('float')];
329 final DoubleType = ['double', () => new IDLType('double')];
330
331 final SequenceType = ['sequence', '<', Type, '>',
332 (type) => new IDLType('sequence', type)];
333
334 final ScopedNameType = [ScopedName, (name) => new IDLType(name)];
335
336 final NullableType =
337 [OR([IntegerType, BooleanType, OctetType, FloatType,
338 DoubleType, SequenceType, ScopedNameType]),
339 MAYBE('?'),
340 (type, nullable) =>
341 nullable ? new IDLType(type.id, type.parameter, true) : type];
342
343 final VoidType = ['void', () => new IDLType('void')];
344 final AnyType = ['any', () => new IDLType('any')];
345 final ObjectType = ['object', () => new IDLType('object')];
346
347 Type.def = OR([AnyType, ObjectType, NullableType]);
348
349 final ReturnType = OR([VoidType, Type]);
350
351 var Definition = syntax_switch(
352 WebIDL: OR([Module, Interface, ExceptionDef, TypeDef, ImplStmt,
353 ValueTypeDef, Const]),
354 WebKit: OR([Module, Interface]));
355
356 var Definitions = MANY(Definition, min:0);
357
358 Module.def = syntax_switch(
359 WebIDL: [MaybeExtAttrs, 'module', Id, '{', Definitions, '}',
360 SKIP(MAYBE(';')),
361 (ea, id, defs) => new IDLModule(id, ea, null, defs)],
362 WebKit: ['module', MaybeExtAttrs, Id, '{', Definitions, '}',
363 SKIP(MAYBE(';')),
364 (ea, id, defs) => new IDLModule(id, ea, null, defs)],
365 FremontCut: [MaybeAnnotations, MaybeExtAttrs, 'module', Id,
366 '{', Definitions, '}', SKIP(MAYBE(';')),
367 (ann, ea, id, defs) => new IDLModule(id, ea, ann, defs)]);
368
369 Interface.def = syntax_switch(
370 WebIDL: [MaybeExtAttrs, 'interface', Id, MAYBE(ParentInterfaces),
371 MAYBE(['{', MANY0(Member), '}']), ';',
372 (ea, id, p, ms) => new IDLInterface(id, ea, null, p, ms)],
373 WebKit: ['interface', MaybeExtAttrs, Id, MAYBE(ParentInterfaces),
374 MAYBE(['{', MANY0(Member), '}']), ';',
375 (ea, id, p, ms) => new IDLInterface(id, ea, null, p, ms)],
376 FremontCut: [MaybeAnnotations, MaybeExtAttrs, 'interface',
377 Id, MAYBE(ParentInterfaces),
378 MAYBE(['{', MANY0(Member), '}']), ';',
379 (ann, ea, id, p, ms) => new IDLInterface(id, ea, ann, p, ms )]);
380
381 Member.def = syntax_switch(
382 WebIDL: OR([Const, Attribute, Operation, ExtAttrs]),
383 WebKit: OR([Const, Attribute, Operation]),
384 FremontCut: OR([Const, Attribute, Operation, Snippet]));
385
386 var InterfaceType = ScopedName;
387
388 var ParentInterface = syntax_switch(
389 WebIDL: [InterfaceType],
390 WebKit: [InterfaceType],
391 FremontCut: [MaybeAnnotations, InterfaceType]);
392
393 ParentInterfaces.def = [':', MANY(ParentInterface, ',')];
394
395 // TypeDef (Web IDL):
396 TypeDef.def = ['typedef', Type, Id, ';', (type, id) => new IDLTypeDef(id, ty pe)];
397
398 // TypeDef (Old-school W3C IDLs)
399 ValueTypeDef.def = ['valuetype', Id, Type, ';'];
400
401 // Implements Statement (Web IDL):
402 var ImplStmtImplementor = ScopedName;
403 var ImplStmtImplemented = ScopedName;
404
405 ImplStmt.def = [ImplStmtImplementor, 'implements', ImplStmtImplemented, ';'] ;
406
407 var ConstExpr = OR([BooleanLiteral, IntegerLiteral, FloatLiteral]);
408
409 Const.def = syntax_switch(
410 WebIDL: [MaybeExtAttrs, 'const', Type, Id, '=', ConstExpr, ';',
411 (ea, type, id, v) => new IDLConstant(id, type, ea, null, v)],
412 WebKit: ['const', MaybeExtAttrs, Type, Id, '=', ConstExpr, ';',
413 (ea, type, id, v) => new IDLConstant(id, type, ea, null, v)],
414 FremontCut: [MaybeAnnotations, MaybeExtAttrs,
415 'const', Type, Id, '=', ConstExpr, ';',
416 (ann, ea, type, id, v) =>
417 new IDLConstant(id, type, ea, ann, v)]);
418
419 // Attributes
420
421 var Stringifier = 'stringifier';
422 var AttrGetter = 'getter';
423 var AttrSetter = 'setter';
424 var ReadOnly = 'readonly';
425 var AttrGetterSetter = OR([AttrGetter, AttrSetter]);
426
427 var GetRaises = syntax_switch(
428 WebIDL: ['getraises', '(', ScopedNames, ')'],
429 WebKit: ['getter', 'raises', '(', ScopedNames, ')']);
430
431 var SetRaises = syntax_switch(
432 WebIDL: ['setraises', '(', ScopedNames, ')'],
433 WebKit: ['setter', 'raises', '(', ScopedNames, ')']);
434
435 var Raises = ['raises', '(', ScopedNames, ')'];
436
437 var AttrRaises = syntax_switch(
438 WebIDL: MANY(OR([GetRaises, SetRaises])),
439 WebKit: MANY(OR([GetRaises, SetRaises, Raises]), separator:','));
440
441 Attribute.def = syntax_switch(
442 WebIDL: [MaybeExtAttrs, MAYBE(Stringifier), MAYBE(ReadOnly),
443 'attribute', Type, Id, MAYBE(AttrRaises), ';'],
444 WebKit: [MAYBE(Stringifier), MAYBE(ReadOnly), 'attribute',
445 MaybeExtAttrs, Type, Id, MAYBE(AttrRaises), ';'],
446 FremontCut: [MaybeAnnotations, MaybeExtAttrs,
447 MAYBE(AttrGetterSetter), MAYBE(Stringifier), MAYBE(ReadOnly ),
448 'attribute', Type, Id, MAYBE(AttrRaises), ';'
449 ]);
450
451 // Operations
452
453 final Special = TEXT(OR(['getter', 'setter', 'creator', 'deleter', 'caller'] ));
454 final Specials = MANY(Special);
455
456 final Optional = 'optional';
457 final AnEllipsis = '...';
458
459 Argument.def = syntax_switch(
460 WebIDL: SEQ(MaybeExtAttrs, MAYBE(Optional), MAYBE(IN),
461 MAYBE(Optional), Type, MAYBE(AnEllipsis), Id,
462 (e, opt1, isin, opt2, type, el, id) =>
463 new IDLArgument(id, type, e, opt1 || opt2, isin, el)),
464
465 WebKit: SEQ(MAYBE(Optional), MAYBE('in'), MAYBE(Optional),
466 MaybeExtAttrs, Type, Id
467 (opt1, isin, opt2, e, type, id) =>
468 new IDLArgument(id, type, e, opt1 || opt2, isin, false)) );
469
470 final Arguments = MANY0(Argument, ',');
471
472 Operation.def = syntax_switch(
473 WebIDL: [MaybeExtAttrs, MAYBE(Stringifier), MAYBE(Specials),
474 ReturnType, MAYBE(Id), '(', Arguments, ')', MAYBE(Raises), ';',
475 (ea, isStringifier, specials, type, id, args, raises) =>
476 new IDLOperation(id, type, ea, null, args, specials, isStri ngifier)
477 ],
478 WebKit: [MaybeExtAttrs, ReturnType, MAYBE(Id), '(', Arguments, ')',
479 MAYBE(Raises), ';',
480 (ea, type, id, args, raises) =>
481 new IDLOperation(id, type, ea, null, args, [], false)
482 ],
483 FremontCut: [MaybeAnnotations, MaybeExtAttrs, MAYBE(Stringifier),
484 MAYBE(Specials), ReturnType, MAYBE(Id), '(', Arguments, ')' ,
485 MAYBE(Raises), ';',
486 (ann, ea, isStringifier, specials, type, id, args, raises) =>
487 new IDLOperation(id, type, ea, ann, args, specials, isStr ingifier)
488 ]);
489
490 // Exceptions
491
492 final ExceptionField = [Type, Id, ';'];
493 final ExceptionMember = OR([Const, ExceptionField, ExtAttrs]);
494 ExceptionDef.def = ['exception', Id, '{', MANY0(ExceptionMember), '}', ';'];
495
496 // ExtendedAttributes
497
498 var ExtAttrArgList = ['(', MANY0(Argument, ','), ')'];
499
500 var ExtAttrFunctionValue =
501 [Id, '(', MANY0(Argument, ','), ')',
502 (name, args) => new IDLExtAttrFunctionValue(name, args)
503 ];
504
505 var ExtAttrValue = OR([ExtAttrFunctionValue,
506 TEXT(LEX('value', MANY(CHAR(idNextCharSet + '&:-|'))) )]);
507
508 var ExtAttr = [Id, MAYBE(OR([['=', ExtAttrValue], ExtAttrArgList]))];
509
510 ExtAttrs.def = ['[', MANY(ExtAttr, ','), ']',
511 (list) => new IDLExtAttrs(list)];;
512
513 MaybeExtAttrs.def = OR(ExtAttrs,
514 [ () => new IDLExtAttrs() ] );
515
516 // Annotations - used in the FremontCut IDL grammar.
517
518 var AnnotationArgValue = TEXT(LEX('xx', MANY(CHAR(idNextCharSet + '&:-|')))) ;
519
520 var AnnotationArg = [Id, MAYBE(['=', AnnotationArgValue])];
521
522 var AnnotationBody = ['(', MANY0(AnnotationArg, ','), ')'];
523
524 var Annotation = ['@', Id, MAYBE(AnnotationBody),
525 (id, body) => new IDLAnnotation(id, body)];
526
527 MaybeAnnotations.def = [MANY0(Annotation), (list) => new IDLAnnotations(list )];
528
529 // Snippets - used in the FremontCut IDL grammar.
530
531 final SnippetText = TEXT(LEX('snippet body', MANY0([NOT('}'), CHAR()])));
532 Snippet.def = [MaybeAnnotations, 'snippet', '{', SnippetText, '}', ';',
533 (ann, text) => new IDLSnippet(ann, text)];
534
535
536 grammar.whitespace =
537 OR([MANY(CHAR(' \t\r\n')),
538 ['//', MANY0([NOT(CHAR('\r\n')), CHAR()])],
539 ['#', MANY0([NOT(CHAR('\r\n')), CHAR()])],
540 ['/*', MANY0([NOT('*/'), CHAR()]), '*/']]);
541
542 // Top level - at least one definition.
543 return MANY(Definition);
544
545 }
546 }
OLDNEW
« no previous file with comments | « no previous file | client/dom/scripts/idlparser_test.dart » ('j') | utils/peg/pegparser.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698