/[suikacvs]/markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src
Suika

Diff of /markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17 by wakaba, Sun Oct 19 04:39:25 2008 UTC revision 1.26 by wakaba, Thu Jul 2 21:42:43 2009 UTC
# Line 177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO Line 177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATIO
177  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }
178  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }  sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }
179  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }  sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }
180  sub BOGUS_MD_STATE () { 85 }  sub BEFORE_NDATA_STATE () { 85 }
181    sub NDATA_STATE () { 86 }
182    sub AFTER_NDATA_STATE () { 87 }
183    sub BEFORE_NOTATION_NAME_STATE () { 88 }
184    sub NOTATION_NAME_STATE () { 89 }
185    sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
186    sub DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE () { 91 }
187    sub ENTITY_VALUE_ENTITY_STATE () { 92 }
188    sub AFTER_ELEMENT_NAME_STATE () { 93 }
189    sub BEFORE_ELEMENT_CONTENT_STATE () { 94 }
190    sub CONTENT_KEYWORD_STATE () { 95 }
191    sub AFTER_CM_GROUP_OPEN_STATE () { 96 }
192    sub CM_ELEMENT_NAME_STATE () { 97 }
193    sub AFTER_CM_ELEMENT_NAME_STATE () { 98 }
194    sub AFTER_CM_GROUP_CLOSE_STATE () { 99 }
195    sub AFTER_MD_DEF_STATE () { 100 }
196    sub BOGUS_MD_STATE () { 101 }
197    
198  ## Tree constructor state constants (see Whatpm::HTML for the full  ## Tree constructor state constants (see Whatpm::HTML for the full
199  ## list and descriptions)  ## list and descriptions)
# Line 1254  sub _get_next_token ($) { Line 1270  sub _get_next_token ($) {
1270    
1271          redo A;          redo A;
1272        } else {        } else {
1273          if ($self->{nc} == 0x003D) { # =          if ($self->{nc} == 0x003D or $self->{nc} == 0x003C) { # =, <
1274            !!!cp (93);            !!!cp (93);
1275            ## XML5: Not a parse error.            ## XML5: Not a parse error.
1276            !!!parse-error (type => 'bad attribute value');            !!!parse-error (type => 'bad attribute value');
# Line 1300  sub _get_next_token ($) { Line 1316  sub _get_next_token ($) {
1316          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1317          !!!next-input-character;          !!!next-input-character;
1318          redo A;          redo A;
1319          } elsif ($self->{is_xml} and
1320                   $is_space->{$self->{nc}}) {
1321            !!!cp (97.1);
1322            $self->{ca}->{value} .= ' ';
1323            ## Stay in the state.
1324            !!!next-input-character;
1325            redo A;
1326        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1327          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1328          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1347  sub _get_next_token ($) { Line 1370  sub _get_next_token ($) {
1370          }          }
1371          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1372          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1373                                q["&<],                                qq["&<\x09\x0C\x20],
1374                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1375    
1376          ## Stay in the state          ## Stay in the state
# Line 1384  sub _get_next_token ($) { Line 1407  sub _get_next_token ($) {
1407          $self->{state} = ENTITY_STATE;          $self->{state} = ENTITY_STATE;
1408          !!!next-input-character;          !!!next-input-character;
1409          redo A;          redo A;
1410          } elsif ($self->{is_xml} and
1411                   $is_space->{$self->{nc}}) {
1412            !!!cp (103.1);
1413            $self->{ca}->{value} .= ' ';
1414            ## Stay in the state.
1415            !!!next-input-character;
1416            redo A;
1417        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
1418          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1419          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
# Line 1431  sub _get_next_token ($) { Line 1461  sub _get_next_token ($) {
1461          }          }
1462          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1463          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1464                                q['&<],                                qq['&<\x09\x0C\x20],
1465                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1466    
1467          ## Stay in the state          ## Stay in the state
# Line 1543  sub _get_next_token ($) { Line 1573  sub _get_next_token ($) {
1573               0x0022 => 1, # "               0x0022 => 1, # "
1574               0x0027 => 1, # '               0x0027 => 1, # '
1575               0x003D => 1, # =               0x003D => 1, # =
1576                 0x003C => 1, # <
1577              }->{$self->{nc}}) {              }->{$self->{nc}}) {
1578            !!!cp (115);            !!!cp (115);
1579            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1552  sub _get_next_token ($) { Line 1583  sub _get_next_token ($) {
1583          }          }
1584          $self->{ca}->{value} .= chr ($self->{nc});          $self->{ca}->{value} .= chr ($self->{nc});
1585          $self->{read_until}->($self->{ca}->{value},          $self->{read_until}->($self->{ca}->{value},
1586                                q["'=& >],                                qq["'=& \x09\x0C>],
1587                                length $self->{ca}->{value});                                length $self->{ca}->{value});
1588    
1589          ## Stay in the state          ## Stay in the state
# Line 2256  sub _get_next_token ($) { Line 2287  sub _get_next_token ($) {
2287          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
2288          !!!next-input-character;          !!!next-input-character;
2289          redo A;          redo A;
2290  ## TODO: " and ' for ENTITY        } elsif ($self->{nc} == 0x0022 and # "
2291                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2292                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2293            !!!cp (167.21);
2294            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
2295            $self->{ct}->{value} = ''; # ENTITY
2296            !!!next-input-character;
2297            redo A;
2298          } elsif ($self->{nc} == 0x0027 and # '
2299                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2300                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2301            !!!cp (167.22);
2302            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
2303            $self->{ct}->{value} = ''; # ENTITY
2304            !!!next-input-character;
2305            redo A;
2306        } elsif ($self->{is_xml} and        } elsif ($self->{is_xml} and
2307                 $self->{ct}->{type} == DOCTYPE_TOKEN and                 $self->{ct}->{type} == DOCTYPE_TOKEN and
2308                 $self->{nc} == 0x005B) { # [                 $self->{nc} == 0x005B) { # [
# Line 2812  sub _get_next_token ($) { Line 2858  sub _get_next_token ($) {
2858        }        }
2859      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2860        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2861          !!!cp (215);          if ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN) {
2862          ## Stay in the state            !!!cp (215.1);
2863              $self->{state} = BEFORE_NDATA_STATE;
2864            } else {
2865              !!!cp (215);
2866              ## Stay in the state
2867            }
2868          !!!next-input-character;          !!!next-input-character;
2869          redo A;          redo A;
2870        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
# Line 2829  sub _get_next_token ($) { Line 2880  sub _get_next_token ($) {
2880          !!!next-input-character;          !!!next-input-character;
2881          !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION          !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2882          redo A;          redo A;
2883  ## TODO: "NDATA"        } elsif ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN and
2884                   ($self->{nc} == 0x004E or # N
2885                    $self->{nc} == 0x006E)) { # n
2886            !!!cp (216.2);
2887            !!!parse-error (type => 'no space before NDATA'); ## TODO: type
2888            $self->{state} = NDATA_STATE;
2889            $self->{kwd} = chr $self->{nc};
2890            !!!next-input-character;
2891            redo A;
2892        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2893          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2894            !!!cp (217);            !!!cp (217);
# Line 2871  sub _get_next_token ($) { Line 2930  sub _get_next_token ($) {
2930          !!!next-input-character;          !!!next-input-character;
2931          redo A;          redo A;
2932        }        }
2933        } elsif ($self->{state} == BEFORE_NDATA_STATE) {
2934          if ($is_space->{$self->{nc}}) {
2935            !!!cp (218.3);
2936            ## Stay in the state.
2937            !!!next-input-character;
2938            redo A;
2939          } elsif ($self->{nc} == 0x003E) { # >
2940            !!!cp (218.4);
2941            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2942            !!!next-input-character;
2943            !!!emit ($self->{ct}); # ENTITY
2944            redo A;
2945          } elsif ($self->{nc} == 0x004E or # N
2946                   $self->{nc} == 0x006E) { # n
2947            !!!cp (218.5);
2948            $self->{state} = NDATA_STATE;
2949            $self->{kwd} = chr $self->{nc};
2950            !!!next-input-character;
2951            redo A;
2952          } elsif ($self->{nc} == -1) {
2953            !!!cp (218.6);
2954            !!!parse-error (type => 'unclosed md'); ## TODO: type
2955            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2956            ## reconsume
2957            !!!emit ($self->{ct}); # ENTITY
2958            redo A;
2959          } else {
2960            !!!cp (218.7);
2961            !!!parse-error (type => 'string after SYSTEM literal');
2962            $self->{state} = BOGUS_MD_STATE;
2963            !!!next-input-character;
2964            redo A;
2965          }
2966      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {      } elsif ($self->{state} == BOGUS_DOCTYPE_STATE) {
2967        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
2968          !!!cp (219);          !!!cp (219);
# Line 3001  sub _get_next_token ($) { Line 3093  sub _get_next_token ($) {
3093              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3094              $self->{entity_add} => 1,              $self->{entity_add} => 1,
3095            }->{$self->{nc}}) {            }->{$self->{nc}}) {
3096          !!!cp (1001);          if ($self->{is_xml}) {
3097              !!!cp (1001.1);
3098              !!!parse-error (type => 'bare ero',
3099                              line => $self->{line_prev},
3100                              column => $self->{column_prev}
3101                                  + ($self->{nc} == -1 ? 1 : 0));
3102            } else {
3103              !!!cp (1001);
3104              ## No error
3105            }
3106          ## Don't consume          ## Don't consume
         ## No error  
3107          ## Return nothing.          ## Return nothing.
3108          #          #
3109        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 3012  sub _get_next_token ($) { Line 3112  sub _get_next_token ($) {
3112          $self->{kwd} = '#';          $self->{kwd} = '#';
3113          !!!next-input-character;          !!!next-input-character;
3114          redo A;          redo A;
3115        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
3116                   (0x0041 <= $self->{nc} and
3117                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
3118                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
3119                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 3056  sub _get_next_token ($) { Line 3157  sub _get_next_token ($) {
3157          redo A;          redo A;
3158        }        }
3159      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
3160        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
           $self->{nc} == 0x0058) { # X  
3161          !!!cp (995);          !!!cp (995);
3162          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
3163          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3164          !!!next-input-character;          !!!next-input-character;
3165          redo A;          redo A;
3166          } elsif ($self->{nc} == 0x0058) { # X
3167            !!!cp (995.1);
3168            if ($self->{is_xml}) {
3169              !!!parse-error (type => 'uppercase hcro'); ## TODO: type
3170            }
3171            $self->{state} = HEXREF_X_STATE;
3172            $self->{kwd} .= chr $self->{nc};
3173            !!!next-input-character;
3174            redo A;
3175        } elsif (0x0030 <= $self->{nc} and        } elsif (0x0030 <= $self->{nc} and
3176                 $self->{nc} <= 0x0039) { # 0..9                 $self->{nc} <= 0x0039) { # 0..9
3177          !!!cp (994);          !!!cp (994);
# Line 3123  sub _get_next_token ($) { Line 3232  sub _get_next_token ($) {
3232        my $code = $self->{kwd};        my $code = $self->{kwd};
3233        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3234        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3235        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3236              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3237              ($self->{is_xml} and $code == 0x0000)) {
3238          !!!cp (1015);          !!!cp (1015);
3239          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3240                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3236  sub _get_next_token ($) { Line 3347  sub _get_next_token ($) {
3347        my $code = $self->{kwd};        my $code = $self->{kwd};
3348        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3349        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3350        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3351              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3352              ($self->{is_xml} and $code == 0x0000)) {
3353          !!!cp (1008);          !!!cp (1008);
3354          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3355                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3270  sub _get_next_token ($) { Line 3383  sub _get_next_token ($) {
3383          redo A;          redo A;
3384        }        }
3385      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
3386        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
3387            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
3388            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
3389              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
3390             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
3391              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
3392             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
3393              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
3394             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
3395                    {
3396                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3397                      $self->{entity_add} => 1,
3398                    }->{$self->{nc}}))) {
3399          our $EntityChar;          our $EntityChar;
3400          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3401          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
3402                $self->{ge}->{$self->{kwd}}) {
3403            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
3404              !!!cp (1020);              if (defined $self->{ge}->{$self->{kwd}}) {
3405              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
3406                    !!!cp (1020.1);
3407                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
3408                  } else {
3409                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
3410                      !!!cp (1020.2);
3411                      !!!parse-error (type => 'unparsed entity', ## TODO: type
3412                                      value => $self->{kwd});
3413                    } else {
3414                      !!!cp (1020.3);
3415                    }
3416                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
3417                  }
3418                } else {
3419                  if ($self->{is_xml}) {
3420                    !!!cp (1020.4);
3421                    !!!parse-error (type => 'entity not declared', ## TODO: type
3422                                    value => $self->{kwd},
3423                                    level => {
3424                                              'amp;' => $self->{level}->{warn},
3425                                              'quot;' => $self->{level}->{warn},
3426                                              'lt;' => $self->{level}->{warn},
3427                                              'gt;' => $self->{level}->{warn},
3428                                              'apos;' => $self->{level}->{warn},
3429                                             }->{$self->{kwd}} ||
3430                                             $self->{level}->{must});
3431                  } else {
3432                    !!!cp (1020);
3433                  }
3434                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
3435                }
3436              $self->{entity__match} = 1;              $self->{entity__match} = 1;
3437              !!!next-input-character;              !!!next-input-character;
3438              #              #
# Line 3530  sub _get_next_token ($) { Line 3678  sub _get_next_token ($) {
3678          ## XML5: Not defined yet.          ## XML5: Not defined yet.
3679    
3680          ## TODO:          ## TODO:
3681    
3682            if (not $self->{stop_processing} and
3683                not $self->{document}->xml_standalone) {
3684              !!!parse-error (type => 'stop processing', ## TODO: type
3685                              level => $self->{level}->{info});
3686              $self->{stop_processing} = 1;
3687            }
3688    
3689          !!!next-input-character;          !!!next-input-character;
3690          redo A;          redo A;
3691        } elsif ($self->{nc} == 0x005D) { # ]        } elsif ($self->{nc} == 0x005D) { # ]
# Line 3764  sub _get_next_token ($) { Line 3920  sub _get_next_token ($) {
3920          }          }
3921          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
3922                         line => $self->{line_prev},                         line => $self->{line_prev},
3923                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
3924          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
3925          !!!next-input-character;          !!!next-input-character;
3926          redo A;          redo A;
# Line 3812  sub _get_next_token ($) { Line 3968  sub _get_next_token ($) {
3968          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
3969                         attrdefs => [],                         attrdefs => [],
3970                         line => $self->{line_prev},                         line => $self->{line_prev},
3971                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
3972          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
3973          !!!next-input-character;          !!!next-input-character;
3974          redo A;          redo A;
# Line 3861  sub _get_next_token ($) { Line 4017  sub _get_next_token ($) {
4017          }          }
4018          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
4019                         line => $self->{line_prev},                         line => $self->{line_prev},
4020                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
4021          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4022          !!!next-input-character;          !!!next-input-character;
4023          redo A;          redo A;
# Line 3973  sub _get_next_token ($) { Line 4129  sub _get_next_token ($) {
4129          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4130            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4131          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4132            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
4133          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
4134            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4135          }          }
# Line 4502  sub _get_next_token ($) { Line 4657  sub _get_next_token ($) {
4657          ## Reconsume.          ## Reconsume.
4658          redo A;          redo A;
4659        }        }
4660        } elsif ($self->{state} == NDATA_STATE) {
4661          ## ASCII case-insensitive
4662          if ($self->{nc} == [
4663                undef,
4664                0x0044, # D
4665                0x0041, # A
4666                0x0054, # T
4667              ]->[length $self->{kwd}] or
4668              $self->{nc} == [
4669                undef,
4670                0x0064, # d
4671                0x0061, # a
4672                0x0074, # t
4673              ]->[length $self->{kwd}]) {
4674            !!!cp (172.2);
4675            ## Stay in the state.
4676            $self->{kwd} .= chr $self->{nc};
4677            !!!next-input-character;
4678            redo A;
4679          } elsif ((length $self->{kwd}) == 4 and
4680                   ($self->{nc} == 0x0041 or # A
4681                    $self->{nc} == 0x0061)) { # a
4682            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
4683              !!!cp (172.3);
4684              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4685                              text => 'NDATA',
4686                              line => $self->{line_prev},
4687                              column => $self->{column_prev} - 4);
4688            } else {
4689              !!!cp (172.4);
4690            }
4691            $self->{state} = AFTER_NDATA_STATE;
4692            !!!next-input-character;
4693            redo A;
4694          } else {
4695            !!!parse-error (type => 'string after literal', ## TODO: type
4696                            line => $self->{line_prev},
4697                            column => $self->{column_prev} + 1
4698                                - length $self->{kwd});
4699            !!!cp (172.5);
4700            $self->{state} = BOGUS_MD_STATE;
4701            ## Reconsume.
4702            redo A;
4703          }
4704        } elsif ($self->{state} == AFTER_NDATA_STATE) {
4705          if ($is_space->{$self->{nc}}) {
4706            $self->{state} = BEFORE_NOTATION_NAME_STATE;
4707            !!!next-input-character;
4708            redo A;
4709          } elsif ($self->{nc} == 0x003E) { # >
4710            !!!parse-error (type => 'no notation name'); ## TODO: type
4711            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4712            !!!next-input-character;
4713            !!!emit ($self->{ct}); # ENTITY
4714            redo A;
4715          } elsif ($self->{nc} == -1) {
4716            !!!parse-error (type => 'unclosed md'); ## TODO: type
4717            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4718            !!!next-input-character;
4719            !!!emit ($self->{ct}); # ENTITY
4720            redo A;
4721          } else {
4722            !!!parse-error (type => 'string after literal', ## TODO: type
4723                            line => $self->{line_prev},
4724                            column => $self->{column_prev} + 1
4725                                - length $self->{kwd});
4726            $self->{state} = BOGUS_MD_STATE;
4727            ## Reconsume.
4728            redo A;
4729          }
4730        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
4731          if ($is_space->{$self->{nc}}) {
4732            ## Stay in the state.
4733            !!!next-input-character;
4734            redo A;
4735          } elsif ($self->{nc} == 0x003E) { # >
4736            !!!parse-error (type => 'no notation name'); ## TODO: type
4737            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4738            !!!next-input-character;
4739            !!!emit ($self->{ct}); # ENTITY
4740            redo A;
4741          } elsif ($self->{nc} == -1) {
4742            !!!parse-error (type => 'unclosed md'); ## TODO: type
4743            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4744            !!!next-input-character;
4745            !!!emit ($self->{ct}); # ENTITY
4746            redo A;
4747          } else {
4748            $self->{ct}->{notation} = chr $self->{nc}; # ENTITY
4749            $self->{state} = NOTATION_NAME_STATE;
4750            !!!next-input-character;
4751            redo A;
4752          }
4753        } elsif ($self->{state} == NOTATION_NAME_STATE) {
4754          if ($is_space->{$self->{nc}}) {
4755            $self->{state} = AFTER_MD_DEF_STATE;
4756            !!!next-input-character;
4757            redo A;
4758          } elsif ($self->{nc} == 0x003E) { # >
4759            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4760            !!!next-input-character;
4761            !!!emit ($self->{ct}); # ENTITY
4762            redo A;
4763          } elsif ($self->{nc} == -1) {
4764            !!!parse-error (type => 'unclosed md'); ## TODO: type
4765            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4766            !!!next-input-character;
4767            !!!emit ($self->{ct}); # ENTITY
4768            redo A;
4769          } else {
4770            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
4771            ## Stay in the state.
4772            !!!next-input-character;
4773            redo A;
4774          }
4775        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
4776          if ($self->{nc} == 0x0022) { # "
4777            $self->{state} = AFTER_MD_DEF_STATE;
4778            !!!next-input-character;
4779            redo A;
4780          } elsif ($self->{nc} == 0x0026) { # &
4781            $self->{prev_state} = $self->{state};
4782            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4783            $self->{entity_add} = 0x0022; # "
4784            !!!next-input-character;
4785            redo A;
4786    ## TODO: %
4787          } elsif ($self->{nc} == -1) {
4788            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4789            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4790            ## Reconsume.
4791            !!!emit ($self->{ct}); # ENTITY
4792            redo A;
4793          } else {
4794            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4795            !!!next-input-character;
4796            redo A;
4797          }
4798        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
4799          if ($self->{nc} == 0x0027) { # '
4800            $self->{state} = AFTER_MD_DEF_STATE;
4801            !!!next-input-character;
4802            redo A;
4803          } elsif ($self->{nc} == 0x0026) { # &
4804            $self->{prev_state} = $self->{state};
4805            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4806            $self->{entity_add} = 0x0027; # '
4807            !!!next-input-character;
4808            redo A;
4809    ## TODO: %
4810          } elsif ($self->{nc} == -1) {
4811            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4812            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4813            ## Reconsume.
4814            !!!emit ($self->{ct}); # ENTITY
4815            redo A;
4816          } else {
4817            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4818            !!!next-input-character;
4819            redo A;
4820          }
4821        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
4822          if ($is_space->{$self->{nc}} or
4823              {
4824                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4825                $self->{entity_add} => 1,
4826              }->{$self->{nc}}) {
4827            !!!parse-error (type => 'bare ero',
4828                            line => $self->{line_prev},
4829                            column => $self->{column_prev}
4830                                + ($self->{nc} == -1 ? 1 : 0));
4831            ## Don't consume
4832            ## Return nothing.
4833            #
4834          } elsif ($self->{nc} == 0x0023) { # #
4835            $self->{ca} = $self->{ct};
4836            $self->{state} = ENTITY_HASH_STATE;
4837            $self->{kwd} = '#';
4838            !!!next-input-character;
4839            redo A;
4840          } else {
4841            #
4842          }
4843    
4844          $self->{ct}->{value} .= '&';
4845          $self->{state} = $self->{prev_state};
4846          ## Reconsume.
4847          redo A;
4848        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
4849          if ($is_space->{$self->{nc}}) {
4850            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
4851            !!!next-input-character;
4852            redo A;
4853          } elsif ($self->{nc} == 0x0028) { # (
4854            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4855            $self->{ct}->{content} = ['('];
4856            $self->{group_depth} = 1;
4857            !!!next-input-character;
4858            redo A;
4859          } elsif ($self->{nc} == 0x003E) { # >
4860            !!!parse-error (type => 'no md def'); ## TODO: type
4861            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4862            !!!next-input-character;
4863            !!!emit ($self->{ct}); # ELEMENT
4864            redo A;
4865          } elsif ($self->{nc} == -1) {
4866            !!!parse-error (type => 'unclosed md'); ## TODO: type
4867            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4868            !!!next-input-character;
4869            !!!emit ($self->{ct}); # ELEMENT
4870            redo A;
4871          } else {
4872            $self->{ct}->{content} = [chr $self->{nc}];
4873            $self->{state} = CONTENT_KEYWORD_STATE;
4874            !!!next-input-character;
4875            redo A;
4876          }
4877        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
4878          if ($is_space->{$self->{nc}}) {
4879            $self->{state} = AFTER_MD_DEF_STATE;
4880            !!!next-input-character;
4881            redo A;
4882          } elsif ($self->{nc} == 0x003E) { # >
4883            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4884            !!!next-input-character;
4885            !!!emit ($self->{ct}); # ELEMENT
4886            redo A;
4887          } elsif ($self->{nc} == -1) {
4888            !!!parse-error (type => 'unclosed md'); ## TODO: type
4889            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4890            !!!next-input-character;
4891            !!!emit ($self->{ct}); # ELEMENT
4892            redo A;
4893          } else {
4894            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
4895            ## Stay in the state.
4896            !!!next-input-character;
4897            redo A;
4898          }
4899        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
4900          if ($is_space->{$self->{nc}}) {
4901            ## Stay in the state.
4902            !!!next-input-character;
4903            redo A;
4904          } elsif ($self->{nc} == 0x0028) { # (
4905            $self->{group_depth}++;
4906            push @{$self->{ct}->{content}}, chr $self->{nc};
4907            ## Stay in the state.
4908            !!!next-input-character;
4909            redo A;
4910          } elsif ($self->{nc} == 0x007C or # |
4911                   $self->{nc} == 0x002C) { # ,
4912            !!!parse-error (type => 'empty element name'); ## TODO: type
4913            ## Stay in the state.
4914            !!!next-input-character;
4915            redo A;
4916          } elsif ($self->{nc} == 0x0029) { # )
4917            !!!parse-error (type => 'empty element name'); ## TODO: type
4918            push @{$self->{ct}->{content}}, chr $self->{nc};
4919            $self->{group_depth}--;
4920            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4921            !!!next-input-character;
4922            redo A;
4923          } elsif ($self->{nc} == 0x003E) { # >
4924            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4925            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4926            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4927            !!!next-input-character;
4928            !!!emit ($self->{ct}); # ELEMENT
4929            redo A;
4930          } elsif ($self->{nc} == -1) {
4931            !!!parse-error (type => 'unclosed md'); ## TODO: type
4932            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4933            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4934            !!!next-input-character;
4935            !!!emit ($self->{ct}); # ELEMENT
4936            redo A;
4937          } else {
4938            push @{$self->{ct}->{content}}, chr $self->{nc};
4939            $self->{state} = CM_ELEMENT_NAME_STATE;
4940            !!!next-input-character;
4941            redo A;
4942          }
4943        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
4944          if ($is_space->{$self->{nc}}) {
4945            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4946            !!!next-input-character;
4947            redo A;
4948          } elsif ($self->{nc} == 0x002A or # *
4949                   $self->{nc} == 0x002B or # +
4950                   $self->{nc} == 0x003F) { # ?
4951            push @{$self->{ct}->{content}}, chr $self->{nc};
4952            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4953            !!!next-input-character;
4954            redo A;
4955          } elsif ($self->{nc} == 0x007C or # |
4956                   $self->{nc} == 0x002C) { # ,
4957            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
4958            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4959            !!!next-input-character;
4960            redo A;
4961          } elsif ($self->{nc} == 0x0029) { # )
4962            $self->{group_depth}--;
4963            push @{$self->{ct}->{content}}, chr $self->{nc};
4964            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4965            !!!next-input-character;
4966            redo A;
4967          } elsif ($self->{nc} == 0x003E) { # >
4968            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4969            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4970            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4971            !!!next-input-character;
4972            !!!emit ($self->{ct}); # ELEMENT
4973            redo A;
4974          } elsif ($self->{nc} == -1) {
4975            !!!parse-error (type => 'unclosed md'); ## TODO: type
4976            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4977            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4978            !!!next-input-character;
4979            !!!emit ($self->{ct}); # ELEMENT
4980            redo A;
4981          } else {
4982            $self->{ct}->{content}->[-1] .= chr $self->{nc};
4983            ## Stay in the state.
4984            !!!next-input-character;
4985            redo A;
4986          }
4987        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
4988          if ($is_space->{$self->{nc}}) {
4989            ## Stay in the state.
4990            !!!next-input-character;
4991            redo A;
4992          } elsif ($self->{nc} == 0x007C or # |
4993                   $self->{nc} == 0x002C) { # ,
4994            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
4995            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4996            !!!next-input-character;
4997            redo A;
4998          } elsif ($self->{nc} == 0x0029) { # )
4999            $self->{group_depth}--;
5000            push @{$self->{ct}->{content}}, chr $self->{nc};
5001            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5002            !!!next-input-character;
5003            redo A;
5004          } elsif ($self->{nc} == 0x003E) { # >
5005            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5006            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5007            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5008            !!!next-input-character;
5009            !!!emit ($self->{ct}); # ELEMENT
5010            redo A;
5011          } elsif ($self->{nc} == -1) {
5012            !!!parse-error (type => 'unclosed md'); ## TODO: type
5013            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5014            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5015            !!!next-input-character;
5016            !!!emit ($self->{ct}); # ELEMENT
5017            redo A;
5018          } else {
5019            !!!parse-error (type => 'after element name'); ## TODO: type
5020            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5021            $self->{state} = BOGUS_MD_STATE;
5022            !!!next-input-character;
5023            redo A;
5024          }
5025        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
5026          if ($is_space->{$self->{nc}}) {
5027            if ($self->{group_depth}) {
5028              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5029            } else {
5030              $self->{state} = AFTER_MD_DEF_STATE;
5031            }
5032            !!!next-input-character;
5033            redo A;
5034          } elsif ($self->{nc} == 0x002A or # *
5035                   $self->{nc} == 0x002B or # +
5036                   $self->{nc} == 0x003F) { # ?
5037            push @{$self->{ct}->{content}}, chr $self->{nc};
5038            if ($self->{group_depth}) {
5039              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5040            } else {
5041              $self->{state} = AFTER_MD_DEF_STATE;
5042            }
5043            !!!next-input-character;
5044            redo A;
5045          } elsif ($self->{nc} == 0x0029) { # )
5046            if ($self->{group_depth}) {
5047              $self->{group_depth}--;
5048              push @{$self->{ct}->{content}}, chr $self->{nc};
5049              ## Stay in the state.
5050              !!!next-input-character;
5051              redo A;
5052            } else {
5053              !!!parse-error (type => 'string after md def'); ## TODO: type
5054              $self->{state} = BOGUS_MD_STATE;
5055              ## Reconsume.
5056              redo A;
5057            }
5058          } elsif ($self->{nc} == 0x003E) { # >
5059            if ($self->{group_depth}) {
5060              !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5061              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5062            }
5063            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5064            !!!next-input-character;
5065            !!!emit ($self->{ct}); # ELEMENT
5066            redo A;
5067          } elsif ($self->{nc} == -1) {
5068            !!!parse-error (type => 'unclosed md'); ## TODO: type
5069            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5070            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5071            !!!next-input-character;
5072            !!!emit ($self->{ct}); # ELEMENT
5073            redo A;
5074          } else {
5075            if ($self->{group_depth}) {
5076              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5077            } else {
5078              !!!parse-error (type => 'string after md def'); ## TODO: type
5079              $self->{state} = BOGUS_MD_STATE;
5080            }
5081            ## Reconsume.
5082            redo A;
5083          }
5084        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
5085          if ($is_space->{$self->{nc}}) {
5086            ## Stay in the state.
5087            !!!next-input-character;
5088            redo A;
5089          } elsif ($self->{nc} == 0x003E) { # >
5090            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5091            !!!next-input-character;
5092            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5093            redo A;
5094          } elsif ($self->{nc} == -1) {
5095            !!!parse-error (type => 'unclosed md'); ## TODO: type
5096            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5097            !!!next-input-character;
5098            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5099            redo A;
5100          } else {
5101            !!!parse-error (type => 'string after md def'); ## TODO: type
5102            $self->{state} = BOGUS_MD_STATE;
5103            ## Reconsume.
5104            redo A;
5105          }
5106      } elsif ($self->{state} == BOGUS_MD_STATE) {      } elsif ($self->{state} == BOGUS_MD_STATE) {
5107        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
5108          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.26

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24