/[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.18 by wakaba, Sun Oct 19 06:14:57 2008 UTC revision 1.28 by wakaba, Sun Jul 5 04:38:45 2009 UTC
# Line 182  sub NDATA_STATE () { 86 } Line 182  sub NDATA_STATE () { 86 }
182  sub AFTER_NDATA_STATE () { 87 }  sub AFTER_NDATA_STATE () { 87 }
183  sub BEFORE_NOTATION_NAME_STATE () { 88 }  sub BEFORE_NOTATION_NAME_STATE () { 88 }
184  sub NOTATION_NAME_STATE () { 89 }  sub NOTATION_NAME_STATE () { 89 }
185  sub AFTER_NOTATION_NAME_STATE () { 90 }  sub DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE () { 90 }
186  sub BOGUS_MD_STATE () { 91 }  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 1260  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 1306  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 1353  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 1390  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 1437  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 1549  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 1558  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 2094  sub _get_next_token ($) { Line 2119  sub _get_next_token ($) {
2119          redo A;          redo A;
2120        } else {        } else {
2121          !!!cp (154);          !!!cp (154);
         ## XML5: Not a parse error.  
         !!!parse-error (type => 'dash in comment',  
                         line => $self->{line_prev},  
                         column => $self->{column_prev});  
2122          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment          $self->{ct}->{data} .= '--' . chr ($self->{nc}); # comment
2123          $self->{state} = COMMENT_STATE;          $self->{state} = COMMENT_STATE;
2124          !!!next-input-character;          !!!next-input-character;
# Line 2109  sub _get_next_token ($) { Line 2130  sub _get_next_token ($) {
2130          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2131          !!!next-input-character;          !!!next-input-character;
2132          redo A;          redo A;
2133          } elsif ($self->{nc} == -1) {
2134            !!!cp (155.1);
2135            !!!parse-error (type => 'unclosed DOCTYPE');
2136            $self->{ct}->{quirks} = 1;
2137    
2138            $self->{state} = DATA_STATE;
2139            ## Reconsume.
2140            !!!emit ($self->{ct}); # DOCTYPE (quirks)
2141    
2142            redo A;
2143        } else {        } else {
2144          !!!cp (156);          !!!cp (156);
2145          ## XML5: Unless EOF, swith to the bogus comment state.          ## XML5: Swith to the bogus comment state.
2146          !!!parse-error (type => 'no space before DOCTYPE name');          !!!parse-error (type => 'no space before DOCTYPE name');
2147          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2148          ## reconsume          ## reconsume
# Line 2262  sub _get_next_token ($) { Line 2293  sub _get_next_token ($) {
2293          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
2294          !!!next-input-character;          !!!next-input-character;
2295          redo A;          redo A;
2296  ## TODO: " and ' for ENTITY        } elsif ($self->{nc} == 0x0022 and # "
2297                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2298                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2299            !!!cp (167.21);
2300            $self->{state} = DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE;
2301            $self->{ct}->{value} = ''; # ENTITY
2302            !!!next-input-character;
2303            redo A;
2304          } elsif ($self->{nc} == 0x0027 and # '
2305                   ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN or
2306                    $self->{ct}->{type} == PARAMETER_ENTITY_TOKEN)) {
2307            !!!cp (167.22);
2308            $self->{state} = DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE;
2309            $self->{ct}->{value} = ''; # ENTITY
2310            !!!next-input-character;
2311            redo A;
2312        } elsif ($self->{is_xml} and        } elsif ($self->{is_xml} and
2313                 $self->{ct}->{type} == DOCTYPE_TOKEN and                 $self->{ct}->{type} == DOCTYPE_TOKEN and
2314                 $self->{nc} == 0x005B) { # [                 $self->{nc} == 0x005B) { # [
# Line 3053  sub _get_next_token ($) { Line 3099  sub _get_next_token ($) {
3099              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3100              $self->{entity_add} => 1,              $self->{entity_add} => 1,
3101            }->{$self->{nc}}) {            }->{$self->{nc}}) {
3102          !!!cp (1001);          if ($self->{is_xml}) {
3103              !!!cp (1001.1);
3104              !!!parse-error (type => 'bare ero',
3105                              line => $self->{line_prev},
3106                              column => $self->{column_prev}
3107                                  + ($self->{nc} == -1 ? 1 : 0));
3108            } else {
3109              !!!cp (1001);
3110              ## No error
3111            }
3112          ## Don't consume          ## Don't consume
         ## No error  
3113          ## Return nothing.          ## Return nothing.
3114          #          #
3115        } elsif ($self->{nc} == 0x0023) { # #        } elsif ($self->{nc} == 0x0023) { # #
# Line 3064  sub _get_next_token ($) { Line 3118  sub _get_next_token ($) {
3118          $self->{kwd} = '#';          $self->{kwd} = '#';
3119          !!!next-input-character;          !!!next-input-character;
3120          redo A;          redo A;
3121        } elsif ((0x0041 <= $self->{nc} and        } elsif ($self->{is_xml} or
3122                   (0x0041 <= $self->{nc} and
3123                  $self->{nc} <= 0x005A) or # A..Z                  $self->{nc} <= 0x005A) or # A..Z
3124                 (0x0061 <= $self->{nc} and                 (0x0061 <= $self->{nc} and
3125                  $self->{nc} <= 0x007A)) { # a..z                  $self->{nc} <= 0x007A)) { # a..z
# Line 3108  sub _get_next_token ($) { Line 3163  sub _get_next_token ($) {
3163          redo A;          redo A;
3164        }        }
3165      } elsif ($self->{state} == ENTITY_HASH_STATE) {      } elsif ($self->{state} == ENTITY_HASH_STATE) {
3166        if ($self->{nc} == 0x0078 or # x        if ($self->{nc} == 0x0078) { # x
           $self->{nc} == 0x0058) { # X  
3167          !!!cp (995);          !!!cp (995);
3168          $self->{state} = HEXREF_X_STATE;          $self->{state} = HEXREF_X_STATE;
3169          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3170          !!!next-input-character;          !!!next-input-character;
3171          redo A;          redo A;
3172          } elsif ($self->{nc} == 0x0058) { # X
3173            !!!cp (995.1);
3174            if ($self->{is_xml}) {
3175              !!!parse-error (type => 'uppercase hcro'); ## TODO: type
3176            }
3177            $self->{state} = HEXREF_X_STATE;
3178            $self->{kwd} .= chr $self->{nc};
3179            !!!next-input-character;
3180            redo A;
3181        } elsif (0x0030 <= $self->{nc} and        } elsif (0x0030 <= $self->{nc} and
3182                 $self->{nc} <= 0x0039) { # 0..9                 $self->{nc} <= 0x0039) { # 0..9
3183          !!!cp (994);          !!!cp (994);
# Line 3175  sub _get_next_token ($) { Line 3238  sub _get_next_token ($) {
3238        my $code = $self->{kwd};        my $code = $self->{kwd};
3239        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3240        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3241        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3242              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3243              ($self->{is_xml} and $code == 0x0000)) {
3244          !!!cp (1015);          !!!cp (1015);
3245          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3246                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3288  sub _get_next_token ($) { Line 3353  sub _get_next_token ($) {
3353        my $code = $self->{kwd};        my $code = $self->{kwd};
3354        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3355        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3356        if ($charref_map->{$code}) {        if ((not $self->{is_xml} and $charref_map->{$code}) or
3357              ($self->{is_xml} and 0xD800 <= $code and $code <= 0xDFFF) or
3358              ($self->{is_xml} and $code == 0x0000)) {
3359          !!!cp (1008);          !!!cp (1008);
3360          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3361                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
# Line 3322  sub _get_next_token ($) { Line 3389  sub _get_next_token ($) {
3389          redo A;          redo A;
3390        }        }
3391      } elsif ($self->{state} == ENTITY_NAME_STATE) {      } elsif ($self->{state} == ENTITY_NAME_STATE) {
3392        if (length $self->{kwd} < 30 and        if ((0x0041 <= $self->{nc} and # a
3393            ## NOTE: Some number greater than the maximum length of entity name             $self->{nc} <= 0x005A) or # x
3394            ((0x0041 <= $self->{nc} and # a            (0x0061 <= $self->{nc} and # a
3395              $self->{nc} <= 0x005A) or # x             $self->{nc} <= 0x007A) or # z
3396             (0x0061 <= $self->{nc} and # a            (0x0030 <= $self->{nc} and # 0
3397              $self->{nc} <= 0x007A) or # z             $self->{nc} <= 0x0039) or # 9
3398             (0x0030 <= $self->{nc} and # 0            $self->{nc} == 0x003B or # ;
3399              $self->{nc} <= 0x0039) or # 9            ($self->{is_xml} and
3400             $self->{nc} == 0x003B)) { # ;             not ($is_space->{$self->{nc}} or
3401                    {
3402                      0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3403                      $self->{entity_add} => 1,
3404                    }->{$self->{nc}}))) {
3405          our $EntityChar;          our $EntityChar;
3406          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3407          if (defined $EntityChar->{$self->{kwd}}) {          if (defined $EntityChar->{$self->{kwd}} or
3408                $self->{ge}->{$self->{kwd}}) {
3409            if ($self->{nc} == 0x003B) { # ;            if ($self->{nc} == 0x003B) { # ;
3410              !!!cp (1020);              if (defined $self->{ge}->{$self->{kwd}}) {
3411              $self->{entity__value} = $EntityChar->{$self->{kwd}};                if ($self->{ge}->{$self->{kwd}}->{only_text}) {
3412                    !!!cp (1020.1);
3413                    $self->{entity__value} = $self->{ge}->{$self->{kwd}}->{value};
3414                  } else {
3415                    if (defined $self->{ge}->{$self->{kwd}}->{notation}) {
3416                      !!!cp (1020.2);
3417                      !!!parse-error (type => 'unparsed entity', ## TODO: type
3418                                      value => $self->{kwd});
3419                    } else {
3420                      !!!cp (1020.3);
3421                    }
3422                    $self->{entity__value} = '&' . $self->{kwd}; ## TODO: expand
3423                  }
3424                } else {
3425                  if ($self->{is_xml}) {
3426                    !!!cp (1020.4);
3427                    !!!parse-error (type => 'entity not declared', ## TODO: type
3428                                    value => $self->{kwd},
3429                                    level => {
3430                                              'amp;' => $self->{level}->{warn},
3431                                              'quot;' => $self->{level}->{warn},
3432                                              'lt;' => $self->{level}->{warn},
3433                                              'gt;' => $self->{level}->{warn},
3434                                              'apos;' => $self->{level}->{warn},
3435                                             }->{$self->{kwd}} ||
3436                                             $self->{level}->{must});
3437                  } else {
3438                    !!!cp (1020);
3439                  }
3440                  $self->{entity__value} = $EntityChar->{$self->{kwd}};
3441                }
3442              $self->{entity__match} = 1;              $self->{entity__match} = 1;
3443              !!!next-input-character;              !!!next-input-character;
3444              #              #
# Line 3582  sub _get_next_token ($) { Line 3684  sub _get_next_token ($) {
3684          ## XML5: Not defined yet.          ## XML5: Not defined yet.
3685    
3686          ## TODO:          ## TODO:
3687    
3688            if (not $self->{stop_processing} and
3689                not $self->{document}->xml_standalone) {
3690              !!!parse-error (type => 'stop processing', ## TODO: type
3691                              level => $self->{level}->{info});
3692              $self->{stop_processing} = 1;
3693            }
3694    
3695          !!!next-input-character;          !!!next-input-character;
3696          redo A;          redo A;
3697        } elsif ($self->{nc} == 0x005D) { # ]        } elsif ($self->{nc} == 0x005D) { # ]
# Line 3816  sub _get_next_token ($) { Line 3926  sub _get_next_token ($) {
3926          }          }
3927          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
3928                         line => $self->{line_prev},                         line => $self->{line_prev},
3929                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
3930          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
3931          !!!next-input-character;          !!!next-input-character;
3932          redo A;          redo A;
# Line 3864  sub _get_next_token ($) { Line 3974  sub _get_next_token ($) {
3974          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
3975                         attrdefs => [],                         attrdefs => [],
3976                         line => $self->{line_prev},                         line => $self->{line_prev},
3977                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 7};
3978          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
3979          !!!next-input-character;          !!!next-input-character;
3980          redo A;          redo A;
# Line 3913  sub _get_next_token ($) { Line 4023  sub _get_next_token ($) {
4023          }          }
4024          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
4025                         line => $self->{line_prev},                         line => $self->{line_prev},
4026                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 8};
4027          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
4028          !!!next-input-character;          !!!next-input-character;
4029          redo A;          redo A;
# Line 4025  sub _get_next_token ($) { Line 4135  sub _get_next_token ($) {
4135          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4136            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4137          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {          } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4138            ## TODO: ...            $self->{state} = AFTER_ELEMENT_NAME_STATE;
           $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;  
4139          } else { # ENTITY/NOTATION          } else { # ENTITY/NOTATION
4140            $self->{state} = AFTER_DOCTYPE_NAME_STATE;            $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4141          }          }
# Line 4649  sub _get_next_token ($) { Line 4758  sub _get_next_token ($) {
4758        }        }
4759      } elsif ($self->{state} == NOTATION_NAME_STATE) {      } elsif ($self->{state} == NOTATION_NAME_STATE) {
4760        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4761          $self->{state} = AFTER_NOTATION_NAME_STATE;          $self->{state} = AFTER_MD_DEF_STATE;
4762          !!!next-input-character;          !!!next-input-character;
4763          redo A;          redo A;
4764        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
# Line 4669  sub _get_next_token ($) { Line 4778  sub _get_next_token ($) {
4778          !!!next-input-character;          !!!next-input-character;
4779          redo A;          redo A;
4780        }        }
4781      } elsif ($self->{state} == AFTER_NOTATION_NAME_STATE) {      } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_DOUBLE_QUOTED_STATE) {
4782          if ($self->{nc} == 0x0022) { # "
4783            $self->{state} = AFTER_MD_DEF_STATE;
4784            !!!next-input-character;
4785            redo A;
4786          } elsif ($self->{nc} == 0x0026) { # &
4787            $self->{prev_state} = $self->{state};
4788            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4789            $self->{entity_add} = 0x0022; # "
4790            !!!next-input-character;
4791            redo A;
4792    ## TODO: %
4793          } elsif ($self->{nc} == -1) {
4794            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4795            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4796            ## Reconsume.
4797            !!!emit ($self->{ct}); # ENTITY
4798            redo A;
4799          } else {
4800            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4801            !!!next-input-character;
4802            redo A;
4803          }
4804        } elsif ($self->{state} == DOCTYPE_ENTITY_VALUE_SINGLE_QUOTED_STATE) {
4805          if ($self->{nc} == 0x0027) { # '
4806            $self->{state} = AFTER_MD_DEF_STATE;
4807            !!!next-input-character;
4808            redo A;
4809          } elsif ($self->{nc} == 0x0026) { # &
4810            $self->{prev_state} = $self->{state};
4811            $self->{state} = ENTITY_VALUE_ENTITY_STATE;
4812            $self->{entity_add} = 0x0027; # '
4813            !!!next-input-character;
4814            redo A;
4815    ## TODO: %
4816          } elsif ($self->{nc} == -1) {
4817            !!!parse-error (type => 'unclosed entity value'); ## TODO: type
4818            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4819            ## Reconsume.
4820            !!!emit ($self->{ct}); # ENTITY
4821            redo A;
4822          } else {
4823            $self->{ct}->{value} .= chr $self->{nc}; # ENTITY
4824            !!!next-input-character;
4825            redo A;
4826          }
4827        } elsif ($self->{state} == ENTITY_VALUE_ENTITY_STATE) {
4828          if ($is_space->{$self->{nc}} or
4829              {
4830                0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
4831                $self->{entity_add} => 1,
4832              }->{$self->{nc}}) {
4833            !!!parse-error (type => 'bare ero',
4834                            line => $self->{line_prev},
4835                            column => $self->{column_prev}
4836                                + ($self->{nc} == -1 ? 1 : 0));
4837            ## Don't consume
4838            ## Return nothing.
4839            #
4840          } elsif ($self->{nc} == 0x0023) { # #
4841            $self->{ca} = $self->{ct};
4842            $self->{state} = ENTITY_HASH_STATE;
4843            $self->{kwd} = '#';
4844            !!!next-input-character;
4845            redo A;
4846          } else {
4847            #
4848          }
4849    
4850          $self->{ct}->{value} .= '&';
4851          $self->{state} = $self->{prev_state};
4852          ## Reconsume.
4853          redo A;
4854        } elsif ($self->{state} == AFTER_ELEMENT_NAME_STATE) {
4855          if ($is_space->{$self->{nc}}) {
4856            $self->{state} = BEFORE_ELEMENT_CONTENT_STATE;
4857            !!!next-input-character;
4858            redo A;
4859          } elsif ($self->{nc} == 0x0028) { # (
4860            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4861            $self->{ct}->{content} = ['('];
4862            $self->{group_depth} = 1;
4863            !!!next-input-character;
4864            redo A;
4865          } elsif ($self->{nc} == 0x003E) { # >
4866            !!!parse-error (type => 'no md def'); ## TODO: type
4867            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4868            !!!next-input-character;
4869            !!!emit ($self->{ct}); # ELEMENT
4870            redo A;
4871          } elsif ($self->{nc} == -1) {
4872            !!!parse-error (type => 'unclosed md'); ## TODO: type
4873            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4874            !!!next-input-character;
4875            !!!emit ($self->{ct}); # ELEMENT
4876            redo A;
4877          } else {
4878            $self->{ct}->{content} = [chr $self->{nc}];
4879            $self->{state} = CONTENT_KEYWORD_STATE;
4880            !!!next-input-character;
4881            redo A;
4882          }
4883        } elsif ($self->{state} == CONTENT_KEYWORD_STATE) {
4884          if ($is_space->{$self->{nc}}) {
4885            $self->{state} = AFTER_MD_DEF_STATE;
4886            !!!next-input-character;
4887            redo A;
4888          } elsif ($self->{nc} == 0x003E) { # >
4889            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4890            !!!next-input-character;
4891            !!!emit ($self->{ct}); # ELEMENT
4892            redo A;
4893          } elsif ($self->{nc} == -1) {
4894            !!!parse-error (type => 'unclosed md'); ## TODO: type
4895            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4896            !!!next-input-character;
4897            !!!emit ($self->{ct}); # ELEMENT
4898            redo A;
4899          } else {
4900            $self->{ct}->{content}->[-1] .= chr $self->{nc}; # ELEMENT
4901            ## Stay in the state.
4902            !!!next-input-character;
4903            redo A;
4904          }
4905        } elsif ($self->{state} == AFTER_CM_GROUP_OPEN_STATE) {
4906        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4907          ## Stay in the state.          ## Stay in the state.
4908          !!!next-input-character;          !!!next-input-character;
4909          redo A;          redo A;
4910          } elsif ($self->{nc} == 0x0028) { # (
4911            $self->{group_depth}++;
4912            push @{$self->{ct}->{content}}, chr $self->{nc};
4913            ## Stay in the state.
4914            !!!next-input-character;
4915            redo A;
4916          } elsif ($self->{nc} == 0x007C or # |
4917                   $self->{nc} == 0x002C) { # ,
4918            !!!parse-error (type => 'empty element name'); ## TODO: type
4919            ## Stay in the state.
4920            !!!next-input-character;
4921            redo A;
4922          } elsif ($self->{nc} == 0x0029) { # )
4923            !!!parse-error (type => 'empty element name'); ## TODO: type
4924            push @{$self->{ct}->{content}}, chr $self->{nc};
4925            $self->{group_depth}--;
4926            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4927            !!!next-input-character;
4928            redo A;
4929        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
4930            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4931            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4932          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4933          !!!next-input-character;          !!!next-input-character;
4934          !!!emit ($self->{ct}); # ENTITY          !!!emit ($self->{ct}); # ELEMENT
4935          redo A;          redo A;
4936        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
4937          !!!parse-error (type => 'unclosed md'); ## TODO: type          !!!parse-error (type => 'unclosed md'); ## TODO: type
4938            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4939          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4940          !!!next-input-character;          !!!next-input-character;
4941          !!!emit ($self->{ct}); # ENTITY          !!!emit ($self->{ct}); # ELEMENT
4942            redo A;
4943          } else {
4944            push @{$self->{ct}->{content}}, chr $self->{nc};
4945            $self->{state} = CM_ELEMENT_NAME_STATE;
4946            !!!next-input-character;
4947            redo A;
4948          }
4949        } elsif ($self->{state} == CM_ELEMENT_NAME_STATE) {
4950          if ($is_space->{$self->{nc}}) {
4951            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4952            !!!next-input-character;
4953            redo A;
4954          } elsif ($self->{nc} == 0x002A or # *
4955                   $self->{nc} == 0x002B or # +
4956                   $self->{nc} == 0x003F) { # ?
4957            push @{$self->{ct}->{content}}, chr $self->{nc};
4958            $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
4959            !!!next-input-character;
4960            redo A;
4961          } elsif ($self->{nc} == 0x007C or # |
4962                   $self->{nc} == 0x002C) { # ,
4963            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
4964            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
4965            !!!next-input-character;
4966            redo A;
4967          } elsif ($self->{nc} == 0x0029) { # )
4968            $self->{group_depth}--;
4969            push @{$self->{ct}->{content}}, chr $self->{nc};
4970            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
4971            !!!next-input-character;
4972            redo A;
4973          } elsif ($self->{nc} == 0x003E) { # >
4974            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
4975            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4976            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4977            !!!next-input-character;
4978            !!!emit ($self->{ct}); # ELEMENT
4979            redo A;
4980          } elsif ($self->{nc} == -1) {
4981            !!!parse-error (type => 'unclosed md'); ## TODO: type
4982            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
4983            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4984            !!!next-input-character;
4985            !!!emit ($self->{ct}); # ELEMENT
4986            redo A;
4987          } else {
4988            $self->{ct}->{content}->[-1] .= chr $self->{nc};
4989            ## Stay in the state.
4990            !!!next-input-character;
4991            redo A;
4992          }
4993        } elsif ($self->{state} == AFTER_CM_ELEMENT_NAME_STATE) {
4994          if ($is_space->{$self->{nc}}) {
4995            ## Stay in the state.
4996            !!!next-input-character;
4997            redo A;
4998          } elsif ($self->{nc} == 0x007C or # |
4999                   $self->{nc} == 0x002C) { # ,
5000            push @{$self->{ct}->{content}}, $self->{nc} == 0x007C ? ' | ' : ', ';
5001            $self->{state} = AFTER_CM_GROUP_OPEN_STATE;
5002            !!!next-input-character;
5003            redo A;
5004          } elsif ($self->{nc} == 0x0029) { # )
5005            $self->{group_depth}--;
5006            push @{$self->{ct}->{content}}, chr $self->{nc};
5007            $self->{state} = AFTER_CM_GROUP_CLOSE_STATE;
5008            !!!next-input-character;
5009            redo A;
5010          } elsif ($self->{nc} == 0x003E) { # >
5011            !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5012            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5013            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5014            !!!next-input-character;
5015            !!!emit ($self->{ct}); # ELEMENT
5016            redo A;
5017          } elsif ($self->{nc} == -1) {
5018            !!!parse-error (type => 'unclosed md'); ## TODO: type
5019            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5020            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5021            !!!next-input-character;
5022            !!!emit ($self->{ct}); # ELEMENT
5023            redo A;
5024          } else {
5025            !!!parse-error (type => 'after element name'); ## TODO: type
5026            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5027            $self->{state} = BOGUS_MD_STATE;
5028            !!!next-input-character;
5029            redo A;
5030          }
5031        } elsif ($self->{state} == AFTER_CM_GROUP_CLOSE_STATE) {
5032          if ($is_space->{$self->{nc}}) {
5033            if ($self->{group_depth}) {
5034              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5035            } else {
5036              $self->{state} = AFTER_MD_DEF_STATE;
5037            }
5038            !!!next-input-character;
5039            redo A;
5040          } elsif ($self->{nc} == 0x002A or # *
5041                   $self->{nc} == 0x002B or # +
5042                   $self->{nc} == 0x003F) { # ?
5043            push @{$self->{ct}->{content}}, chr $self->{nc};
5044            if ($self->{group_depth}) {
5045              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5046            } else {
5047              $self->{state} = AFTER_MD_DEF_STATE;
5048            }
5049            !!!next-input-character;
5050            redo A;
5051          } elsif ($self->{nc} == 0x0029) { # )
5052            if ($self->{group_depth}) {
5053              $self->{group_depth}--;
5054              push @{$self->{ct}->{content}}, chr $self->{nc};
5055              ## Stay in the state.
5056              !!!next-input-character;
5057              redo A;
5058            } else {
5059              !!!parse-error (type => 'string after md def'); ## TODO: type
5060              $self->{state} = BOGUS_MD_STATE;
5061              ## Reconsume.
5062              redo A;
5063            }
5064          } elsif ($self->{nc} == 0x003E) { # >
5065            if ($self->{group_depth}) {
5066              !!!parse-error (type => 'unclosed cm group'); ## TODO: type
5067              push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5068            }
5069            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5070            !!!next-input-character;
5071            !!!emit ($self->{ct}); # ELEMENT
5072            redo A;
5073          } elsif ($self->{nc} == -1) {
5074            !!!parse-error (type => 'unclosed md'); ## TODO: type
5075            push @{$self->{ct}->{content}}, (')') x $self->{group_depth};
5076            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5077            !!!next-input-character;
5078            !!!emit ($self->{ct}); # ELEMENT
5079          redo A;          redo A;
5080        } else {        } else {
5081          !!!parse-error (type => 'string after notation name'); ## TODO: type          if ($self->{group_depth}) {
5082              $self->{state} = AFTER_CM_ELEMENT_NAME_STATE;
5083            } else {
5084              !!!parse-error (type => 'string after md def'); ## TODO: type
5085              $self->{state} = BOGUS_MD_STATE;
5086            }
5087            ## Reconsume.
5088            redo A;
5089          }
5090        } elsif ($self->{state} == AFTER_MD_DEF_STATE) {
5091          if ($is_space->{$self->{nc}}) {
5092            ## Stay in the state.
5093            !!!next-input-character;
5094            redo A;
5095          } elsif ($self->{nc} == 0x003E) { # >
5096            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5097            !!!next-input-character;
5098            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5099            redo A;
5100          } elsif ($self->{nc} == -1) {
5101            !!!parse-error (type => 'unclosed md'); ## TODO: type
5102            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
5103            !!!next-input-character;
5104            !!!emit ($self->{ct}); # ENTITY/ELEMENT
5105            redo A;
5106          } else {
5107            !!!parse-error (type => 'string after md def'); ## TODO: type
5108          $self->{state} = BOGUS_MD_STATE;          $self->{state} = BOGUS_MD_STATE;
5109          ## Reconsume.          ## Reconsume.
5110          redo A;          redo A;
5111        }        }
   
   
5112      } elsif ($self->{state} == BOGUS_MD_STATE) {      } elsif ($self->{state} == BOGUS_MD_STATE) {
5113        if ($self->{nc} == 0x003E) { # >        if ($self->{nc} == 0x003E) { # >
5114          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;

Legend:
Removed from v.1.18  
changed lines
  Added in v.1.28

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24