DOM4: Add support for rest parameters to DOMTokenList
[WebKit.git] / Source / WebCore / bindings / scripts / IDLParser.pm
1
2 # KDOM IDL parser
3 #
4 # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
5
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Library General Public
8 # License as published by the Free Software Foundation; either
9 # version 2 of the License, or (at your option) any later version.
10
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Library General Public License for more details.
15
16 # You should have received a copy of the GNU Library General Public License
17 # along with this library; see the file COPYING.LIB.  If not, write to
18 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 # Boston, MA 02110-1301, USA.
20
21
22 package IDLParser;
23
24 use Class::Struct;
25
26 use strict;
27
28 use IPC::Open2;
29 use IDLStructure;
30 use preprocessor;
31
32 use constant StringToken => 0;
33 use constant IntegerToken => 1;
34 use constant FloatToken => 2;
35 use constant IdentifierToken => 3;
36 use constant OtherToken => 4;
37 use constant EmptyToken => 5;
38
39 struct( Token => {
40     type => '$', # type of token
41     value => '$' # value of token
42 });
43
44 sub new {
45     my $class = shift;
46
47     my $emptyToken = Token->new();
48     $emptyToken->type(EmptyToken);
49     $emptyToken->value("empty");
50
51     my $self = {
52         DocumentContent => "",
53         EmptyToken => $emptyToken,
54         NextToken => $emptyToken,
55         Token => $emptyToken,
56         Line => "",
57         LineNumber => 1
58     };
59     return bless $self, $class;
60 }
61
62 sub assertTokenValue
63 {
64     my $self = shift;
65     my $token = shift;
66     my $value = shift;
67     my $line = shift;
68     my $msg = "Next token should be " . $value . ", but " . $token->value() . " at " . $self->{Line};
69     if (defined ($line)) {
70         $msg .= " IDLParser.pm:" . $line;
71     }
72     die $msg unless $token->value() eq $value;
73 }
74
75 sub assertTokenType
76 {
77     my $self = shift;
78     my $token = shift;
79     my $type = shift;
80     die "Next token's type should be " . $type . ", but " . $token->type() . " at " . $self->{Line} unless $token->type() eq $type;
81 }
82
83 sub assertUnexpectedToken
84 {
85     my $self = shift;
86     my $token = shift;
87     my $line = shift;
88     my $msg = "Unexpected token " . $token . " at " . $self->{Line};
89     if (defined ($line)) {
90         $msg .= " IDLParser.pm:" . $line;
91     }
92     die $msg;
93 }
94
95 sub Parse
96 {
97     my $self = shift;
98     my $fileName = shift;
99     my $defines = shift;
100     my $preprocessor = shift;
101
102     my @definitions = ();
103
104     my @lines = applyPreprocessor($fileName, $defines, $preprocessor);
105     $self->{Line} = $lines[0];
106     $self->{DocumentContent} = join(' ', @lines);
107
108     $self->getToken();
109     eval {
110         my $result = $self->parseDefinitions();
111         push(@definitions, @{$result});
112
113         my $next = $self->nextToken();
114         $self->assertTokenType($next, EmptyToken);
115     };
116     die $@ . " in $fileName" if $@;
117
118     die "No document found" unless @definitions;
119
120     my $document;
121     if ($#definitions == 0 && ref($definitions[0]) eq "idlDocument") {
122         $document = $definitions[0];
123     } else {
124         $document = new idlDocument();
125         $document->module("");
126         push(@{$document->classes}, @definitions);
127     }
128
129     $document->fileName($fileName);
130     return $document;
131 }
132
133 sub nextToken
134 {
135     my $self = shift;
136     return $self->{NextToken};
137 }
138
139 sub getToken
140 {
141     my $self = shift;
142     $self->{Token} = $self->{NextToken};
143     $self->{NextToken} = $self->getTokenInternal();
144     return $self->{Token};
145 }
146
147 my $whitespaceTokenPattern = '^[\t\n\r ]*[\n\r]';
148 my $floatTokenPattern = '^(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+))';
149 my $integerTokenPattern = '^(-?[1-9][0-9]*|-?0[Xx][0-9A-Fa-f]+|-?0[0-7]*)';
150 my $stringTokenPattern = '^(\"[^\"]*\")';
151 my $identifierTokenPattern = '^([A-Z_a-z][0-9A-Z_a-z]*)';
152 my $otherTokenPattern = '^(::|\.\.\.|[^\t\n\r 0-9A-Z_a-z])';
153
154 sub getTokenInternal
155 {
156     my $self = shift;
157
158     if ($self->{DocumentContent} =~ /$whitespaceTokenPattern/) {
159         $self->{DocumentContent} =~ s/($whitespaceTokenPattern)//;
160         my $skipped = $1;
161         $self->{LineNumber}++ while ($skipped =~ /\n/g);
162         if ($self->{DocumentContent} =~ /^([^\n\r]+)/) {
163             $self->{Line} = $self->{LineNumber} . ":" . $1;
164         } else {
165             $self->{Line} = "Unknown";
166         }
167     }
168     $self->{DocumentContent} =~ s/^([\t\n\r ]+)//;
169     if ($self->{DocumentContent} eq "") {
170         return $self->{EmptyToken};
171     }
172
173     my $token = Token->new();
174     if ($self->{DocumentContent} =~ /$floatTokenPattern/) {
175         $token->type(FloatToken);
176         $token->value($1);
177         $self->{DocumentContent} =~ s/$floatTokenPattern//;
178         return $token;
179     }
180     if ($self->{DocumentContent} =~ /$integerTokenPattern/) {
181         $token->type(IntegerToken);
182         $token->value($1);
183         $self->{DocumentContent} =~ s/$integerTokenPattern//;
184         return $token;
185     }
186     if ($self->{DocumentContent} =~ /$stringTokenPattern/) {
187         $token->type(StringToken);
188         $token->value($1);
189         $self->{DocumentContent} =~ s/$stringTokenPattern//;
190         return $token;
191     }
192     if ($self->{DocumentContent} =~ /$identifierTokenPattern/) {
193         $token->type(IdentifierToken);
194         $token->value($1);
195         $self->{DocumentContent} =~ s/$identifierTokenPattern//;
196         return $token;
197     }
198     if ($self->{DocumentContent} =~ /$otherTokenPattern/) {
199         $token->type(OtherToken);
200         $token->value($1);
201         $self->{DocumentContent} =~ s/$otherTokenPattern//;
202         return $token;
203     }
204     die "Failed in tokenizing at " . $self->{Line};
205 }
206
207 my $nextAttributeOld_1 = '^(attribute|inherit|readonly)$';
208 my $nextPrimitiveType_1 = '^(int|long|short|unsigned)$';
209 my $nextPrimitiveType_2 = '^(double|float|unrestricted)$';
210 my $nextSetGetRaises2_1 = '^(;|getraises|setraises)$';
211 my $nextArgumentList_1 = '^(\(|::|ByteString|DOMString|Date|\[|any|boolean|byte|double|float|in|int|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
212 my $nextNonAnyType_1 = '^(boolean|byte|double|float|int|long|octet|short|unrestricted|unsigned)$';
213 my $nextInterfaceMemberOld_1 = '^(\(|::|ByteString|DOMString|Date|any|attribute|boolean|byte|creator|deleter|double|float|getter|inherit|int|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
214 my $nextOptionalIteratorInterfaceOrObject_1 = '^(;|=)$';
215 my $nextAttributeOrOperationOrIterator_1 = '^(static|stringifier)$';
216 my $nextAttributeOrOperationOrIterator_2 = '^(\(|::|ByteString|DOMString|Date|any|boolean|byte|creator|deleter|double|float|getter|int|legacycaller|long|object|octet|sequence|setter|short|unrestricted|unsigned|void)$';
217 my $nextUnrestrictedFloatType_1 = '^(double|float)$';
218 my $nextExtendedAttributeRest3_1 = '^(\,|::|\])$';
219 my $nextExceptionField_1 = '^(\(|::|ByteString|DOMString|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
220 my $nextType_1 = '^(::|ByteString|DOMString|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
221 my $nextSpecials_1 = '^(creator|deleter|getter|legacycaller|setter)$';
222 my $nextDefinitions_1 = '^(::|callback|dictionary|enum|exception|interface|partial|typedef)$';
223 my $nextExceptionMembers_1 = '^(\(|::|ByteString|DOMString|Date|\[|any|boolean|byte|const|double|float|int|long|object|octet|optional|sequence|short|unrestricted|unsigned)$';
224 my $nextAttributeRest_1 = '^(attribute|readonly)$';
225 my $nextInterfaceMembers_1 = '^(\(|::|ByteString|DOMString|Date|any|attribute|boolean|byte|const|creator|deleter|double|float|getter|inherit|int|legacycaller|long|object|octet|readonly|sequence|serializer|setter|short|static|stringifier|unrestricted|unsigned|void)$';
226 my $nextSingleType_1 = '^(::|ByteString|DOMString|Date|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned)$';
227 my $nextGet_1 = '^(;|getraises|getter|setraises|setter)$';
228 my $nextArgumentName_1 = '^(attribute|callback|const|creator|deleter|dictionary|enum|exception|getter|implements|inherit|interface|legacycaller|partial|serializer|setter|static|stringifier|typedef|unrestricted)$';
229 my $nextConstValue_1 = '^(false|true)$';
230 my $nextConstValue_2 = '^(-|Infinity|NaN)$';
231 my $nextDefinition_1 = '^(callback|interface)$';
232 my $nextAttributeOrOperationRest_1 = '^(\(|::|ByteString|DOMString|Date|any|boolean|byte|double|float|int|long|object|octet|sequence|short|unrestricted|unsigned|void)$';
233 my $nextUnsignedIntegerType_1 = '^(int|long|short)$';
234 my $nextDefaultValue_1 = '^(-|Infinity|NaN|false|null|true)$';
235
236
237 sub parseDefinitions
238 {
239     my $self = shift;
240     my @definitions = ();
241
242     while (1) {
243         my $next = $self->nextToken();
244         my $definition;
245         if ($next->value() eq "[") {
246             my $extendedAttributeList = $self->parseExtendedAttributeList();
247             $definition = $self->parseDefinition($extendedAttributeList);
248         } elsif ($next->type() == IdentifierToken || $next->value() =~ /$nextDefinitions_1/) {
249             $definition = $self->parseDefinitionOld();
250         } else {
251             last;
252         }
253         if (defined ($definition)) {
254             push(@definitions, $definition);
255         }
256     }
257     return \@definitions;
258 }
259
260 sub parseDefinition
261 {
262     my $self = shift;
263     my $extendedAttributeList = shift;
264
265     my $next = $self->nextToken();
266     if ($next->value() =~ /$nextDefinition_1/) {
267         return $self->parseCallbackOrInterface($extendedAttributeList);
268     }
269     if ($next->value() eq "partial") {
270         return $self->parsePartial($extendedAttributeList);
271     }
272     if ($next->value() eq "dictionary") {
273         return $self->parseDictionary($extendedAttributeList);
274     }
275     if ($next->value() eq "exception") {
276         return $self->parseException($extendedAttributeList);
277     }
278     if ($next->value() eq "enum") {
279         return $self->parseEnum($extendedAttributeList);
280     }
281     if ($next->value() eq "typedef") {
282         return $self->parseTypedef($extendedAttributeList);
283     }
284     if ($next->type() == IdentifierToken || $next->value() eq "::") {
285         return $self->parseImplementsStatement($extendedAttributeList);
286     }
287     $self->assertUnexpectedToken($next->value(), __LINE__);
288 }
289
290 sub parseCallbackOrInterface
291 {
292     my $self = shift;
293     my $extendedAttributeList = shift;
294
295     my $next = $self->nextToken();
296     if ($next->value() eq "callback") {
297         $self->assertTokenValue($self->getToken(), "callback", __LINE__);
298         return $self->parseCallbackRestOrInterface($extendedAttributeList);
299     }
300     if ($next->value() eq "interface") {
301         return $self->parseInterface($extendedAttributeList);
302     }
303     $self->assertUnexpectedToken($next->value(), __LINE__);
304 }
305
306 sub parseCallbackRestOrInterface
307 {
308     my $self = shift;
309     my $extendedAttributeList = shift;
310
311     my $next = $self->nextToken();
312     if ($next->value() eq "interface") {
313         return $self->parseInterface($extendedAttributeList);
314     }
315     if ($next->type() == IdentifierToken) {
316         return $self->parseCallbackRest($extendedAttributeList);
317     }
318     $self->assertUnexpectedToken($next->value(), __LINE__);
319 }
320
321 sub parseInterface
322 {
323     my $self = shift;
324     my $extendedAttributeList = shift;
325
326     my $next = $self->nextToken();
327     if ($next->value() eq "interface") {
328         my $dataNode = new domClass();
329         $self->assertTokenValue($self->getToken(), "interface", __LINE__);
330         my $interfaceNameToken = $self->getToken();
331         $self->assertTokenType($interfaceNameToken, IdentifierToken);
332         $dataNode->name($interfaceNameToken->value());
333         push(@{$dataNode->parents}, @{$self->parseInheritance()});
334         $self->assertTokenValue($self->getToken(), "{", __LINE__);
335         my $interfaceMembers = $self->parseInterfaceMembers();
336         $self->assertTokenValue($self->getToken(), "}", __LINE__);
337         $self->assertTokenValue($self->getToken(), ";", __LINE__);
338         applyMemberList($dataNode, $interfaceMembers);
339         applyExtendedAttributeList($dataNode, $extendedAttributeList);
340         return $dataNode;
341     }
342     $self->assertUnexpectedToken($next->value(), __LINE__);
343 }
344
345 sub parsePartial
346 {
347     my $self = shift;
348     my $extendedAttributeList = shift;
349
350     my $next = $self->nextToken();
351     if ($next->value() eq "partial") {
352         $self->assertTokenValue($self->getToken(), "partial", __LINE__);
353         return $self->parsePartialDefinition($extendedAttributeList);
354     }
355     $self->assertUnexpectedToken($next->value(), __LINE__);
356 }
357
358 sub parsePartialDefinition
359 {
360     my $self = shift;
361     my $extendedAttributeList = shift;
362
363     my $next = $self->nextToken();
364     if ($next->value() eq "interface") {
365         return $self->parsePartialInterface($extendedAttributeList);
366     }
367     if ($next->value() eq "dictionary") {
368         return $self->parsePartialDictionary($extendedAttributeList);
369     }
370     $self->assertUnexpectedToken($next->value(), __LINE__);
371 }
372
373 sub parsePartialInterface
374 {
375     my $self = shift;
376     my $extendedAttributeList = shift;
377
378     my $next = $self->nextToken();
379     if ($next->value() eq "interface") {
380         $self->assertTokenValue($self->getToken(), "interface", __LINE__);
381         $self->assertTokenType($self->getToken(), IdentifierToken);
382         $self->assertTokenValue($self->getToken(), "{", __LINE__);
383         $self->parseInterfaceMembers();
384         $self->assertTokenValue($self->getToken(), "}", __LINE__);
385         $self->assertTokenValue($self->getToken(), ";", __LINE__);
386         return;
387     }
388     $self->assertUnexpectedToken($next->value(), __LINE__);
389 }
390
391 sub parseInterfaceMembers
392 {
393     my $self = shift;
394     my @interfaceMembers = ();
395
396     while (1) {
397         my $next = $self->nextToken();
398         my $interfaceMember;
399
400         if ($next->value() eq "[") {
401             my $extendedAttributeList = $self->parseExtendedAttributeList();
402             $interfaceMember = $self->parseInterfaceMember($extendedAttributeList);
403         } elsif ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMembers_1/) {
404             $interfaceMember = $self->parseInterfaceMemberOld();
405         } else {
406             last;
407         }
408         if (defined $interfaceMember) {
409             push(@interfaceMembers, $interfaceMember);
410         }
411     }
412     return \@interfaceMembers;
413 }
414
415 sub parseInterfaceMember
416 {
417     my $self = shift;
418     my $extendedAttributeList = shift;
419
420     my $next = $self->nextToken();
421     if ($next->value() eq "const") {
422         return $self->parseConst($extendedAttributeList);
423     }
424     if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMemberOld_1/) {
425         return $self->parseAttributeOrOperationOrIterator($extendedAttributeList);
426     }
427     $self->assertUnexpectedToken($next->value(), __LINE__);
428 }
429
430 sub parseDictionary
431 {
432     my $self = shift;
433     my $extendedAttributeList = shift;
434
435     my $next = $self->nextToken();
436     if ($next->value() eq "dictionary") {
437         $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
438         $self->assertTokenType($self->getToken(), IdentifierToken);
439         $self->parseInheritance();
440         $self->assertTokenValue($self->getToken(), "{", __LINE__);
441         $self->parseDictionaryMembers();
442         $self->assertTokenValue($self->getToken(), "}", __LINE__);
443         $self->assertTokenValue($self->getToken(), ";", __LINE__);
444         return;
445     }
446     $self->assertUnexpectedToken($next->value(), __LINE__);
447 }
448
449 sub parseDictionaryMembers
450 {
451     my $self = shift;
452
453     while (1) {
454         my $next = $self->nextToken();
455         if ($next->value() eq "[") {
456             my $extendedAttributeList = $self->parseExtendedAttributeList();
457             $self->parseDictionaryMember($extendedAttributeList);
458         } elsif ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
459             $self->parseDictionaryMemberOld();
460         } else {
461             last;
462         }
463     }
464 }
465
466 sub parseDictionaryMember
467 {
468     my $self = shift;
469     my $extendedAttributeList = shift;
470
471     my $next = $self->nextToken();
472     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
473         $self->parseType();
474         $self->assertTokenType($self->getToken(), IdentifierToken);
475         $self->parseDefault();
476         $self->assertTokenValue($self->getToken(), ";", __LINE__);
477         return;
478     }
479     $self->assertUnexpectedToken($next->value(), __LINE__);
480 }
481
482 sub parsePartialDictionary
483 {
484     my $self = shift;
485     my $next = $self->nextToken();
486     if ($next->value() eq "dictionary") {
487         $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
488         $self->assertTokenType($self->getToken(), IdentifierToken);
489         $self->assertTokenValue($self->getToken(), "{", __LINE__);
490         $self->parseDictionaryMembers();
491         $self->assertTokenValue($self->getToken(), "}", __LINE__);
492         $self->assertTokenValue($self->getToken(), ";", __LINE__);
493         return;
494     }
495     $self->assertUnexpectedToken($next->value(), __LINE__);
496 }
497
498 sub parseDefault
499 {
500     my $self = shift;
501     my $next = $self->nextToken();
502     if ($next->value() eq "=") {
503         $self->assertTokenValue($self->getToken(), "=", __LINE__);
504         return $self->parseDefaultValue();
505     }
506 }
507
508 sub parseDefaultValue
509 {
510     my $self = shift;
511     my $next = $self->nextToken();
512     if ($next->type() == FloatToken || $next->type() == IntegerToken || $next->value() =~ /$nextDefaultValue_1/) {
513         return $self->parseConstValue();
514     }
515     if ($next->type() == StringToken) {
516         return $self->getToken()->value();
517     }
518     $self->assertUnexpectedToken($next->value(), __LINE__);
519 }
520
521 sub parseException
522 {
523     my $self = shift;
524     my $extendedAttributeList = shift;
525
526     my $next = $self->nextToken();
527     if ($next->value() eq "exception") {
528         my $dataNode = new domClass();
529         $self->assertTokenValue($self->getToken(), "exception", __LINE__);
530         my $exceptionNameToken = $self->getToken();
531         $self->assertTokenType($exceptionNameToken, IdentifierToken);
532         $dataNode->name($exceptionNameToken->value());
533         $dataNode->isException(1);
534         push(@{$dataNode->parents}, @{$self->parseInheritance()});
535         $self->assertTokenValue($self->getToken(), "{", __LINE__);
536         my $exceptionMembers = $self->parseExceptionMembers();
537         $self->assertTokenValue($self->getToken(), "}", __LINE__);
538         $self->assertTokenValue($self->getToken(), ";", __LINE__);
539         applyMemberList($dataNode, $exceptionMembers);
540         applyExtendedAttributeList($dataNode, $extendedAttributeList);
541         return $dataNode;
542     }
543     $self->assertUnexpectedToken($next->value(), __LINE__);
544 }
545
546 sub parseExceptionMembers
547 {
548     my $self = shift;
549     my @members = ();
550
551     while (1) {
552         my $next = $self->nextToken();
553         if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionMembers_1/) {
554             my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
555             #my $member = $self->parseExceptionMember($extendedAttributeList);
556             my $member = $self->parseInterfaceMember($extendedAttributeList);
557             if (defined ($member)) {
558                 push(@members, $member);
559             }
560         } else {
561             last;
562         }
563     }
564     return \@members;
565 }
566
567 sub parseInheritance
568 {
569     my $self = shift;
570     my @parent = ();
571
572     my $next = $self->nextToken();
573     if ($next->value() eq ":") {
574         $self->assertTokenValue($self->getToken(), ":", __LINE__);
575         my $scopedName = $self->parseScopedName();
576         push(@parent, $scopedName);
577         # Multiple inheritance?
578         push(@parent, @{$self->parseIdentifiers()});
579     }
580     return \@parent;
581 }
582
583 sub parseEnum
584 {
585     my $self = shift;
586     my $extendedAttributeList = shift;
587
588     my $next = $self->nextToken();
589     if ($next->value() eq "enum") {
590         $self->assertTokenValue($self->getToken(), "enum", __LINE__);
591         $self->assertTokenType($self->getToken(), IdentifierToken);
592         $self->assertTokenValue($self->getToken(), "{", __LINE__);
593         $self->parseEnumValueList();
594         $self->assertTokenValue($self->getToken(), "}", __LINE__);
595         $self->assertTokenValue($self->getToken(), ";", __LINE__);
596         return;
597     }
598     $self->assertUnexpectedToken($next->value(), __LINE__);
599 }
600
601 sub parseEnumValueList
602 {
603     my $self = shift;
604     my $next = $self->nextToken();
605     if ($next->type() == StringToken) {
606         $self->assertTokenType($self->getToken(), StringToken);
607         $self->parseEnumValues();
608         return;
609     }
610     $self->assertUnexpectedToken($next->value(), __LINE__);
611 }
612
613 sub parseEnumValues
614 {
615     my $self = shift;
616     my $next = $self->nextToken();
617     if ($next->value() eq ",") {
618         $self->assertTokenValue($self->getToken(), ",", __LINE__);
619         $self->assertTokenType($self->getToken(), StringToken);
620         $self->parseEnumValues();
621     }
622 }
623
624 sub parseCallbackRest
625 {
626     my $self = shift;
627     my $extendedAttributeList = shift;
628
629     my $next = $self->nextToken();
630     if ($next->type() == IdentifierToken) {
631         $self->assertTokenType($self->getToken(), IdentifierToken);
632         $self->assertTokenValue($self->getToken(), "=", __LINE__);
633         $self->parseReturnType();
634         $self->assertTokenValue($self->getToken(), "(", __LINE__);
635         $self->parseArgumentList();
636         $self->assertTokenValue($self->getToken(), ")", __LINE__);
637         $self->assertTokenValue($self->getToken(), ";", __LINE__);
638         return;
639     }
640     $self->assertUnexpectedToken($next->value(), __LINE__);
641 }
642
643 sub parseTypedef
644 {
645     my $self = shift;
646     my $extendedAttributeList = shift;
647
648     my $next = $self->nextToken();
649     if ($next->value() eq "typedef") {
650         $self->assertTokenValue($self->getToken(), "typedef", __LINE__);
651         $self->parseExtendedAttributeList();
652         $self->parseType();
653         $self->assertTokenType($self->getToken(), IdentifierToken);
654         $self->assertTokenValue($self->getToken(), ";", __LINE__);
655         return;
656     }
657     $self->assertUnexpectedToken($next->value(), __LINE__);
658 }
659
660 sub parseImplementsStatement
661 {
662     my $self = shift;
663     my $extendedAttributeList = shift;
664
665     my $next = $self->nextToken();
666     if ($next->type() == IdentifierToken) {
667         $self->parseScopedName();
668         $self->assertTokenValue($self->getToken(), "implements", __LINE__);
669         $self->parseScopedName();
670         $self->assertTokenValue($self->getToken(), ";", __LINE__);
671         return;
672     }
673     $self->assertUnexpectedToken($next->value(), __LINE__);
674 }
675
676 sub parseConst
677 {
678     my $self = shift;
679     my $extendedAttributeList = shift;
680
681     my $next = $self->nextToken();
682     if ($next->value() eq "const") {
683         my $newDataNode = new domConstant();
684         $self->assertTokenValue($self->getToken(), "const", __LINE__);
685         $newDataNode->type($self->parseConstType());
686         my $constNameToken = $self->getToken();
687         $self->assertTokenType($constNameToken, IdentifierToken);
688         $newDataNode->name($constNameToken->value());
689         $self->assertTokenValue($self->getToken(), "=", __LINE__);
690         $newDataNode->value($self->parseConstValue());
691         $self->assertTokenValue($self->getToken(), ";", __LINE__);
692         $newDataNode->extendedAttributes($extendedAttributeList);
693         return $newDataNode;
694     }
695     $self->assertUnexpectedToken($next->value(), __LINE__);
696 }
697
698 sub parseConstValue
699 {
700     my $self = shift;
701     my $next = $self->nextToken();
702     if ($next->value() =~ /$nextConstValue_1/) {
703         return $self->parseBooleanLiteral();
704     }
705     if ($next->value() eq "null") {
706         $self->assertTokenValue($self->getToken(), "null", __LINE__);
707         return "null";
708     }
709     if ($next->type() == FloatToken || $next->value() =~ /$nextConstValue_2/) {
710         return $self->parseFloatLiteral();
711     }
712     # backward compatibility
713     if ($next->type() == StringToken) {
714         return $self->getToken()->value();
715     }
716     if ($next->type() == IntegerToken) {
717         return $self->getToken()->value();
718     }
719     $self->assertUnexpectedToken($next->value(), __LINE__);
720 }
721
722 sub parseBooleanLiteral
723 {
724     my $self = shift;
725     my $next = $self->nextToken();
726     if ($next->value() eq "true") {
727         $self->assertTokenValue($self->getToken(), "true", __LINE__);
728         return "true";
729     }
730     if ($next->value() eq "false") {
731         $self->assertTokenValue($self->getToken(), "false", __LINE__);
732         return "false";
733     }
734     $self->assertUnexpectedToken($next->value(), __LINE__);
735 }
736
737 sub parseFloatLiteral
738 {
739     my $self = shift;
740     my $next = $self->nextToken();
741     if ($next->value() eq "-") {
742         $self->assertTokenValue($self->getToken(), "-", __LINE__);
743         $self->assertTokenValue($self->getToken(), "Infinity", __LINE__);
744         return "-Infinity";
745     }
746     if ($next->value() eq "Infinity") {
747         $self->assertTokenValue($self->getToken(), "Infinity", __LINE__);
748         return "Infinity";
749     }
750     if ($next->value() eq "NaN") {
751         $self->assertTokenValue($self->getToken(), "NaN", __LINE__);
752         return "NaN";
753     }
754     if ($next->type() == FloatToken) {
755         return $self->getToken()->value();
756     }
757     $self->assertUnexpectedToken($next->value(), __LINE__);
758 }
759
760 sub parseAttributeOrOperationOrIterator
761 {
762     my $self = shift;
763     my $extendedAttributeList = shift;
764
765     my $next = $self->nextToken();
766     if ($next->value() eq "serializer") {
767         return $self->parseSerializer($extendedAttributeList);
768     }
769     if ($next->value() =~ /$nextAttributeOrOperationOrIterator_1/) {
770         my $qualifier = $self->parseQualifier();
771         my $newDataNode = $self->parseAttributeOrOperationRest($extendedAttributeList);
772         if (defined($newDataNode) && $qualifier eq "static") {
773             $newDataNode->isStatic(1);
774         }
775         return $newDataNode;
776     }
777     if ($next->value() =~ /$nextAttributeOld_1/) {
778         return $self->parseAttribute($extendedAttributeList);
779     }
780     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationOrIterator_2/) {
781         return $self->parseOperationOrIterator($extendedAttributeList);
782     }
783     $self->assertUnexpectedToken($next->value(), __LINE__);
784 }
785
786 sub parseSerializer
787 {
788     my $self = shift;
789     my $extendedAttributeList = shift;
790
791     my $next = $self->nextToken();
792     if ($next->value() eq "serializer") {
793         $self->assertTokenValue($self->getToken(), "serializer", __LINE__);
794         return $self->parseSerializerRest($extendedAttributeList);
795     }
796     $self->assertUnexpectedToken($next->value(), __LINE__);
797 }
798
799 sub parseSerializerRest
800 {
801     my $self = shift;
802     my $extendedAttributeList = shift;
803
804     my $next = $self->nextToken();
805     if ($next->value() eq "=") {
806         $self->assertTokenValue($self->getToken(), "=", __LINE__);
807         return $self->parseSerializationPattern($extendedAttributeList);
808     }
809     if ($next->type() == IdentifierToken || $next->value() eq "(") {
810         return $self->parseOperationRest($extendedAttributeList);
811     }
812 }
813
814 sub parseSerializationPattern
815 {
816     my $self = shift;
817     my $extendedAttributeList = shift;
818
819     my $next = $self->nextToken();
820     if ($next->value() eq "{") {
821         $self->assertTokenValue($self->getToken(), "{", __LINE__);
822         $self->parseSerializationPatternMap();
823         $self->assertTokenValue($self->getToken(), "}", __LINE__);
824         return;
825     }
826     if ($next->value() eq "[") {
827         $self->assertTokenValue($self->getToken(), "[", __LINE__);
828         $self->parseSerializationPatternList();
829         $self->assertTokenValue($self->getToken(), "]", __LINE__);
830         return;
831     }
832     if ($next->type() == IdentifierToken) {
833         $self->assertTokenType($self->getToken(), IdentifierToken);
834         return;
835     }
836     $self->assertUnexpectedToken($next->value(), __LINE__);
837 }
838
839 sub parseSerializationPatternMap
840 {
841     my $self = shift;
842     my $next = $self->nextToken();
843     if ($next->value() eq "getter") {
844         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
845         return;
846     }
847     if ($next->value() eq "inherit") {
848         $self->assertTokenValue($self->getToken(), "inherit", __LINE__);
849         $self->parseIdentifiers();
850         return;
851     }
852     if ($next->type() == IdentifierToken) {
853         $self->assertTokenType($self->getToken(), IdentifierToken);
854         $self->parseIdentifiers();
855     }
856 }
857
858 sub parseSerializationPatternList
859 {
860     my $self = shift;
861     my $next = $self->nextToken();
862     if ($next->value() eq "getter") {
863         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
864         return;
865     }
866     if ($next->type() == IdentifierToken) {
867         $self->assertTokenType($self->getToken(), IdentifierToken);
868         $self->parseIdentifiers();
869     }
870 }
871
872 sub parseIdentifiers
873 {
874     my $self = shift;
875     my @idents = ();
876
877     while (1) {
878         my $next = $self->nextToken();
879         if ($next->value() eq ",") {
880             $self->assertTokenValue($self->getToken(), ",", __LINE__);
881             my $token = $self->getToken();
882             $self->assertTokenType($token, IdentifierToken);
883             push(@idents, $token->value());
884         } else {
885             last;
886         }
887     }
888     return \@idents;
889 }
890
891 sub parseQualifier
892 {
893     my $self = shift;
894
895     my $next = $self->nextToken();
896     if ($next->value() eq "static") {
897         $self->assertTokenValue($self->getToken(), "static", __LINE__);
898         return "static";
899     }
900     if ($next->value() eq "stringifier") {
901         $self->assertTokenValue($self->getToken(), "stringifier", __LINE__);
902         return "stringifier";
903     }
904     $self->assertUnexpectedToken($next->value(), __LINE__);
905 }
906
907 sub parseAttributeOrOperationRest
908 {
909     my $self = shift;
910     my $extendedAttributeList = shift;
911
912     my $next = $self->nextToken();
913     if ($next->value() =~ /$nextAttributeRest_1/) {
914         return $self->parseAttributeRest($extendedAttributeList);
915     }
916     if ($next->value() eq ";") {
917         $self->assertTokenValue($self->getToken(), ";", __LINE__);
918         return;
919     }
920     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationRest_1/) {
921         my $returnType = $self->parseReturnType();
922         my $dataNode = $self->parseOperationRest($extendedAttributeList);
923         if (defined ($dataNode)) {
924             $dataNode->signature->type($returnType);
925         }
926         return $dataNode;
927     }
928     $self->assertUnexpectedToken($next->value(), __LINE__);
929 }
930
931 sub parseAttribute
932 {
933     my $self = shift;
934     my $extendedAttributeList = shift;
935
936     my $next = $self->nextToken();
937     if ($next->value() =~ /$nextAttributeOld_1/) {
938         $self->parseInherit();
939         return $self->parseAttributeRest($extendedAttributeList);
940     }
941     $self->assertUnexpectedToken($next->value(), __LINE__);
942 }
943
944 sub parseAttributeRest
945 {
946     my $self = shift;
947     my $extendedAttributeList = shift;
948
949     my $next = $self->nextToken();
950     if ($next->value() =~ /$nextAttributeRest_1/) {
951         my $newDataNode = new domAttribute();
952         if ($self->parseReadOnly()) {
953             $newDataNode->type("readonly attribute");
954         } else {
955             $newDataNode->type("attribute");
956         }
957         $self->assertTokenValue($self->getToken(), "attribute", __LINE__);
958         $newDataNode->signature(new domSignature());
959         $newDataNode->signature->type($self->parseType());
960         my $token = $self->getToken();
961         $self->assertTokenType($token, IdentifierToken);
962         $newDataNode->signature->name($token->value());
963         my $getRef = $self->parseGet();
964         if (defined $getRef) {
965             push(@{$newDataNode->getterExceptions}, @{$getRef->{"getraises"}});
966             push(@{$newDataNode->setterExceptions}, @{$getRef->{"setraises"}});
967         }
968         $self->assertTokenValue($self->getToken(), ";", __LINE__);
969         $newDataNode->signature->extendedAttributes($extendedAttributeList);
970         return $newDataNode;
971     }
972     $self->assertUnexpectedToken($next->value(), __LINE__);
973 }
974
975 sub parseInherit
976 {
977     my $self = shift;
978     my $next = $self->nextToken();
979     if ($next->value() eq "inherit") {
980         $self->assertTokenValue($self->getToken(), "inherit", __LINE__);
981         return 1;
982     }
983     return 0;
984 }
985
986 sub parseReadOnly
987 {
988     my $self = shift;
989     my $next = $self->nextToken();
990     if ($next->value() eq "readonly") {
991         $self->assertTokenValue($self->getToken(), "readonly", __LINE__);
992         return 1;
993     }
994     return 0;
995 }
996
997 sub parseOperationOrIterator
998 {
999     my $self = shift;
1000     my $extendedAttributeList = shift;
1001
1002     my $next = $self->nextToken();
1003     if ($next->value() =~ /$nextSpecials_1/) {
1004         return $self->parseSpecialOperation($extendedAttributeList);
1005     }
1006     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationRest_1/) {
1007         my $returnType = $self->parseReturnType();
1008         my $dataNode = $self->parseOperationOrIteratorRest($extendedAttributeList);
1009         if (defined ($dataNode)) {
1010             $dataNode->signature->type($returnType);
1011         }
1012         return $dataNode;
1013     }
1014     $self->assertUnexpectedToken($next->value(), __LINE__);
1015 }
1016
1017 sub parseSpecialOperation
1018 {
1019     my $self = shift;
1020     my $extendedAttributeList = shift;
1021
1022     my $next = $self->nextToken();
1023     if ($next->value() =~ /$nextSpecials_1/) {
1024         $self->parseSpecial();
1025         $self->parseSpecials();
1026         my $returnType = $self->parseReturnType();
1027         my $dataNode = $self->parseOperationRest($extendedAttributeList);
1028         if (defined ($dataNode)) {
1029             $dataNode->signature->type($returnType);
1030         }
1031         return $dataNode;
1032     }
1033     $self->assertUnexpectedToken($next->value(), __LINE__);
1034 }
1035
1036 sub parseSpecials
1037 {
1038     my $self = shift;
1039
1040     while (1) {
1041         my $next = $self->nextToken();
1042         if ($next->value() =~ /$nextSpecials_1/) {
1043             $self->parseSpecial();
1044         } else {
1045             last;
1046         }
1047     }
1048     return [];
1049 }
1050
1051 sub parseSpecial
1052 {
1053     my $self = shift;
1054     my $next = $self->nextToken();
1055     if ($next->value() eq "getter") {
1056         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
1057         return "getter";
1058     }
1059     if ($next->value() eq "setter") {
1060         $self->assertTokenValue($self->getToken(), "setter", __LINE__);
1061         return "setter";
1062     }
1063     if ($next->value() eq "creator") {
1064         $self->assertTokenValue($self->getToken(), "creator", __LINE__);
1065         return "creator";
1066     }
1067     if ($next->value() eq "deleter") {
1068         $self->assertTokenValue($self->getToken(), "deleter", __LINE__);
1069         return "deleter";
1070     }
1071     if ($next->value() eq "legacycaller") {
1072         $self->assertTokenValue($self->getToken(), "legacycaller", __LINE__);
1073         return "legacycaller";
1074     }
1075     $self->assertUnexpectedToken($next->value(), __LINE__);
1076 }
1077
1078 sub parseOperationOrIteratorRest
1079 {
1080     my $self = shift;
1081     my $extendedAttributeList = shift;
1082
1083     my $next = $self->nextToken();
1084     if ($next->value() eq "iterator") {
1085         return $self->parseIteratorRest($extendedAttributeList);
1086     }
1087     if ($next->type() == IdentifierToken || $next->value() eq "(") {
1088         return $self->parseOperationRest($extendedAttributeList);
1089     }
1090     $self->assertUnexpectedToken($next->value(), __LINE__);
1091 }
1092
1093 sub parseIteratorRest
1094 {
1095     my $self = shift;
1096     my $extendedAttributeList = shift;
1097
1098     my $next = $self->nextToken();
1099     if ($next->value() eq "iterator") {
1100         $self->assertTokenValue($self->getToken(), "iterator", __LINE__);
1101         $self->parseOptionalIteratorInterfaceOrObject($extendedAttributeList);
1102         $self->assertTokenValue($self->getToken(), ";", __LINE__);
1103         return;
1104     }
1105     $self->assertUnexpectedToken($next->value(), __LINE__);
1106 }
1107
1108 sub parseOptionalIteratorInterfaceOrObject
1109 {
1110     my $self = shift;
1111     my $extendedAttributeList = shift;
1112
1113     my $next = $self->nextToken();
1114     if ($next->value() =~ /$nextOptionalIteratorInterfaceOrObject_1/) {
1115         return $self->parseOptionalIteratorInterface($extendedAttributeList);
1116     }
1117     if ($next->value() eq "object") {
1118         $self->assertTokenValue($self->getToken(), "object", __LINE__);
1119         return;
1120     }
1121     $self->assertUnexpectedToken($next->value(), __LINE__);
1122 }
1123
1124 sub parseOptionalIteratorInterface
1125 {
1126     my $self = shift;
1127     my $extendedAttributeList = shift;
1128
1129     my $next = $self->nextToken();
1130     if ($next->value() eq "=") {
1131         $self->assertTokenValue($self->getToken(), "=", __LINE__);
1132         $self->assertTokenType($self->getToken(), IdentifierToken);
1133     }
1134 }
1135
1136 sub parseOperationRest
1137 {
1138     my $self = shift;
1139     my $extendedAttributeList = shift;
1140
1141     my $next = $self->nextToken();
1142     if ($next->type() == IdentifierToken || $next->value() eq "(") {
1143         my $newDataNode = new domFunction();
1144         $newDataNode->signature(new domSignature());
1145         my $name = $self->parseOptionalIdentifier();
1146         $newDataNode->signature->name($name);
1147         $self->assertTokenValue($self->getToken(), "(", $name, __LINE__);
1148         push(@{$newDataNode->parameters}, @{$self->parseArgumentList()});
1149         $self->assertTokenValue($self->getToken(), ")", __LINE__);
1150         push(@{$newDataNode->raisesExceptions}, @{$self->parseRaises()});
1151         $self->assertTokenValue($self->getToken(), ";", __LINE__);
1152         $newDataNode->signature->extendedAttributes($extendedAttributeList);
1153         return $newDataNode;
1154     }
1155     $self->assertUnexpectedToken($next->value(), __LINE__);
1156 }
1157
1158 sub parseOptionalIdentifier
1159 {
1160     my $self = shift;
1161     my $next = $self->nextToken();
1162     if ($next->type() == IdentifierToken) {
1163         my $token = $self->getToken();
1164         return $token->value();
1165     }
1166     return "";
1167 }
1168
1169 sub parseArgumentList
1170 {
1171     my $self = shift;
1172     my @arguments = ();
1173
1174     my $next = $self->nextToken();
1175     if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList_1/) {
1176         push(@arguments, $self->parseArgument());
1177         push(@arguments, @{$self->parseArguments()});
1178     }
1179     return \@arguments;
1180 }
1181
1182 sub parseArguments
1183 {
1184     my $self = shift;
1185     my @arguments = ();
1186
1187     while (1) {
1188         my $next = $self->nextToken();
1189         if ($next->value() eq ",") {
1190             $self->assertTokenValue($self->getToken(), ",", __LINE__);
1191             push(@arguments, $self->parseArgument());
1192         } else {
1193             last;
1194         }
1195     }
1196     return \@arguments;
1197 }
1198
1199 sub parseArgument
1200 {
1201     my $self = shift;
1202     my $next = $self->nextToken();
1203     if ($next->type() == IdentifierToken || $next->value() =~ /$nextArgumentList_1/) {
1204         my $in = $self->parseIn();
1205         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
1206         my $argument = $self->parseOptionalOrRequiredArgument($extendedAttributeList);
1207         $argument->direction($self->parseIn());
1208         return $argument;
1209     }
1210     $self->assertUnexpectedToken($next->value(), __LINE__);
1211 }
1212
1213 sub parseOptionalOrRequiredArgument
1214 {
1215     my $self = shift;
1216     my $extendedAttributeList = shift;
1217
1218     my $paramDataNode = new domSignature();
1219     $paramDataNode->extendedAttributes($extendedAttributeList);
1220
1221     my $next = $self->nextToken();
1222     if ($next->value() eq "optional") {
1223         $self->assertTokenValue($self->getToken(), "optional", __LINE__);
1224         my $type = $self->parseType();
1225         # domDataNode can only consider last "?".
1226         if ($type =~ /\?$/) {
1227             $paramDataNode->isNullable(1);
1228         } else {
1229             $paramDataNode->isNullable(0);
1230         }
1231         # Remove all "?" if exists, e.g. "object?[]?" -> "object[]".
1232         $type =~ s/\?//g;
1233         $paramDataNode->type($type);
1234         $paramDataNode->name($self->parseArgumentName());
1235         $self->parseDefault();
1236         return $paramDataNode;
1237     }
1238     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
1239         my $type = $self->parseType();
1240         # domDataNode can only consider last "?".
1241         if ($type =~ /\?$/) {
1242             $paramDataNode->isNullable(1);
1243         } else {
1244             $paramDataNode->isNullable(0);
1245         }
1246         # Remove all "?" if exists, e.g. "object?[]?" -> "object[]".
1247         $type =~ s/\?//g;
1248         $paramDataNode->type($type);
1249         $paramDataNode->isVariadic($self->parseEllipsis());
1250         $paramDataNode->name($self->parseArgumentName());
1251         return $paramDataNode;
1252     }
1253     $self->assertUnexpectedToken($next->value(), __LINE__);
1254 }
1255
1256 sub parseArgumentName
1257 {
1258     my $self = shift;
1259     my $next = $self->nextToken();
1260     if ($next->value() =~ /$nextArgumentName_1/) {
1261         return $self->parseArgumentNameKeyword();
1262     }
1263     if ($next->type() == IdentifierToken) {
1264         return $self->getToken()->value();
1265     }
1266     $self->assertUnexpectedToken($next->value(), __LINE__);
1267 }
1268
1269 sub parseEllipsis
1270 {
1271     my $self = shift;
1272     my $next = $self->nextToken();
1273     if ($next->value() eq "...") {
1274         $self->assertTokenValue($self->getToken(), "...", __LINE__);
1275         return 1;
1276     }
1277     return 0;
1278 }
1279
1280 sub parseExceptionMember
1281 {
1282     my $self = shift;
1283     my $extendedAttributeList = shift;
1284
1285     my $next = $self->nextToken();
1286     if ($next->value() eq "const") {
1287         return $self->parseConst($extendedAttributeList);
1288     }
1289     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
1290         return $self->parseExceptionField($extendedAttributeList);
1291     }
1292     $self->assertUnexpectedToken($next->value(), __LINE__);
1293 }
1294
1295 sub parseExceptionField
1296 {
1297     my $self = shift;
1298     my $extendedAttributeList = shift;
1299
1300     my $next = $self->nextToken();
1301     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
1302         my $newDataNode = new domAttribute();
1303         $newDataNode->type("readonly attribute");
1304         $newDataNode->signature(new domSignature());
1305         $newDataNode->signature->type($self->parseType());
1306         my $token = $self->getToken();
1307         $self->assertTokenType($token, IdentifierToken);
1308         $newDataNode->signature->name($token->value());
1309         $self->assertTokenValue($self->getToken(), ";", __LINE__);
1310         $newDataNode->signature->extendedAttributes($extendedAttributeList);
1311         return $newDataNode;
1312     }
1313     $self->assertUnexpectedToken($next->value(), __LINE__);
1314 }
1315
1316 sub parseExtendedAttributeListAllowEmpty
1317 {
1318     my $self = shift;
1319     my $next = $self->nextToken();
1320     if ($next->value() eq "[") {
1321         return $self->parseExtendedAttributeList();
1322     }
1323     return {};
1324 }
1325
1326 sub parseExtendedAttributeList
1327 {
1328     my $self = shift;
1329     my $next = $self->nextToken();
1330     if ($next->value() eq "[") {
1331         $self->assertTokenValue($self->getToken(), "[", __LINE__);
1332         my $extendedAttributeList = {};
1333         my $attr = $self->parseExtendedAttribute();
1334         for my $key (keys %{$attr}) {
1335             $extendedAttributeList->{$key} = $attr->{$key};
1336         }
1337         $attr = $self->parseExtendedAttributes();
1338         for my $key (keys %{$attr}) {
1339             $extendedAttributeList->{$key} = $attr->{$key};
1340         }
1341         $self->assertTokenValue($self->getToken(), "]", __LINE__);
1342         return $extendedAttributeList;
1343     }
1344     $self->assertUnexpectedToken($next->value(), __LINE__);
1345 }
1346
1347 sub parseExtendedAttributes
1348 {
1349     my $self = shift;
1350     my $extendedAttributeList = {};
1351
1352     while (1) {
1353         my $next = $self->nextToken();
1354         if ($next->value() eq ",") {
1355             $self->assertTokenValue($self->getToken(), ",", __LINE__);
1356             my $attr = $self->parseExtendedAttribute2();
1357             for my $key (keys %{$attr}) {
1358                 $extendedAttributeList->{$key} = $attr->{$key};
1359             }
1360         } else {
1361             last;
1362         }
1363     }
1364     return $extendedAttributeList;
1365 }
1366
1367 sub parseExtendedAttribute
1368 {
1369     my $self = shift;
1370     my $next = $self->nextToken();
1371     if ($next->type() == IdentifierToken || $next->value() eq "::") {
1372         my $scopedName = $self->parseScopedName();
1373         return $self->parseExtendedAttributeRest($scopedName);
1374     }
1375     # backward compatibility. Spec doesn' allow "[]". But WebKit requires.
1376     if ($next->value() eq ']') {
1377         return {};
1378     }
1379     $self->assertUnexpectedToken($next->value(), __LINE__);
1380 }
1381
1382 sub parseExtendedAttribute2
1383 {
1384     my $self = shift;
1385     my $next = $self->nextToken();
1386     if ($next->type() == IdentifierToken || $next->value() eq "::") {
1387         my $scopedName = $self->parseScopedName();
1388         return $self->parseExtendedAttributeRest($scopedName);
1389     }
1390     return {};
1391 }
1392
1393 sub parseExtendedAttributeRest
1394 {
1395     my $self = shift;
1396     my $name = shift;
1397     my $attrs = {};
1398
1399     my $next = $self->nextToken();
1400     if ($next->value() eq "(") {
1401         $self->assertTokenValue($self->getToken(), "(", __LINE__);
1402         $attrs->{$name} = $self->parseArgumentList();
1403         $self->assertTokenValue($self->getToken(), ")", __LINE__);
1404         return $attrs;
1405     }
1406     if ($next->value() eq "=") {
1407         $self->assertTokenValue($self->getToken(), "=", __LINE__);
1408         $attrs->{$name} = $self->parseExtendedAttributeRest2();
1409         return $attrs;
1410     }
1411
1412     if ($name eq "Constructor") {
1413         $attrs->{$name} = [];
1414     } else {
1415         $attrs->{$name} = "VALUE_IS_MISSING";
1416     }
1417     return $attrs;
1418 }
1419
1420 sub parseExtendedAttributeRest2
1421 {
1422     my $self = shift;
1423     my $next = $self->nextToken();
1424     if ($next->type() == IdentifierToken || $next->value() eq "::") {
1425         my $scopedName = $self->parseScopedName();
1426         return $self->parseExtendedAttributeRest3($scopedName);
1427     }
1428     if ($next->type() == IntegerToken) {
1429         my $token = $self->getToken();
1430         return $token->value();
1431     }
1432     $self->assertUnexpectedToken($next->value(), __LINE__);
1433 }
1434
1435 sub parseExtendedAttributeRest3
1436 {
1437     my $self = shift;
1438     my $name = shift;
1439
1440     my $next = $self->nextToken();
1441     if ($next->value() eq "&") {
1442         $self->assertTokenValue($self->getToken(), "&", __LINE__);
1443         my $rightValue = $self->parseScopedName();
1444         return $name . "&" . $rightValue;
1445     }
1446     if ($next->value() eq "|") {
1447         $self->assertTokenValue($self->getToken(), "|", __LINE__);
1448         my $rightValue = $self->parseScopedName();
1449         return $name . "|" . $rightValue;
1450     }
1451     if ($next->value() eq "(") {
1452         my $attr = {};
1453         $self->assertTokenValue($self->getToken(), "(", __LINE__);
1454         $attr->{$name} = $self->parseArgumentList();
1455         $self->assertTokenValue($self->getToken(), ")", __LINE__);
1456         return $attr;
1457     }
1458     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExtendedAttributeRest3_1/) {
1459         my @names = ();
1460         push(@names, $name);
1461         push(@names, @{$self->parseScopedNameListNoComma()});
1462         return join(' ', @names);
1463     }
1464     $self->assertUnexpectedToken($next->value());
1465 }
1466
1467 sub parseScopedNameListNoComma
1468 {
1469     my $self = shift;
1470     my @names = ();
1471
1472     while (1) {
1473         my $next = $self->nextToken();
1474         if ($next->type() == IdentifierToken || $next->value() eq "::") {
1475             push(@names, $self->parseScopedName());
1476         } else {
1477             last;
1478         }
1479     }
1480     return \@names;
1481 }
1482
1483 sub parseArgumentNameKeyword
1484 {
1485     my $self = shift;
1486     my $next = $self->nextToken();
1487     if ($next->value() eq "attribute") {
1488         return $self->getToken()->value();
1489     }
1490     if ($next->value() eq "callback") {
1491         return $self->getToken()->value();
1492     }
1493     if ($next->value() eq "const") {
1494         return $self->getToken()->value();
1495     }
1496     if ($next->value() eq "creator") {
1497         return $self->getToken()->value();
1498     }
1499     if ($next->value() eq "deleter") {
1500         return $self->getToken()->value();
1501     }
1502     if ($next->value() eq "dictionary") {
1503         return $self->getToken()->value();
1504     }
1505     if ($next->value() eq "enum") {
1506         return $self->getToken()->value();
1507     }
1508     if ($next->value() eq "exception") {
1509         return $self->getToken()->value();
1510     }
1511     if ($next->value() eq "getter") {
1512         return $self->getToken()->value();
1513     }
1514     if ($next->value() eq "implements") {
1515         return $self->getToken()->value();
1516     }
1517     if ($next->value() eq "inherit") {
1518         return $self->getToken()->value();
1519     }
1520     if ($next->value() eq "interface") {
1521         return $self->getToken()->value();
1522     }
1523     if ($next->value() eq "legacycaller") {
1524         return $self->getToken()->value();
1525     }
1526     if ($next->value() eq "partial") {
1527         return $self->getToken()->value();
1528     }
1529     if ($next->value() eq "serializer") {
1530         return $self->getToken()->value();
1531     }
1532     if ($next->value() eq "setter") {
1533         return $self->getToken()->value();
1534     }
1535     if ($next->value() eq "static") {
1536         return $self->getToken()->value();
1537     }
1538     if ($next->value() eq "stringifier") {
1539         return $self->getToken()->value();
1540     }
1541     if ($next->value() eq "typedef") {
1542         return $self->getToken()->value();
1543     }
1544     if ($next->value() eq "unrestricted") {
1545         return $self->getToken()->value();
1546     }
1547     $self->assertUnexpectedToken($next->value(), __LINE__);
1548 }
1549
1550 sub parseType
1551 {
1552     my $self = shift;
1553     my $next = $self->nextToken();
1554     if ($next->value() eq "(") {
1555         $self->parseUnionType();
1556         $self->parseTypeSuffix();
1557         return;
1558     }
1559     if ($next->type() == IdentifierToken || $next->value() =~ /$nextType_1/) {
1560         return $self->parseSingleType();
1561     }
1562     $self->assertUnexpectedToken($next->value(), __LINE__);
1563 }
1564
1565 sub parseSingleType
1566 {
1567     my $self = shift;
1568     my $next = $self->nextToken();
1569     if ($next->value() eq "any") {
1570         $self->assertTokenValue($self->getToken(), "any", __LINE__);
1571         return "any" . $self->parseTypeSuffixStartingWithArray();
1572     }
1573     if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1/) {
1574         return $self->parseNonAnyType();
1575     }
1576     $self->assertUnexpectedToken($next->value(), __LINE__);
1577 }
1578
1579 sub parseUnionType
1580 {
1581     my $self = shift;
1582     my $next = $self->nextToken();
1583     if ($next->value() eq "(") {
1584         $self->assertTokenValue($self->getToken(), "(", __LINE__);
1585         $self->parseUnionMemberType();
1586         $self->assertTokenValue($self->getToken(), "or", __LINE__);
1587         $self->parseUnionMemberType();
1588         $self->parseUnionMemberTypes();
1589         $self->assertTokenValue($self->getToken(), ")", __LINE__);
1590         return;
1591     }
1592     $self->assertUnexpectedToken($next->value(), __LINE__);
1593 }
1594
1595 sub parseUnionMemberType
1596 {
1597     my $self = shift;
1598     my $next = $self->nextToken();
1599     if ($next->value() eq "(") {
1600         $self->parseUnionType();
1601         $self->parseTypeSuffix();
1602         return;
1603     }
1604     if ($next->value() eq "any") {
1605         $self->assertTokenValue($self->getToken(), "any", __LINE__);
1606         $self->assertTokenValue($self->getToken(), "[", __LINE__);
1607         $self->assertTokenValue($self->getToken(), "]", __LINE__);
1608         $self->parseTypeSuffix();
1609         return;
1610     }
1611     if ($next->type() == IdentifierToken || $next->value() =~ /$nextSingleType_1/) {
1612         $self->parseNonAnyType();
1613         return;
1614     }
1615     $self->assertUnexpectedToken($next->value(), __LINE__);
1616 }
1617
1618 sub parseUnionMemberTypes
1619 {
1620     my $self = shift;
1621     my $next = $self->nextToken();
1622     if ($next->value() eq "or") {
1623         $self->assertTokenValue($self->getToken(), "or", __LINE__);
1624         $self->parseUnionMemberType();
1625         $self->parseUnionMemberTypes();
1626     }
1627 }
1628
1629 sub parseNonAnyType
1630 {
1631     my $self = shift;
1632     my $next = $self->nextToken();
1633     if ($next->value() =~ /$nextNonAnyType_1/) {
1634         return $self->parsePrimitiveType() . $self->parseTypeSuffix();
1635     }
1636     if ($next->value() eq "ByteString") {
1637         $self->assertTokenValue($self->getToken(), "ByteString", __LINE__);
1638         return "ByteString" . $self->parseTypeSuffix();
1639     }
1640     if ($next->value() eq "DOMString") {
1641         $self->assertTokenValue($self->getToken(), "DOMString", __LINE__);
1642         return "DOMString" . $self->parseTypeSuffix();
1643     }
1644     if ($next->value() eq "sequence") {
1645         $self->assertTokenValue($self->getToken(), "sequence", __LINE__);
1646         $self->assertTokenValue($self->getToken(), "<", __LINE__);
1647         my $type = $self->parseType();
1648         $self->assertTokenValue($self->getToken(), ">", __LINE__);
1649         return "sequence<" . $type . ">" . $self->parseNull();
1650     }
1651     if ($next->value() eq "object") {
1652         $self->assertTokenValue($self->getToken(), "object", __LINE__);
1653         return "object" . $self->parseTypeSuffix();
1654     }
1655     if ($next->value() eq "Date") {
1656         $self->assertTokenValue($self->getToken(), "Date", __LINE__);
1657         return "Date" . $self->parseTypeSuffix();
1658     }
1659     if ($next->type() == IdentifierToken || $next->value() eq "::") {
1660         my $name = $self->parseScopedName();
1661         return $name . $self->parseTypeSuffix();
1662     }
1663     $self->assertUnexpectedToken($next->value(), __LINE__);
1664 }
1665
1666 sub parseConstType
1667 {
1668     my $self = shift;
1669     my $next = $self->nextToken();
1670     if ($next->value() =~ /$nextNonAnyType_1/) {
1671         return $self->parsePrimitiveType() . $self->parseNull();
1672     }
1673     if ($next->type() == IdentifierToken) {
1674         my $token = $self->getToken();
1675         return $token->value() . $self->parseNull();
1676     }
1677     $self->assertUnexpectedToken($next->value(), __LINE__);
1678 }
1679
1680 sub parsePrimitiveType
1681 {
1682     my $self = shift;
1683     my $next = $self->nextToken();
1684     if ($next->value() =~ /$nextPrimitiveType_1/) {
1685         return $self->parseUnsignedIntegerType();
1686     }
1687     if ($next->value() =~ /$nextPrimitiveType_2/) {
1688         return $self->parseUnrestrictedFloatType();
1689     }
1690     if ($next->value() eq "boolean") {
1691         $self->assertTokenValue($self->getToken(), "boolean", __LINE__);
1692         return "boolean";
1693     }
1694     if ($next->value() eq "byte") {
1695         $self->assertTokenValue($self->getToken(), "byte", __LINE__);
1696         return "byte";
1697     }
1698     if ($next->value() eq "octet") {
1699         $self->assertTokenValue($self->getToken(), "octet", __LINE__);
1700         return "octet";
1701     }
1702     $self->assertUnexpectedToken($next->value(), __LINE__);
1703 }
1704
1705 sub parseUnrestrictedFloatType
1706 {
1707     my $self = shift;
1708     my $next = $self->nextToken();
1709     if ($next->value() eq "unrestricted") {
1710         $self->assertTokenValue($self->getToken(), "unrestricted", __LINE__);
1711         return "unrestricted" . $self->parseFloatType();
1712     }
1713     if ($next->value() =~ /$nextUnrestrictedFloatType_1/) {
1714         return $self->parseFloatType();
1715     }
1716     $self->assertUnexpectedToken($next->value(), __LINE__);
1717 }
1718
1719 sub parseFloatType
1720 {
1721     my $self = shift;
1722     my $next = $self->nextToken();
1723     if ($next->value() eq "float") {
1724         $self->assertTokenValue($self->getToken(), "float", __LINE__);
1725         return "float";
1726     }
1727     if ($next->value() eq "double") {
1728         $self->assertTokenValue($self->getToken(), "double", __LINE__);
1729         return "double";
1730     }
1731     $self->assertUnexpectedToken($next->value(), __LINE__);
1732 }
1733
1734 sub parseUnsignedIntegerType
1735 {
1736     my $self = shift;
1737     my $next = $self->nextToken();
1738     if ($next->value() eq "unsigned") {
1739         $self->assertTokenValue($self->getToken(), "unsigned", __LINE__);
1740         return "unsigned " . $self->parseIntegerType();
1741     }
1742     if ($next->value() =~ /$nextUnsignedIntegerType_1/) {
1743         return $self->parseIntegerType();
1744     }
1745     $self->assertUnexpectedToken($next->value(), __LINE__);
1746 }
1747
1748 sub parseIntegerType
1749 {
1750     my $self = shift;
1751     my $next = $self->nextToken();
1752     if ($next->value() eq "short") {
1753         $self->assertTokenValue($self->getToken(), "short", __LINE__);
1754         return "short";
1755     }
1756     if ($next->value() eq "int") {
1757         $self->assertTokenValue($self->getToken(), "int", __LINE__);
1758         return "int";
1759     }
1760     if ($next->value() eq "long") {
1761         $self->assertTokenValue($self->getToken(), "long", __LINE__);
1762         if ($self->parseOptionalLong()) {
1763             return "long long";
1764         }
1765         return "long";
1766     }
1767     $self->assertUnexpectedToken($next->value(), __LINE__);
1768 }
1769
1770 sub parseOptionalLong
1771 {
1772     my $self = shift;
1773     my $next = $self->nextToken();
1774     if ($next->value() eq "long") {
1775         $self->assertTokenValue($self->getToken(), "long", __LINE__);
1776         return 1;
1777     }
1778     return 0;
1779 }
1780
1781 sub parseTypeSuffix
1782 {
1783     my $self = shift;
1784     my $next = $self->nextToken();
1785     if ($next->value() eq "[") {
1786         $self->assertTokenValue($self->getToken(), "[", __LINE__);
1787         $self->assertTokenValue($self->getToken(), "]", __LINE__);
1788         return "[]" . $self->parseTypeSuffix();
1789     }
1790     if ($next->value() eq "?") {
1791         $self->assertTokenValue($self->getToken(), "?", __LINE__);
1792         return "?" . $self->parseTypeSuffixStartingWithArray();
1793     }
1794     return "";
1795 }
1796
1797 sub parseTypeSuffixStartingWithArray
1798 {
1799     my $self = shift;
1800     my $next = $self->nextToken();
1801     if ($next->value() eq "[") {
1802         $self->assertTokenValue($self->getToken(), "[", __LINE__);
1803         $self->assertTokenValue($self->getToken(), "]", __LINE__);
1804         return "[]" . $self->parseTypeSuffix();
1805     }
1806     return "";
1807 }
1808
1809 sub parseNull
1810 {
1811     my $self = shift;
1812     my $next = $self->nextToken();
1813     if ($next->value() eq "?") {
1814         $self->assertTokenValue($self->getToken(), "?", __LINE__);
1815         return "?";
1816     }
1817     return "";
1818 }
1819
1820 sub parseReturnType
1821 {
1822     my $self = shift;
1823     my $next = $self->nextToken();
1824     if ($next->value() eq "void") {
1825         $self->assertTokenValue($self->getToken(), "void", __LINE__);
1826         return "void";
1827     }
1828     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
1829         return $self->parseType();
1830     }
1831     $self->assertUnexpectedToken($next->value(), __LINE__);
1832 }
1833
1834 sub parseGet
1835 {
1836     my $self = shift;
1837     my $next = $self->nextToken();
1838     if ($next->value() eq "inherits") {
1839         my $attr = {};
1840         $self->parseInheritsGetter();
1841         $attr->{"inherits"} = 1;
1842         $attr->{"getraises"} = [];
1843         $attr->{"setraises"} = $self->parseSetRaises();
1844         return $attr;
1845     }
1846     if ($next->value() =~ /$nextGet_1/) {
1847         return $self->parseSetGetRaises();
1848     }
1849 }
1850
1851 sub parseInheritsGetter
1852 {
1853     my $self = shift;
1854     my $next = $self->nextToken();
1855     if ($next->value() eq "inherits") {
1856         $self->assertTokenValue($self->getToken(), "inherits", __LINE__);
1857         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
1858         return;
1859     }
1860     $self->assertUnexpectedToken($next->value(), __LINE__);
1861 }
1862
1863 sub parseSetGetRaises
1864 {
1865     my $self = shift;
1866     my $attr = {};
1867     $attr->{"inherits"} = 0;
1868
1869     my $next = $self->nextToken();
1870     if ($next->value() eq "setter") {
1871         $attr->{"setraises"} = $self->parseSetRaises();
1872         $attr->{"getraises"} = $self->parseGetRaises2();
1873         return $attr;
1874     }
1875     if ($next->value() eq "getter") {
1876         $attr->{"setraises"} = [];
1877         $attr->{"getraises"} = $self->parseGetRaises();
1878         return $attr;
1879     }
1880     if ($next->value() =~ /$nextSetGetRaises2_1/) {
1881         return $self->parseSetGetRaises2();
1882     }
1883     $self->assertUnexpectedToken($next->value(), __LINE__);
1884 }
1885
1886 sub parseGetRaises
1887 {
1888     my $self = shift;
1889     my $next = $self->nextToken();
1890
1891     if ($next->value() eq "getter") {
1892         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
1893         $self->assertTokenValue($self->getToken(), "raises", __LINE__);
1894         return $self->parseExceptionList();
1895     }
1896     $self->assertUnexpectedToken($next->value(), __LINE__);
1897 }
1898
1899 sub parseGetRaises2
1900 {
1901     my $self = shift;
1902     my $next = $self->nextToken();
1903
1904     if ($next->value() eq ",") {
1905         $self->assertTokenValue($self->getToken(), ",", __LINE__);
1906         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
1907         $self->assertTokenValue($self->getToken(), "raises", __LINE__);
1908         return $self->parseExceptionList();
1909     }
1910     return [];
1911 }
1912
1913 sub parseSetRaises
1914 {
1915     my $self = shift;
1916     my $next = $self->nextToken();
1917     if ($next->value() eq "setter") {
1918         $self->assertTokenValue($self->getToken(), "setter", __LINE__);
1919         $self->assertTokenValue($self->getToken(), "raises", __LINE__);
1920         return $self->parseExceptionList();
1921     }
1922     $self->assertUnexpectedToken($next->value(), __LINE__);
1923 }
1924
1925 sub parseSetGetRaises2
1926 {
1927     my $self = shift;
1928     my $next = $self->nextToken();
1929     if ($next->value() =~ /$nextSetGetRaises2_1/) {
1930         my $attr = {};
1931         $attr->{"inherits"} = 0;
1932         $attr->{"getraises"} = $self->parseGetRaises3();
1933         $attr->{"setraises"} = $self->parseSetRaises3();
1934         return $attr;
1935     }
1936     $self->assertUnexpectedToken($next->value(), __LINE__);
1937 }
1938
1939 sub parseGetRaises3
1940 {
1941     my $self = shift;
1942     my $next = $self->nextToken();
1943     if ($next->value() eq "getraises") {
1944         $self->assertTokenValue($self->getToken(), "getraises", __LINE__);
1945         return $self->parseExceptionList();
1946     }
1947     return [];
1948 }
1949
1950 sub parseSetRaises3
1951 {
1952     my $self = shift;
1953     my $next = $self->nextToken();
1954     if ($next->value() eq "setraises") {
1955         $self->assertTokenValue($self->getToken(), "setraises", __LINE__);
1956         return $self->parseExceptionList();
1957     }
1958     return [];
1959 }
1960
1961 sub parseExceptionList
1962 {
1963     my $self = shift;
1964     my $next = $self->nextToken();
1965     if ($next->value() eq "(") {
1966         my @exceptions = ();
1967         $self->assertTokenValue($self->getToken(), "(", __LINE__);
1968         push(@exceptions, @{$self->parseScopedNameList()});
1969         $self->assertTokenValue($self->getToken(), ")", __LINE__);
1970         return \@exceptions;
1971     }
1972     $self->assertUnexpectedToken($next->value(), __LINE__);
1973 }
1974
1975 sub parseRaises
1976 {
1977     my $self = shift;
1978     my $next = $self->nextToken();
1979     if ($next->value() eq "raises") {
1980         $self->assertTokenValue($self->getToken(), "raises", __LINE__);
1981         return $self->parseExceptionList();
1982     }
1983     return [];
1984 }
1985
1986 sub parseDefinitionOld
1987 {
1988     my $self = shift;
1989     my $next = $self->nextToken();
1990     if ($next->value() =~ /$nextDefinition_1/) {
1991         return $self->parseCallbackOrInterfaceOld();
1992     }
1993     if ($next->value() eq "partial") {
1994         return $self->parsePartial({});
1995     }
1996     if ($next->value() eq "dictionary") {
1997         return $self->parseDictionaryOld();
1998     }
1999     if ($next->value() eq "exception") {
2000         return $self->parseExceptionOld();
2001     }
2002     if ($next->value() eq "enum") {
2003         return $self->parseEnumOld();
2004     }
2005     if ($next->value() eq "typedef") {
2006         return $self->parseTypedef({});
2007     }
2008     if ($next->value() eq "module") {
2009         return $self->parseModule();
2010     }
2011     if ($next->type() == IdentifierToken || $next->value() eq "::") {
2012         return $self->parseImplementsStatement({});
2013     }
2014     $self->assertUnexpectedToken($next->value(), __LINE__);
2015 }
2016
2017 sub parseModule
2018 {
2019     my $self = shift;
2020     my $next = $self->nextToken();
2021     if ($next->value() eq "module") {
2022         my $document = new idlDocument();
2023         $self->assertTokenValue($self->getToken(), "module", __LINE__);
2024         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
2025         my $token = $self->getToken();
2026         $self->assertTokenType($token, IdentifierToken);
2027         $self->assertTokenValue($self->getToken(), "{", __LINE__);
2028         $document->module($token->value());
2029         my $definitions = $self->parseDefinitions();
2030         push(@{$document->classes}, @{$definitions});
2031         $self->assertTokenValue($self->getToken(), "}", __LINE__);
2032         $self->parseOptionalSemicolon();
2033         return $document;
2034     }
2035     $self->assertUnexpectedToken($next->value(), __LINE__);
2036 }
2037
2038 sub parseCallbackOrInterfaceOld
2039 {
2040     my $self = shift;
2041     my $next = $self->nextToken();
2042     if ($next->value() eq "callback") {
2043         $self->assertTokenValue($self->getToken(), "callback", __LINE__);
2044         return $self->parseCallbackRestOrInterface({});
2045     }
2046     if ($next->value() eq "interface") {
2047         return $self->parseInterfaceOld();
2048     }
2049     $self->assertUnexpectedToken($next->value(), __LINE__);
2050 }
2051
2052 sub parseInterfaceOld
2053 {
2054     my $self = shift;
2055     my $next = $self->nextToken();
2056     if ($next->value() eq "interface") {
2057         my $dataNode = new domClass();
2058         $self->assertTokenValue($self->getToken(), "interface", __LINE__);
2059         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
2060         my $token = $self->getToken();
2061         $self->assertTokenType($token, IdentifierToken);
2062         $dataNode->name($token->value());
2063         $dataNode->isException(0);
2064         push(@{$dataNode->parents}, @{$self->parseInheritance()});
2065         $self->assertTokenValue($self->getToken(), "{", __LINE__);
2066         my $interfaceMembers = $self->parseInterfaceMembers();
2067         $self->assertTokenValue($self->getToken(), "}", __LINE__);
2068         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2069         applyMemberList($dataNode, $interfaceMembers);
2070         applyExtendedAttributeList($dataNode, $extendedAttributeList);
2071         return $dataNode;
2072     }
2073     $self->assertUnexpectedToken($next->value(), __LINE__);
2074 }
2075
2076 sub parseInterfaceMemberOld
2077 {
2078     my $self = shift;
2079     my $next = $self->nextToken();
2080     if ($next->value() eq "const") {
2081         return $self->parseConst({});
2082     }
2083     if ($next->type() == IdentifierToken || $next->value() =~ /$nextInterfaceMemberOld_1/) {
2084         return $self->parseAttributeOrOperationOrIteratorOld();
2085     }
2086     $self->assertUnexpectedToken($next->value(), __LINE__);
2087 }
2088
2089 sub parseDictionaryOld
2090 {
2091     my $self = shift;
2092     my $next = $self->nextToken();
2093     if ($next->value() eq "dictionary") {
2094         $self->assertTokenValue($self->getToken(), "dictionary", __LINE__);
2095         $self->parseExtendedAttributeListAllowEmpty();
2096         $self->assertTokenType($self->getToken(), IdentifierToken);
2097         $self->parseInheritance();
2098         $self->assertTokenValue($self->getToken(), "{", __LINE__);
2099         $self->parseDictionaryMembers();
2100         $self->assertTokenValue($self->getToken(), "}", __LINE__);
2101         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2102         return;
2103     }
2104     $self->assertUnexpectedToken($next->value(), __LINE__);
2105 }
2106
2107 sub parseDictionaryMemberOld
2108 {
2109     my $self = shift;
2110     my $next = $self->nextToken();
2111     if ($next->type() == IdentifierToken || $next->value() =~ /$nextExceptionField_1/) {
2112         $self->parseType();
2113         $self->parseExtendedAttributeListAllowEmpty();
2114         $self->assertTokenType($self->getToken(), IdentifierToken);
2115         $self->parseDefault();
2116         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2117         return;
2118     }
2119     $self->assertUnexpectedToken($next->value(), __LINE__);
2120 }
2121
2122 sub parseExceptionOld
2123 {
2124     my $self = shift;
2125     my $next = $self->nextToken();
2126     if ($next->value() eq "exception") {
2127         my $dataNode = new domClass();
2128         $self->assertTokenValue($self->getToken(), "exception", __LINE__);
2129         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
2130         my $token = $self->getToken();
2131         $self->assertTokenType($token, IdentifierToken);
2132         $dataNode->name($token->value());
2133         $dataNode->isException(1);
2134         push(@{$dataNode->parents}, @{$self->parseInheritance()});
2135         $self->assertTokenValue($self->getToken(), "{", __LINE__);
2136         my $exceptionMembers = $self->parseInterfaceMembers();
2137         #$self->parseExceptionMembers();
2138         $self->assertTokenValue($self->getToken(), "}", __LINE__);
2139         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2140         applyMemberList($dataNode, $exceptionMembers);
2141         applyExtendedAttributeList($dataNode, $extendedAttributeList);
2142         return $dataNode;
2143     }
2144     $self->assertUnexpectedToken($next->value(), __LINE__);
2145 }
2146
2147 sub parseEnumOld
2148 {
2149     my $self = shift;
2150     my $next = $self->nextToken();
2151     if ($next->value() eq "enum") {
2152         $self->assertTokenValue($self->getToken(), "enum", __LINE__);
2153         $self->parseExtendedAttributeListAllowEmpty();
2154         $self->assertTokenType($self->getToken(), IdentifierToken);
2155         $self->assertTokenValue($self->getToken(), "{", __LINE__);
2156         $self->parseEnumValueList();
2157         $self->assertTokenValue($self->getToken(), "}", __LINE__);
2158         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2159         return;
2160     }
2161     $self->assertUnexpectedToken($next->value(), __LINE__);
2162 }
2163
2164 sub parseAttributeOrOperationOrIteratorOld
2165 {
2166     my $self = shift;
2167     my $next = $self->nextToken();
2168     if ($next->value() eq "serializer") {
2169         return $self->parseSerializer({});
2170     }
2171     if ($next->value() =~ /$nextAttributeOrOperationOrIterator_1/) {
2172         my $qualifier = $self->parseQualifier();
2173         my $dataNode = $self->parseAttributeOrOperationRestOld();
2174         if (defined ($dataNode) && $qualifier eq "static") {
2175             $dataNode->isStatic(1);
2176         }
2177         return $dataNode;
2178     }
2179     if ($next->value() =~ /$nextAttributeOld_1/) {
2180         return $self->parseAttributeOld();
2181     }
2182     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationOrIterator_2/) {
2183         return $self->parseOperationOrIterator({});
2184     }
2185     $self->assertUnexpectedToken($next->value(), __LINE__);
2186 }
2187
2188 sub parseAttributeOrOperationRestOld
2189 {
2190     my $self = shift;
2191     my $next = $self->nextToken();
2192     if ($next->value() =~ /$nextAttributeRest_1/) {
2193         return $self->parseAttributeRestOld();
2194     }
2195     if ($next->value() eq ";") {
2196         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2197         return;
2198     }
2199     if ($next->type() == IdentifierToken || $next->value() =~ /$nextAttributeOrOperationRest_1/) {
2200         my $returnType = $self->parseReturnType();
2201         my $dataNode = $self->parseOperationRest({});
2202         if (defined ($dataNode)) {
2203             $dataNode->signature->type($returnType);
2204         }
2205         return $dataNode;
2206     }
2207     $self->assertUnexpectedToken($next->value(), __LINE__);
2208 }
2209
2210 sub parseAttributeOld
2211 {
2212     my $self = shift;
2213     my $next = $self->nextToken();
2214     if ($next->value() =~ /$nextAttributeOld_1/) {
2215         $self->parseInherit();
2216         return $self->parseAttributeRestOld();
2217     }
2218     $self->assertUnexpectedToken($next->value(), __LINE__);
2219 }
2220
2221 sub parseAttributeRestOld
2222 {
2223     my $self = shift;
2224     my $next = $self->nextToken();
2225     if ($next->value() =~ /$nextAttributeRest_1/) {
2226         my $newDataNode = new domAttribute();
2227         if ($self->parseReadOnly()) {
2228             $newDataNode->type("readonly attribute");
2229         } else {
2230             $newDataNode->type("attribute");
2231         }
2232         $self->assertTokenValue($self->getToken(), "attribute", __LINE__);
2233         my $extendedAttributeList = $self->parseExtendedAttributeListAllowEmpty();
2234         $newDataNode->signature(new domSignature());
2235         $newDataNode->signature->type($self->parseType());
2236         $newDataNode->signature->extendedAttributes($extendedAttributeList);
2237         my $token = $self->getToken();
2238         $self->assertTokenType($token, IdentifierToken);
2239         $newDataNode->signature->name($token->value());
2240         my $getRef = $self->parseGet();
2241         if (defined $getRef) {
2242             push(@{$newDataNode->getterExceptions}, @{$getRef->{"getraises"}});
2243             push(@{$newDataNode->setterExceptions}, @{$getRef->{"setraises"}});
2244         }
2245         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2246         return $newDataNode;
2247     }
2248     $self->assertUnexpectedToken($next->value(), __LINE__);
2249 }
2250
2251 sub parseIn
2252 {
2253     my $self = shift;
2254     my $next = $self->nextToken();
2255     if ($next->value() eq "in") {
2256         $self->assertTokenValue($self->getToken(), "in", __LINE__);
2257         return "in";
2258     }
2259     return "";
2260 }
2261
2262 sub parseOptionalSemicolon
2263 {
2264     my $self = shift;
2265     my $next = $self->nextToken();
2266     if ($next->value() eq ";") {
2267         $self->assertTokenValue($self->getToken(), ";", __LINE__);
2268     }
2269 }
2270
2271 sub parseScopedName
2272 {
2273     my $self = shift;
2274     my $next = $self->nextToken();
2275     if ($next->value() eq "::") {
2276         return $self->parseAbsoluteScopedName();
2277     }
2278     if ($next->type() == IdentifierToken) {
2279         return $self->parseRelativeScopedName();
2280     }
2281     $self->assertUnexpectedToken($next->value());
2282 }
2283
2284 sub parseAbsoluteScopedName
2285 {
2286     my $self = shift;
2287     my $next = $self->nextToken();
2288     if ($next->value() eq "::") {
2289         $self->assertTokenValue($self->getToken(), "::");
2290         my $token = $self->getToken();
2291         $self->assertTokenType($token, IdentifierToken);
2292         return "::" . $token->value() . $self->parseScopedNameParts();
2293     }
2294     $self->assertUnexpectedToken($next->value());
2295 }
2296
2297 sub parseRelativeScopedName
2298 {
2299     my $self = shift;
2300     my $next = $self->nextToken();
2301     if ($next->type() == IdentifierToken) {
2302         my $token = $self->getToken();
2303         return $token->value() . $self->parseScopedNameParts();
2304     }
2305     $self->assertUnexpectedToken($next->value());
2306 }
2307
2308 sub parseScopedNameParts
2309 {
2310     my $self = shift;
2311     my @names = ();
2312
2313     while (1) {
2314         my $next = $self->nextToken();
2315         if ($next->value() eq "::") {
2316             $self->assertTokenValue($self->getToken(), "::");
2317             push(@names, "::");
2318             my $token = $self->getToken();
2319             $self->assertTokenType($token, IdentifierToken);
2320             push(@names, $token->value());
2321         } else {
2322             last;
2323         }
2324     }
2325     return join("", @names);
2326 }
2327
2328 sub parseScopedNameList
2329 {
2330     my $self = shift;
2331     my $next = $self->nextToken();
2332     if ($next->type() == IdentifierToken || $next->value() eq "::") {
2333         my @names = ();
2334         push(@names, $self->parseScopedName());
2335         push(@names, @{$self->parseScopedNames()});
2336         return \@names;
2337     }
2338     $self->assertUnexpectedToken($next->value(), __LINE__);
2339 }
2340
2341 sub parseScopedNames
2342 {
2343     my $self = shift;
2344     my @names = ();
2345
2346     while (1) {
2347         my $next = $self->nextToken();
2348         if ($next->value() eq ",") {
2349             $self->assertTokenValue($self->getToken(), ",");
2350             push(@names, $self->parseScopedName());
2351         } else {
2352             last;
2353         }
2354     }
2355     return \@names;
2356 }
2357
2358 sub applyMemberList
2359 {
2360     my $dataNode = shift;
2361     my $members = shift;
2362
2363     for my $item (@{$members}) {
2364         if (ref($item) eq "domAttribute") {
2365             push(@{$dataNode->attributes}, $item);
2366             next;
2367         }
2368         if (ref($item) eq "domConstant") {
2369             push(@{$dataNode->constants}, $item);
2370             next;
2371         }
2372         if (ref($item) eq "domFunction") {
2373             push(@{$dataNode->functions}, $item);
2374             next;
2375         }
2376     }
2377 }
2378
2379 sub applyExtendedAttributeList
2380 {
2381     my $dataNode = shift;
2382     my $extendedAttributeList = shift;
2383
2384     if (defined $extendedAttributeList->{"Constructor"}) {
2385         my $newDataNode = new domFunction();
2386         $newDataNode->signature(new domSignature());
2387         $newDataNode->signature->name("Constructor");
2388         $newDataNode->signature->extendedAttributes($extendedAttributeList);
2389         push(@{$newDataNode->parameters}, @{$extendedAttributeList->{"Constructor"}});
2390         $extendedAttributeList->{"Constructor"} = "VALUE_IS_MISSING";
2391         $dataNode->constructor($newDataNode);
2392     } elsif (defined $extendedAttributeList->{"NamedConstructor"}) {
2393         my $newDataNode = new domFunction();
2394         $newDataNode->signature(new domSignature());
2395         $newDataNode->signature->name("NamedConstructor");
2396         $newDataNode->signature->extendedAttributes($extendedAttributeList);
2397         my %attributes = %{$extendedAttributeList->{"NamedConstructor"}};
2398         my @attributeKeys = keys (%attributes);
2399         my $constructorName = $attributeKeys[0];
2400         push(@{$newDataNode->parameters}, @{$attributes{$constructorName}});
2401         $extendedAttributeList->{"NamedConstructor"} = $constructorName;
2402         $dataNode->constructor($newDataNode);
2403     }
2404     $dataNode->extendedAttributes($extendedAttributeList);
2405 }
2406
2407 1;
2408