~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/bindings/scripts/IDLParser.pm

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

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