| 250 |
$state = 'before def'; |
$state = 'before def'; |
| 251 |
} elsif ($token->{type} eq '}' and @current > 1) { |
} elsif ($token->{type} eq '}' and @current > 1) { |
| 252 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 253 |
$state = 'before semicolon'; |
$state = 'before block semicolon'; |
|
$next_state = 'before definitions'; |
|
| 254 |
} elsif ($token->{type} eq 'eof') { |
} elsif ($token->{type} eq 'eof') { |
| 255 |
last; |
last; |
| 256 |
} else { |
} else { |
| 262 |
$next_state = 'before definitions'; |
$next_state = 'before definitions'; |
| 263 |
} |
} |
| 264 |
} elsif ($state eq 'before xattr') { |
} elsif ($state eq 'before xattr') { |
|
|
|
|
## TODO: methodType methodName ([broken xattr] ...); is not well |
|
|
## handled on forward-compatible parsing (i.e. pop @current). |
|
|
|
|
| 265 |
if ($token->{type} eq 'identifier') { |
if ($token->{type} eq 'identifier') { |
| 266 |
## TODO: _escape |
## TODO: _escape |
| 267 |
## ISSUE: Duplicate attributes |
## ISSUE: Duplicate attributes |
| 465 |
$state = 'before const type'; |
$state = 'before const type'; |
| 466 |
$next_state = 'before definitions'; |
$next_state = 'before definitions'; |
| 467 |
next; |
next; |
|
} elsif ($token->{type} eq 'eof') { |
|
|
## NOTE: Any extended attributes are ignored. |
|
|
$onerror->(type => 'before def:eof', level => 'm', token => $token); |
|
|
last; |
|
| 468 |
} else { |
} else { |
| 469 |
$onerror->(type => 'before definition', level => 'm', |
$onerror->(type => 'before definition', level => 'm', |
| 470 |
token => $token); |
token => $token); |
| 509 |
} |
} |
| 510 |
} else { |
} else { |
| 511 |
$onerror->(type => 'scoped name', level => $self->{must_level}); |
$onerror->(type => 'scoped name', level => $self->{must_level}); |
|
pop @current; # interface |
|
| 512 |
# reconsume |
# reconsume |
| 513 |
$state = 'ignore'; |
$state = 'ignore'; |
| 514 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before definitions'; |
|
| 515 |
} |
} |
| 516 |
} elsif ($state eq 'before exception name') { |
} elsif ($state eq 'before exception name') { |
| 517 |
my $name = $get_scoped_name->(); |
my $name = $get_scoped_name->(); |
| 538 |
} else { |
} else { |
| 539 |
$onerror->(type => 'after exception name', |
$onerror->(type => 'after exception name', |
| 540 |
level => $self->{must_level}); |
level => $self->{must_level}); |
|
pop @current; # operation/attribute |
|
| 541 |
# reconsume |
# reconsume |
| 542 |
$state = 'ignore'; |
$state = 'ignore'; |
| 543 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 544 |
} |
} |
| 545 |
} else { |
} else { |
| 546 |
$onerror->(type => 'scoped name', level => $self->{must_level}); |
$onerror->(type => 'scoped name', level => $self->{must_level}); |
|
pop @current; # operation/attribute |
|
| 547 |
# reconsume |
# reconsume |
| 548 |
$state = 'ignore'; |
$state = 'ignore'; |
| 549 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 550 |
} |
} |
| 551 |
} elsif ($state eq 'before interface block') { |
} elsif ($state eq 'before interface block') { |
| 552 |
if ($token->{type} eq '{') { |
if ($token->{type} eq '{') { |
| 557 |
$onerror->(type => 'before interface block', |
$onerror->(type => 'before interface block', |
| 558 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 559 |
# reconsume |
# reconsume |
|
pop @current; # interface |
|
| 560 |
$state = 'ignore'; |
$state = 'ignore'; |
| 561 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before definitions'; |
|
| 562 |
} |
} |
| 563 |
} elsif ($state eq 'before exception block') { |
} elsif ($state eq 'before exception block') { |
| 564 |
if ($token->{type} eq '{') { |
if ($token->{type} eq '{') { |
| 569 |
$onerror->(type => 'before exception block', |
$onerror->(type => 'before exception block', |
| 570 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 571 |
# reconsume |
# reconsume |
|
pop @current; # exception |
|
| 572 |
$state = 'ignore'; |
$state = 'ignore'; |
| 573 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before definitions'; |
|
| 574 |
} |
} |
| 575 |
} elsif ($state eq 'before members') { |
} elsif ($state eq 'before members') { |
| 576 |
$xattrs = []; |
$xattrs = []; |
| 580 |
#$next_state = $next_state; # 'before interface member' or ... |
#$next_state = $next_state; # 'before interface member' or ... |
| 581 |
} elsif ($token->{type} eq '}') { |
} elsif ($token->{type} eq '}') { |
| 582 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 583 |
$state = 'before semicolon'; |
$state = 'before block semicolon'; |
|
$next_state = 'before definitions'; |
|
| 584 |
} else { |
} else { |
| 585 |
# reconsume |
# reconsume |
| 586 |
$state = $next_state; # ... 'before exception member' |
$state = $next_state; # ... 'before exception member' |
| 618 |
$state = 'before semicolon'; |
$state = 'before semicolon'; |
| 619 |
$next_state = 'before definitions'; |
$next_state = 'before definitions'; |
| 620 |
} elsif ($token->{type} eq 'eof') { |
} elsif ($token->{type} eq 'eof') { |
|
$onerror->(type => 'before interface member:eof', |
|
|
level => $self->{must_level}); |
|
|
$current[-2]->append_child ($current[-1]); |
|
| 621 |
last; |
last; |
| 622 |
} else { |
} else { |
| 623 |
$onerror->(type => 'before interface member', |
$onerror->(type => 'before interface member', |
| 624 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 625 |
# reconsume |
# reconsume |
|
pop @current; # interface |
|
| 626 |
$state = 'ignore'; |
$state = 'ignore'; |
| 627 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 628 |
} |
} |
| 629 |
} elsif ($state eq 'before exception member') { |
} elsif ($state eq 'before exception member') { |
| 630 |
if ({ |
if ({ |
| 639 |
$state = 'before semicolon'; |
$state = 'before semicolon'; |
| 640 |
$next_state = 'before definitions'; |
$next_state = 'before definitions'; |
| 641 |
} elsif ($token->{type} eq 'eof') { |
} elsif ($token->{type} eq 'eof') { |
|
$onerror->(type => 'before exception member:eof', |
|
|
level => $self->{must_level}); |
|
|
$current[-2]->append_child ($current[-1]); |
|
| 642 |
last; |
last; |
| 643 |
} else { |
} else { |
| 644 |
$onerror->(type => 'before exception member', |
$onerror->(type => 'before exception member', |
| 645 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 646 |
# reconsume |
# reconsume |
|
pop @current; # interface |
|
| 647 |
$state = 'ignore'; |
$state = 'ignore'; |
| 648 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before exception member'; |
|
| 649 |
} |
} |
| 650 |
} elsif ($state eq 'before typedef type') { |
} elsif ($state eq 'before typedef type') { |
| 651 |
if ({ |
if ({ |
| 867 |
$state = 'before argument identifier'; |
$state = 'before argument identifier'; |
| 868 |
} else { |
} else { |
| 869 |
# reconsume |
# reconsume |
|
pop @current; # operation |
|
| 870 |
$state = 'ignore'; |
$state = 'ignore'; |
| 871 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 872 |
} |
} |
| 873 |
} else { |
} else { |
| 874 |
$onerror->(type => 'before type', level => $self->{must_level}); |
$onerror->(type => 'before type', level => $self->{must_level}); |
|
pop @current; # operation |
|
| 875 |
# reconsume |
# reconsume |
| 876 |
$state = 'ignore'; |
$state = 'ignore'; |
| 877 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 878 |
} |
} |
| 879 |
} elsif ($state eq 'before attribute identifier') { |
} elsif ($state eq 'before attribute identifier') { |
| 880 |
if ($token->{type} eq 'identifier') { |
if ($token->{type} eq 'identifier') { |
| 924 |
# reconsume |
# reconsume |
| 925 |
$state = 'ignore'; |
$state = 'ignore'; |
| 926 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before exception member'; |
|
| 927 |
} |
} |
| 928 |
} elsif ($state eq 'before operation identifier') { |
} elsif ($state eq 'before operation identifier') { |
| 929 |
if ($token->{type} eq 'identifier') { |
if ($token->{type} eq 'identifier') { |
| 945 |
next; |
next; |
| 946 |
} |
} |
| 947 |
} else { |
} else { |
|
pop @current; |
|
| 948 |
$onerror->(type => 'arguments lparen', |
$onerror->(type => 'arguments lparen', |
| 949 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 950 |
# |
# |
| 988 |
level => $self->{must_level}); |
level => $self->{must_level}); |
| 989 |
# |
# |
| 990 |
} |
} |
|
pop @current; # operation |
|
| 991 |
# reconsume |
# reconsume |
| 992 |
$state = 'ignore'; |
$state = 'ignore'; |
| 993 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 994 |
} elsif ($state eq 'before argument') { |
} elsif ($state eq 'before argument') { |
| 995 |
$xattrs = []; |
$xattrs = []; |
| 996 |
if ($token->{type} eq '[') { |
if ($token->{type} eq '[') { |
| 1008 |
} else { |
} else { |
| 1009 |
$onerror->(type => 'argument in', |
$onerror->(type => 'argument in', |
| 1010 |
level => $self->{must_level}); |
level => $self->{must_level}); |
|
pop @current; # operation |
|
| 1011 |
$state = 'ignore'; |
$state = 'ignore'; |
| 1012 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 1013 |
} |
} |
| 1014 |
} elsif ($state eq 'before raises') { |
} elsif ($state eq 'before raises') { |
| 1015 |
if ($token->{type} eq 'raises') { |
if ($token->{type} eq 'raises') { |
| 1028 |
} else { |
} else { |
| 1029 |
$onerror->(type => 'raises lparen', |
$onerror->(type => 'raises lparen', |
| 1030 |
level => $self->{must_level}); |
level => $self->{must_level}); |
|
pop @current; # operation |
|
| 1031 |
$state = 'ignore'; |
$state = 'ignore'; |
| 1032 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before interface member'; |
|
| 1033 |
} |
} |
| 1034 |
} elsif ($state eq 'before semicolon') { |
} elsif ($state eq 'before semicolon') { |
| 1035 |
if ($token->{type} eq ';') { |
if ($token->{type} eq ';') { |
| 1036 |
$current[-2]->append_child ($current[-1]); |
$current[-2]->append_child ($current[-1]); |
| 1037 |
pop @current; |
pop @current; |
| 1038 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 1039 |
$state = { |
if ($current[-1]->isa ('Whatpm::WebIDL::Definitions') or |
| 1040 |
#'before definitions', |
$current[-1]->isa ('Whatpm::WebIDL::Module')) { |
| 1041 |
'before interface member' => 'before members', # keep $next_state |
$state = 'before definitions'; |
| 1042 |
'before exception member' => 'before members', # as is |
} elsif ($current[-1]->isa ('Whatpm::WebIDL::Interface')) { |
| 1043 |
}->{$next_state} || $next_state; |
$state = 'before members'; |
| 1044 |
|
$next_state = 'before interface member'; |
| 1045 |
|
} else { |
| 1046 |
|
$state = 'before members'; |
| 1047 |
|
$next_state = 'before exception member'; |
| 1048 |
|
} |
| 1049 |
} else { |
} else { |
| 1050 |
|
$onerror->(type => 'before semicolon', level => 'm', |
| 1051 |
|
token => $token); |
| 1052 |
|
# reconsume |
| 1053 |
|
$state = 'ignore'; |
| 1054 |
|
$nest_level = 0; |
| 1055 |
|
} |
| 1056 |
|
} elsif ($state eq 'before block semicolon') { |
| 1057 |
|
if ($token->{type} eq ';') { |
| 1058 |
|
$current[-2]->append_child ($current[-1]); |
| 1059 |
pop @current; |
pop @current; |
| 1060 |
|
$token = $get_next_token->(); |
| 1061 |
|
if ($current[-1]->isa ('Whatpm::WebIDL::Definitions') or |
| 1062 |
|
$current[-1]->isa ('Whatpm::WebIDL::Module')) { |
| 1063 |
|
$state = 'before definitions'; |
| 1064 |
|
} elsif ($current[-1]->isa ('Whatpm::WebIDL::Interface')) { |
| 1065 |
|
$state = 'before members'; |
| 1066 |
|
$next_state = 'before interface member'; |
| 1067 |
|
} else { |
| 1068 |
|
$state = 'before members'; |
| 1069 |
|
$next_state = 'before exception member'; |
| 1070 |
|
} |
| 1071 |
|
} else { |
| 1072 |
$onerror->(type => 'before semicolon', level => 'm', |
$onerror->(type => 'before semicolon', level => 'm', |
| 1073 |
token => $token); |
token => $token); |
| 1074 |
|
pop @current; # avoid appended by 'ignore' |
| 1075 |
# reconsume |
# reconsume |
| 1076 |
$state = 'ignore'; |
$state = 'ignore'; |
| 1077 |
$nest_level = 0; |
$nest_level = 0; |
|
$next_state = 'before definitions'; |
|
| 1078 |
} |
} |
| 1079 |
} elsif ($state eq 'ignore') { |
} elsif ($state eq 'ignore') { |
| 1080 |
if (($nest_level == 0 and $token->{type} eq ';') or |
if ($nest_level == 0 and $token->{type} eq ';') { |
| 1081 |
(@current > 1 and not $nest_level and $token->{type} eq '}')) { |
while (@current > 1) { |
| 1082 |
|
if ($current[-1]->isa ('Whatpm::WebIDL::Interface') or |
| 1083 |
|
$current[-1]->isa ('Whatpm::WebIDL::Exception') or |
| 1084 |
|
$current[-1]->isa ('Whatpm::WebIDL::Module')) { |
| 1085 |
|
last; |
| 1086 |
|
} |
| 1087 |
|
pop @current; |
| 1088 |
|
} |
| 1089 |
|
|
| 1090 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 1091 |
$state = { |
if ($current[-1]->isa ('Whatpm::WebIDL::Definitions') or |
| 1092 |
#'before definitions', |
$current[-1]->isa ('Whatpm::WebIDL::Module')) { |
| 1093 |
'before interface member' => 'before members', # keep $next_state |
$state = 'before definitions'; |
| 1094 |
'before exception member' => 'before members', # as is |
} elsif ($current[-1]->isa ('Whatpm::WebIDL::Interface')) { |
| 1095 |
}->{$next_state} || $next_state; |
$state = 'before members'; |
| 1096 |
|
$next_state = 'before interface member'; |
| 1097 |
|
} else { |
| 1098 |
|
$state = 'before members'; |
| 1099 |
|
$next_state = 'before exception member'; |
| 1100 |
|
} |
| 1101 |
} elsif ($token->{type} eq '{') { |
} elsif ($token->{type} eq '{') { |
| 1102 |
$nest_level++; |
$nest_level++; |
| 1103 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 1107 |
$token = $get_next_token->(); |
$token = $get_next_token->(); |
| 1108 |
# stay in the state |
# stay in the state |
| 1109 |
} elsif ($token->{type} eq 'eof') { |
} elsif ($token->{type} eq 'eof') { |
| 1110 |
|
while (@current > 1) { |
| 1111 |
|
if ($current[-1]->isa ('Whatpm::WebIDL::Interface') or |
| 1112 |
|
$current[-1]->isa ('Whatpm::WebIDL::Exception') or |
| 1113 |
|
$current[-1]->isa ('Whatpm::WebIDL::Module')) { |
| 1114 |
|
last; |
| 1115 |
|
} |
| 1116 |
|
pop @current; |
| 1117 |
|
} |
| 1118 |
|
|
| 1119 |
last; |
last; |
| 1120 |
} else { |
} else { |
| 1121 |
# ignore the token |
# ignore the token |
| 1128 |
} |
} |
| 1129 |
|
|
| 1130 |
if (@current > 1) { |
if (@current > 1) { |
| 1131 |
$onerror->(type => 'block not closed', level => $self->{must_level}); |
$onerror->(type => 'premature end of file', level => $self->{must_level}); |
| 1132 |
|
while (@current > 1) { |
| 1133 |
|
$current[-2]->append_child ($current[-1]); |
| 1134 |
|
pop @current; |
| 1135 |
|
} |
| 1136 |
} |
} |
| 1137 |
|
|
| 1138 |
$get_type = undef; # unlink loop |
$get_type = undef; # unlink loop |