/[suikacvs]/messaging/manakai/lib/Message/DOM/XMLParser.dis
Suika

Contents of /messaging/manakai/lib/Message/DOM/XMLParser.dis

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations) (download)
Wed Feb 8 09:49:58 2006 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.12: +164 -15 lines
++ manakai/lib/Message/Util/DIS/ChangeLog	8 Feb 2006 09:49:49 -0000
	* Test.dis (assertDOMLocatorEquals): New method.
	(assertTypedValueEquals): |DOMLocator| type support is added.
	In addition, if it encounters an unknown type value,
	then it will |die|.

2006-02-08  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/DOM/ChangeLog	8 Feb 2006 09:48:33 -0000
	* XMLParser.dis (shiftChar): Line and column number counting
	is fixed.  Although the DOM Level 3 Core specification
	is unclear about whether the first number is zero or one,
	in most programs the first line is "one" and
	the first column is "one", manakai follows the practice.
	(_XMLDeclaration): Don't set |xmlStandalone| value
	if |standalone| pseudo-attribute value is |no|.  XML declaration
	tests (successful cases) added.
	(xp:get-location-from-token): Sets |lineNumber| and |columnNumber|
	properties.

2006-02-08  Wakaba  <wakaba@suika.fam.cx>

1 wakaba 1.1 Module:
2     @QName: MDOM|XMLParser
3     @Namespace:
4     http://suika.fam.cx/~wakaba/archive/2004/dom/xml-parser#
5    
6     @FullName:
7     @@lang:en
8     @@@: XML Parser
9    
10     @DISCore:author: DISCore|Wakaba
11     @License: license|Perl+MPL
12     @Date:
13 wakaba 1.13 $Date: 2006/02/08 08:18:29 $
14 wakaba 1.1
15     @DefaultFor: ManakaiDOM|ManakaiDOMLatest
16    
17     @Require:
18     @@Module:
19     @@@QName: MDOM|DOMLS
20     @@@WithFor: ManakaiDOM|ManakaiDOMLatest
21 wakaba 1.6 @@Module:
22     @@@QName: MDOM|XDoctype
23     @@@WithFor: ManakaiDOM|ManakaiDOMLatest
24 wakaba 1.1
25     Namespace:
26 wakaba 1.8 @c:
27     http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core#
28 wakaba 1.11 @cfg:
29     http://suika.fam.cx/www/2006/dom-config/
30 wakaba 1.6 @d:
31     http://suika.fam.cx/~wakaba/archive/2004/dom/xdt#
32 wakaba 1.1 @dis:
33     http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis--
34 wakaba 1.5 @dtest:
35     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#Test/
36 wakaba 1.1 @dx:
37     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException#
38     @ecore:
39     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/
40     @f:
41     http://suika.fam.cx/~wakaba/archive/2004/dom/feature#
42 wakaba 1.11 @fe:
43     http://suika.fam.cx/www/2006/feature/
44     @gls:
45     http://suika.fam.cx/~wakaba/archive/2004/dom/gls#
46 wakaba 1.1 @idl:
47     http://suika.fam.cx/~wakaba/archive/2004/dis/IDL#
48     @infoset:
49     http://www.w3.org/2001/04/infoset#
50     @lang:
51     http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#
52     @license:
53     http://suika.fam.cx/~wakaba/archive/2004/8/18/license#
54     @LSEV:
55     http://www.w3.org/2002/DOMLS
56     @ManakaiDOM:
57     http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#
58     @ManakaiDOMLS:
59     http://suika.fam.cx/~wakaba/archive/2004/mdom-ls#
60     @MDOM:
61     http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#ManakaiDOM.
62     @MDOMX:
63     http://suika.fam.cx/~wakaba/archive/2004/8/4/manakai-dom-exception#
64 wakaba 1.11 @mn:
65     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/ManakaiNode#
66 wakaba 1.1 @rdf:
67     http://www.w3.org/1999/02/22-rdf-syntax-ns#
68     @rdfs:
69     http://www.w3.org/2000/01/rdf-schema#
70     @t:
71     http://suika.fam.cx/~wakaba/archive/2004/dom/tree#
72 wakaba 1.5 @test:
73     http://suika.fam.cx/~wakaba/archive/2004/dis/Test#
74 wakaba 1.8 @x:
75     http://suika.fam.cx/~wakaba/archive/2004/dom/xml#
76 wakaba 1.1 @xml:
77     http://www.w3.org/XML/1998/namespace
78 wakaba 1.9 @xml-dtd:
79     http://www.w3.org/TR/REC-xml
80 wakaba 1.1 @xmlns:
81     http://www.w3.org/2000/xmlns/
82     @xp:
83     http://suika.fam.cx/~wakaba/archive/2004/dom/xml-parser#
84    
85     ## -- Features
86    
87     ElementTypeBinding:
88     @Name: FeatureDef
89     @ElementType:
90     dis:ResourceDef
91     @ShadowContent:
92     @@rdf:type: f|Feature
93     @@For: =ManakaiDOM|all
94    
95     ElementTypeBinding:
96     @Name: FeatureVerDef
97     @ElementType:
98     dis:ResourceDef
99     @ShadowContent:
100     @@rdf:type: f|Feature
101    
102     ElementTypeBinding:
103     @Name: featureQName
104     @ElementType:
105     f:name
106     @ShadowContent:
107     @@ContentType: DISCore|QName
108    
109     ResourceDef:
110     @QName: DOMString
111     @AliasFor: DOMMain|DOMString
112     @For: ManakaiDOM|DOM
113    
114     ResourceDef:
115     @QName: Node
116     @AliasFor: t|Node
117     @For: ManakaiDOM|DOM
118    
119     ResourceDef:
120     @QName: Element
121     @AliasFor: t|Element
122     @For: ManakaiDOM|DOM
123    
124     ResourceDef:
125     @QName: Document
126     @AliasFor: t|Document
127     @For: ManakaiDOM|DOM
128    
129 wakaba 1.6 ResourceDef:
130     @QName: DocumentXDoctype
131     @AliasFor: d|DocumentXDoctype
132     @For: ManakaiDOM|DOM
133    
134 wakaba 1.8 ResourceDef:
135     @QName: DTDef
136     @AliasFor: d|DocumentTypeDefinition
137     @For: ManakaiDOM|DOM
138    
139     ResourceDef:
140     @QName: ETDef
141     @AliasFor: d|ElementTypeDefinition
142     @For: ManakaiDOM|DOM
143    
144     ResourceDef:
145     @QName: ATDef
146     @AliasFor: d|AttributeDefinition
147     @For: ManakaiDOM|DOM
148    
149 wakaba 1.1 ElementTypeBinding:
150     @Name: ClsDef
151     @ElementType:
152     dis:ResourceDef
153     @ShadowContent:
154     @@rdf:type:
155     @@@@: dis|MultipleResource
156     @@@ForCheck: !ManakaiDOM|ForIF !ManakaiDOM|ForClass
157     @@resourceFor:
158     @@@@: ManakaiDOM|ForClass
159     @@@ForCheck: ManakaiDOM|ManakaiDOM !=ManakaiDOM|ManakaiDOM
160     @@For: ManakaiDOM|DOM3
161     @@For: =ManakaiDOM|ManakaiDOM
162    
163     @@rdf:type:
164     @@@@: DISLang|Class
165     @@@ForCheck: ManakaiDOM|ForClass
166    
167     ElementTypeBinding:
168     @Name: ClsQName
169     @ElementType:
170     dis:QName
171     @ShadowContent:
172     @@ForCheck: ManakaiDOM|ForClass
173    
174     ElementTypeBinding:
175     @Name: ClsISA
176     @ElementType:
177     dis:ISA
178     @ShadowContent:
179     @@ForCheck: ManakaiDOM|ForClass
180    
181     ElementTypeBinding:
182     @Name: nullCase
183     @ElementType:
184     dis:ResourceDef
185     @ShadowContent:
186     @@rdf:type: ManakaiDOM|InCase
187     @@Value:
188     @@@is-null:1
189    
190     ResourceDef:
191     @QName: LSParser
192     @AliasFor: DOMLS|LSParser
193     @For: ManakaiDOM|DOM3
194    
195     ClsDef:
196     @ClsQName: ManakaiXMLParser
197    
198     @Implement: DOMLS|LSParser
199    
200     @f:implements:
201     @@@: DOMLS|LSFeature30
202     @@For: ManakaiDOM|DOM3
203    
204 wakaba 1.11 @DISLang:role: gls|ParserRole
205 wakaba 1.1
206 wakaba 1.3 @enDesc:
207     Note that the <Class::ManakaiXMLParser> reports any XML errors
208     (syntax errors and / or well-formedness constraint errors)
209     via the <IF::DOMCore:error-handler> registered to
210     the <A::DOMLS:LSParser.domConfig> object. Each error has
211     its <A::DOMCore:DOMError.severity>, either <C::DOMCore:SEVERITY_ERROR>
212     or <C::DOMCore:SEVERITY_FATAL_ERROR>. However, their semantics
213     are slight different from the ones of <QUOTE::error> and
214     <QUOTE::fatal error> in XML; in this implemenetation,
215     <C::DOMCore:SEVERITY_ERROR> implies that the parsing process
216     can effectively be continued to detect more errors while
217     <C::DOMCore:SEVERITY_FATAL_ERROR> implies that the error
218     is serious so that the result document tree and any errors
219     might be far from the ones obtained when the error would not
220     be found.
221    
222 wakaba 1.1 @Attr:
223     @@Name: domConfig
224     @@enDesc:
225     The configuration of the parser.
226    
227     @@Get:
228     @@@Type: DOMCore|DOMConfiguration
229     @@@enDesc: The DOM configuration object.
230     @@@PerlDef:
231     __CODE{DOMCore|getConfigObject::
232     $target => $self,
233     $targetHash => $self,
234     $targetType => {<IFName::LSParser>},
235     $result => $r,
236     }__;
237    
238     @Method:
239     @@ManakaiDOM:isForInternal:1
240     @@ForCheck: ManakaiDOM|ForClass
241     @@Operator: DISPerl|NewMethod
242     @@enDesc:
243     Creates a new instance of the object.
244     @@Param:
245     @@@Name: impl
246 wakaba 1.11 @@@Type: gls|GLSImplementation
247 wakaba 1.1 @@@enDesc:
248     The implementation from which the parser is created.
249     @@Param:
250     @@@Name: features
251     @@@Type: DOMString
252     @@@dis:actualType: f|FeaturesString
253     @@@enDesc:
254     The set of features requested for the parser.
255     @@Return:
256     @@@Type: DOMMain|DOMObject
257     @@@dis:actualType: LSParser
258     @@@enDesc:
259     The newly created parser.
260     @@@PerlDef:
261     $r = bless {
262     <H::DOMCore:implementation> => $impl,
263     }, $self;
264    
265     @Method:
266     @@Name: parseString
267     @@enImplNote:
268     Non-standard - to be removed
269    
270     @@Param:
271     @@@Name: sourceText
272     @@@Type: DOMString
273     @@Return:
274     @@@Type: Document
275     @@@PerlDef:
276    
277     $self->{char} = [];
278     $self->{token} = [];
279 wakaba 1.6 $self->{entity} = [{
280     reptxt => \$sourceText,
281     line => 1,
282     column => 1,
283     pos => 0,
284     }];
285     $self->{entity_char} = [];
286     $self->{entity_token} = [];
287 wakaba 1.3 $self->{xml_version} = '1.0';
288     $self->{standalone} = false;
289 wakaba 1.11 $self->{general_entity} = {
290     lt => {is_predefined => true},
291     gt => {is_predefined => true},
292     amp => {is_predefined => true},
293     quot => {is_predefined => true},
294     apos => {is_predefined => true},
295     };
296 wakaba 1.6 $self->{param_entity} = {};
297 wakaba 1.9 $self->{attr} = {};
298     # $self->{attr}->{$element_type_name}->{$attr_name} = $attr_def
299 wakaba 1.6 $self->{has_error} = false;
300 wakaba 1.3 ## Well-formedness constraint Entity Declared takes effect?
301 wakaba 1.1
302     __DEEP{
303 wakaba 1.11 $r = $self->{<H::c|implementation>}-><M::DOMImpl.createDocument>;
304     $r-><AS::Document.strictErrorChecking> (false);
305     $self->{doc} = $r;
306     CORE::delete $self->{docx};
307     CORE::delete $self->{dtdef};
308     $self->{cfg} = $r-><AG::Document.domConfig>;
309     local $r->{<H::mn:node>}
310     ->{<H::cfg|entity-reference-read-only>} = false;
311    
312     ## Document entity -> |Document| node
313     $self->_parse_DocumentEntity;
314    
315     ## Replacement tree for general |Entity| nodes
316     my @ent = values %{$self->{general_entities}};
317     if (@ent) {
318     for my $ent (@ent) {
319     if (exists $ent->{reptxt}) {
320     my $ent_name = $ent->{name};
321     $self->{entity} = [<Code::getCopyOfEntityState::
322     $entity_type = 'general_entity',
323     $entity_name = $ent_name>];
324     $self->{token} = [];
325     $self->{char} = [];
326     ## TODO: External entity support
327     $self->_parse_InternalGeneralParsedEntity ($ent->{node});
328     $ent->{node}-><AS::x|Entity.hasReplacementTree> (true);
329     }
330     ## TODO: Read-only if configuration (for all entities)
331     }
332     }
333    
334     $r-><AS::Document.strictErrorChecking> (true);
335 wakaba 1.1 }__;
336    
337     @Method:
338     @@Name: shiftChar
339     @@ManakaiDOM:isForInternal:1
340     @@ForCheck: ManakaiDOM|ForClass
341     @@enDesc:
342     Returns the next character.
343     @@Return:
344     @@@Type: idl|long||ManakaiDOM|all
345     @@@enDesc:
346     The code position number of the next character, if any,
347 wakaba 1.6 or <CODE::-1>.
348 wakaba 1.1 @@@PerlDef:
349     if (@{$self->{char}}) {
350     $r = shift @{$self->{char}};
351     } else {
352 wakaba 1.7 no warnings 'substr';
353     ## substr outside length warnings at the end of the string
354 wakaba 1.6 GETCHAR: {
355     my $char = substr (${$self->{entity}->[-1]->{reptxt}},
356     $self->{entity}->[-1]->{pos}, 1);
357    
358 wakaba 1.7 if (defined $char and length $char) {
359 wakaba 1.13 $self->{entity}->[-1]->{pos}++;
360 wakaba 1.6 $r = ord $char;
361     if ($r == 0x000A) {
362     $self->{entity}->[-1]->{line}++;
363     $self->{entity}->[-1]->{column} = 1;
364     } elsif ($r == 0x000D) {
365     my $next_char = substr (${$self->{entity}->[-1]->{reptxt}},
366     $self->{entity}->[-1]->{pos}, 1);
367     if ($next_char eq "\x0A") {
368     $self->{entity}->[-1]->{pos}++;
369 wakaba 1.13 $self->{entity}->[-1]->{line}++;
370 wakaba 1.6 $self->{entity}->[-1]->{column} = 1;
371     } elsif ($next_char eq "\x85") {
372     if ($self->{xml_version} eq '1.1') {
373     $self->{entity}->[-1]->{pos}++;
374 wakaba 1.13 $self->{entity}->[-1]->{line}++;
375 wakaba 1.6 $self->{entity}->[-1]->{column} = 1;
376     } else {
377 wakaba 1.13 $self->{entity}->[-1]->{column}++;
378     ## Line number will be increased by next |shiftChar| call.
379 wakaba 1.6 }
380 wakaba 1.3 } else {
381 wakaba 1.13 $self->{entity}->[-1]->{line}++;
382 wakaba 1.6 $self->{entity}->[-1]->{column} = 1;
383     }
384     $r = 0x000A;
385     } elsif (
386     not ((0x0020 <= $r and $r <= 0x007E) or
387     (0x00A0 <= $r and $r <= 0xD7FF) or
388     (0xE000 <= $r and $r <= 0xFFFD) or
389     (0x10000 <= $r and $r <= 0x10FFFF)) and
390     $r != 0x0009 and $r != 0x0085 and
391     not ($self->{xml_version} eq '1.0' and
392     (0x007F <= $r and $r <= 0x009F))
393     ) {
394     my $location = {
395 wakaba 1.13 utf32_offset => $self->{entity}->[-1]->{pos} - 1,
396 wakaba 1.6 line_number => $self->{entity}->[-1]->{line},
397     column_number => $self->{entity}->[-1]->{column},
398     };
399     my $continue = __DOMCore:ERROR{xp|wf-legal-literal-character::
400     DOMCore|location => {$location},
401     xp|character-number => {$r},
402     }__;
403     unless ($continue) {
404     __EXCEPTION{DOMLS|PARSE_ERR}__;
405 wakaba 1.3 }
406 wakaba 1.6 $self->{has_error} = true;
407     $self->{entity}->[-1]->{column}++;
408     } elsif ($r == 0x0085 or $r == 0x2028) {
409     $r = 0x000A if $self->{xml_version} eq '1.1';
410 wakaba 1.13 ## Even in XML 1.0 it increases the line number.
411 wakaba 1.6 $self->{entity}->[-1]->{line}++;
412     $self->{entity}->[-1]->{column} = 1;
413 wakaba 1.3 } else {
414 wakaba 1.6 $self->{entity}->[-1]->{column}++;
415 wakaba 1.3 }
416     } else {
417 wakaba 1.6 $r = -1;
418 wakaba 1.3 }
419 wakaba 1.6 } # GETCHAR
420 wakaba 1.1 }
421    
422     @Method:
423     @@ManakaiDOM:isForInternal: 1
424     @@Operator: ManakaiDOM|MUErrorHandler
425     @@enDesc:
426     When a <IF::ecore|ErrorInterface||ManakaiDOM|Perl> is <Perl::report>ed,
427     then this method is invoked.
428    
429     The method calls the <cfg::DOMCore|error-handler> if the error is of
430     <IF::DOMCore|DOMError>. Otherwise, the error is re-thrown so that
431     corresponding <Perl::catch> clause, if any, can catch the error.
432     @@Param:
433     @@@Name: err
434     @@@Type: ecore|ErrorInterface||ManakaiDOM|Perl
435     @@@enDesc:
436     The reported error object.
437     @@Return:
438     @@@Type: DISPerl|Any
439     @@@enDesc:
440     If the <P::err> is a <IF::DOMCore|DOMError>, then the return value
441     of the error handler.
442    
443     {NOTE:: If the error is thrown, the method never returns.
444     }
445     @@@nullCase:
446     @@@@enDesc:
447     No error handler.
448     @@@PerlDef:
449     if ($err->isa (<IFName::DOMCore|DOMError||ManakaiDOM|ManakaiDOM>)) {
450     __DEEP{
451     A: {
452     my $cfg = $self-><AG::LSParser.domConfig>;
453     my $h = $cfg-><M::DOMCore|DOMConfiguration.getParameter>
454     ('error-handler');
455     $r = $h-><M::DOMCore|DOMErrorHandler.handleError> ($err);
456     } # A
457     }__;
458     } else {
459     $err-><M::ecore|ErrorInterface||ManakaiDOM|Perl.throw>;
460     }
461    
462     @DISPerl:dpgDef:
463    
464     /*
465     XML Document Entity
466    
467     document := prolog element *Misc
468     - *Char RestrictedChar *Char ;; [1]
469     */
470 wakaba 1.11 rule DocumentEntity : standalone {
471 wakaba 1.1 /*
472     prolog := XMLDecl? *Misc [doctypedecl *Misc] ;; [22]
473     */
474     ?lexmode 'DocumentStart';
475 wakaba 1.11
476     my $doc;
477     lang:Perl {
478     $doc = $self->{doc};
479     }
480 wakaba 1.1
481 wakaba 1.3 ~? (XDO) {
482     &_XMLDeclaration_ ($doc => $doc);
483    
484     ~ (PIC) {
485     ?lexmode DocumentProlog;
486     } else {
487     ?lexmode DocumentProlog;
488     }
489     } else {
490     ?lexmode 'DocumentProlog';
491     }
492 wakaba 1.1
493     // *Misc
494 wakaba 1.2 ~* (CDO) {
495 wakaba 1.1 &_CommentDeclaration_ ($doc => $doc, $parent => $doc);
496    
497     ~ (MDC) {
498     ?lexmode DocumentProlog;
499     } else {
500     ?lexmode DocumentProlog;
501     }
502     } (PIO) {
503     &_ProcessingInstruction_ ($doc => $doc, $parent => $doc);
504    
505     ~ (PIC) {
506     ?lexmode 'DocumentProlog';
507     } else {
508     ?lexmode DocumentProlog;
509     }
510     } (S) {
511     //
512     }
513    
514     // doctypedecl
515     ~? (MDO) {
516     &_DocumentTypeDeclaration_ ($doc => $doc);
517    
518 wakaba 1.3 ~ (MDC) {
519     ?lexmode DocumentMisc;
520     } else {
521     ?lexmode DocumentMisc;
522     }
523     } else {
524     lang:Perl {
525     $self->{standalone} = true;
526     }
527     ?lexmode DocumentMisc;
528 wakaba 1.1 }
529    
530     // *Misc
531 wakaba 1.2 ~* (CDO) {
532 wakaba 1.1 &_CommentDeclaration_ ($doc => $doc, $parent => $doc);
533    
534     ~ (MDC) {
535     ?lexmode DocumentMisc;
536     } else {
537     ?lexmode DocumentMisc;
538     }
539     } (PIO) {
540     &_ProcessingInstruction_ ($doc => $doc, $parent => $doc);
541    
542     ~ (PIC) {
543     ?lexmode 'DocumentMisc';
544     } else {
545     ?lexmode DocumentMisc;
546     }
547     } (S) {
548     //
549     }
550    
551     // Document element
552     ~ (STAGO) {
553     &Element_ ($doc => $doc, $parent => $doc)
554     : unshift-current-token;
555     ~ (TAGC) {
556     ?lexmode DocumentEnd;
557     } else {
558     ?lexmode DocumentEnd;
559     }
560     } else {
561     ?lexmode 'DocumentEnd';
562     }
563    
564     // *Misc
565 wakaba 1.2 ~* (CDO) {
566 wakaba 1.1 &_CommentDeclaration_ ($doc => $doc, $parent => $doc);
567    
568     ~ (MDC) {
569     ?lexmode DocumentEnd;
570     } else {
571     ?lexmode DocumentEnd;
572     }
573     } (PIO) {
574     &_ProcessingInstruction_ ($doc => $doc, $parent => $doc);
575     ~ (PIC) {
576     ?lexmode 'DocumentEnd';
577     } else {
578     ?lexmode DocumentEnd;
579     }
580     } (S) {
581     //
582     }
583    
584     ~ (#EOF) { }
585    
586     lang:Perl {
587     if ($self->{has_error}) {
588     __EXCEPTION{DOMLS|PARSE_ERR::
589     }__;
590     }
591     }
592     } // DocumentEntity
593 wakaba 1.11
594     /*
595     Internal General Parsed Entity
596    
597     An internal general parsed entity is well-formed if its
598     replacement text matches the production labeled |content|.
599     */
600     rule InternalGeneralParsedEntity ($ent) : standalone {
601     ?lexmode ElementContent;
602    
603     my $ns;
604     lang:Perl {
605     $ns = {
606     xml => <Q::xml:>,
607     xmlns => <Q::xmlns:>,
608     };
609     }
610    
611     &content ($parent => $ent, $ns => $ns);
612    
613     ~ (#EOF) { }
614     } // InternalGeneralParsedEntity
615    
616 wakaba 1.1 /*
617     XML Declaration
618    
619     XMLDecl := '<?xml' VersionInfo
620     [EncodingDecl]
621     [SDDecl]
622     [S] '?>' ;; [23]
623    
624     NOTE: XML declaration is optional in XML 1.0
625     while it is required in XML 1.1.
626     */
627 wakaba 1.3 rule _XMLDeclaration_ ($doc) {
628     ?lexmode XMLDeclaration;
629    
630     ~ (S) { }
631    
632     ~ (Name == 'version') {
633     ~? (S) { }
634     ~ (VI) { }
635     ~? (S) { }
636 wakaba 1.1
637 wakaba 1.3 my $ver;
638     my $bad_token;
639    
640     ~ (LIT) {
641     ?lexmode AttributeValueLiteral;
642    
643     ~ (STRING) {
644     lang:Perl ($version => $token.value) {
645     $ver = $version;
646     $bad_token = $token;
647     }
648     }
649    
650     ~ (LIT) {
651     ?lexmode XMLDeclaration;
652     }
653     } (LITA) {
654     ?lexmode AttributeValueLiteralA;
655    
656     ~ (STRING) {
657     lang:Perl ($version => $token.value) {
658     $ver = $version;
659     $bad_token = $token;
660     }
661     }
662    
663     ~ (LITA) {
664     ?lexmode XMLDeclaration;
665     }
666     }
667    
668     lang:Perl : has-error {
669     unless ($ver eq '1.0' or $ver eq '1.1') {
670     my $location;
671     __CODE{xp|get-location-from-token::
672     $token => {$bad_token},
673     $result => {$location},
674     }__;
675     my $continue = __DOMCore:ERROR{xp|wf-unsupported-xml-version::
676     DOMCore|location => {$location},
677     xp|parent => {$doc},
678     infoset|version => {$ver},
679     xp|error-token => {$bad_token},
680     }__;
681     unless ($continue) {
682     __EXCEPTION{DOMLS|PARSE_ERR}__;
683     }
684     $self->{has_error} = true;
685     }
686     $doc-><AS::Document.xmlVersion> ($ver);
687     $self->{xml_version} = $ver;
688     }
689    
690     ~? (S) { }
691 wakaba 1.1 }
692    
693 wakaba 1.3 ~? (Name == 'encoding') {
694     ~? (S) { }
695     ~ (VI) { }
696     ~? (S) { }
697    
698     my $ver;
699     my $bad_token;
700    
701     ~ (LIT) {
702     ?lexmode AttributeValueLiteral;
703    
704     ~ (STRING) {
705     lang:Perl ($version => $token.value) {
706     $ver = $version;
707     $bad_token = $token;
708     }
709     }
710    
711     ~ (LIT) {
712     ?lexmode XMLDeclaration;
713     }
714     } (LITA) {
715     ?lexmode AttributeValueLiteralA;
716    
717     ~ (STRING) {
718     lang:Perl ($version => $token.value) {
719     $ver = $version;
720     $bad_token = $token;
721     }
722     }
723    
724     ~ (LITA) {
725     ?lexmode XMLDeclaration;
726     }
727     }
728    
729     lang:Perl : has-error {
730     unless ($ver =~ /\A[A-Za-z][A-Za-z0-9._-]*\z/) {
731     my $location;
732     __CODE{xp|get-location-from-token::
733     $token => {$bad_token},
734     $result => {$location},
735     }__;
736     my $continue = __DOMCore:ERROR{xp|wf-malformed-enc-name::
737     DOMCore|location => {$location},
738     xp|parent => {$doc},
739     xp|name => {$ver},
740     xp|error-token => {$bad_token},
741     }__;
742     unless ($continue) {
743     __EXCEPTION{DOMLS|PARSE_ERR}__;
744     }
745     $self->{has_error} = true;
746     }
747     $doc-><AS::Document.xmlEncoding> ($ver);
748     }
749    
750     ~? (S) { }
751 wakaba 1.1 }
752 wakaba 1.3
753     ~? (Name == 'standalone') {
754     ~? (S) { }
755     ~ (VI) { }
756     ~? (S) { }
757    
758     my $ver;
759     my $bad_token;
760    
761     ~ (LIT) {
762     ?lexmode AttributeValueLiteral;
763    
764     ~ (STRING) {
765     lang:Perl ($version => $token.value) {
766     $ver = $version;
767     $bad_token = $token;
768     }
769     }
770    
771     ~ (LIT) {
772     ?lexmode XMLDeclaration;
773     }
774     } (LITA) {
775     ?lexmode AttributeValueLiteralA;
776    
777     ~ (STRING) {
778     lang:Perl ($version => $token.value) {
779     $ver = $version;
780     $bad_token = $token;
781     }
782     }
783 wakaba 1.1
784 wakaba 1.3 ~ (LITA) {
785     ?lexmode XMLDeclaration;
786     }
787     }
788    
789     lang:Perl : has-error {
790     unless ($ver eq 'yes' or $ver eq 'no') {
791     my $location;
792     __CODE{xp|get-location-from-token::
793     $token => {$bad_token},
794     $result => {$location},
795     }__;
796     my $continue = __DOMCore:ERROR{xp|wf-malformed-xml-standalone::
797     DOMCore|location => {$location},
798     xp|parent => {$doc},
799     xp|name => {$ver},
800     xp|error-token => {$bad_token},
801     }__;
802     unless ($continue) {
803     __EXCEPTION{DOMLS|PARSE_ERR}__;
804     }
805     $self->{has_error} = true;
806     }
807 wakaba 1.13 if ($ver eq 'yes') {
808     $doc-><AS::Document.xmlStandalone> (true);
809     $self->{standalone} = true;
810     }
811 wakaba 1.3 }
812    
813     ~? (S) { }
814     }
815    
816     // ~ (PIC) { }
817     } // _XMLDeclaration_
818 wakaba 1.1
819     /*
820     Comment Declaration
821    
822     Comment := '<!--' *(Char - '-' / '-' (Char - '-'))
823     '-->' ;; [15]
824 wakaba 1.4 */
825 wakaba 1.1 rule _CommentDeclaration_ ($doc, $parent) {
826     ?lexmode 'CommentDeclaration';
827    
828     ~? (STRING) {
829     lang:Perl ($data => $token.value) {
830     my $com = $doc-><M::Document.createComment> ($data);
831     $parent-><M::Node.appendChild> ($com);
832     }
833     } else {
834     lang:Perl {
835     my $com = $doc-><M::Document.createComment> ('');
836     $parent-><M::Node.appendChild> ($com);
837     }
838     }
839    
840     ~ (COM) {
841     ?lexmode MarkupDeclaration;
842     } else {
843     ?lexmode MarkupDeclaration;
844     }
845    
846     // ~ (MDC) { }
847 wakaba 1.4 } // _CommentDeclaration
848     _
849     rule _CommentDeclarationDTD ($doc) {
850     ?lexmode 'CommentDeclaration';
851    
852     ~? (STRING) {
853     //
854     }
855    
856     ~ (COM) {
857     ?lexmode MarkupDeclaration;
858     } else {
859     ?lexmode MarkupDeclaration;
860     }
861    
862     ~ (MDC) {
863     ?lexmode DTD;
864     } else {
865     ?lexmode DTD;
866     }
867     } // _CommentDeclarationDTD
868    
869 wakaba 1.1 /*
870     Processing Instruction
871    
872     PI := '<?' PITarget [S *Char - *Char '?>' *Char]
873     '?>' ;; [16]
874     */
875     rule _ProcessingInstruction_ ($doc, $parent) {
876     ?lexmode 'PIName';
877    
878     my $pi;
879    
880     ~ (Name) {
881 wakaba 1.3 lang:Perl ($name => $token.value) : has-error {
882 wakaba 1.1 if (lc $name eq 'xml') {
883 wakaba 1.3 my $location;
884     __CODE{xp|get-location-from-token::
885     $token => {$token},
886     $result => {$location},
887     }__;
888     my $continue = __DOMCore:ERROR{xp|wf-pi-target-is-xml::
889     xp|name => {$name},
890     DOMCore|location => {$location},
891     xp|parent => {$parent},
892     }__;
893     unless ($continue) {
894     __EXCEPTION{DOMLS|PARSE_ERR::
895     }__;
896     }
897     $self->{has_error} = true;
898 wakaba 1.1 }
899     ## TODO: Namespace well-formedness
900     $pi = $doc-><M::Document.createProcessingInstruction>
901     ($name);
902     }
903     }
904    
905     ~ (S) {
906     ?lexmode 'PIData';
907    
908     my $tdata;
909    
910     ~? (DATA) {
911     lang:Perl ($data => $token.value) {
912     $tdata = $data;
913     }
914     } else {
915     lang:Perl {
916     $tdata = '';
917     }
918     }
919    
920     lang:Perl {
921     $pi-><AS::Node.nodeValue> ($tdata);
922     }
923     }
924    
925     lang:Perl {
926     $parent-><M::Node.appendChild> ($pi);
927     }
928    
929     // ~ (PIC) { }
930     } // _ProcessingInstruction_
931 wakaba 1.4
932 wakaba 1.6 /*
933     Processing instruction in DTD
934     */
935     rule _ProcessingInstructionDTD ($doc, $doctype) {
936 wakaba 1.4 ?lexmode 'PIName';
937 wakaba 1.6
938     my $pi;
939 wakaba 1.4
940     ~ (Name) {
941 wakaba 1.6 lang:Perl ($name => $token.value) : has-error {
942     if (lc $name eq 'xml') {
943     my $location;
944     __CODE{xp|get-location-from-token::
945     $token => {$token},
946     $result => {$location},
947     }__;
948     my $continue = __DOMCore:ERROR{xp|wf-pi-target-is-xml::
949     xp|name => {$name},
950     DOMCore|location => {$location},
951     xp|parent => {$doctype},
952     }__;
953     unless ($continue) {
954     __EXCEPTION{DOMLS|PARSE_ERR::
955     }__;
956     }
957     $self->{has_error} = true;
958     }
959     ## TODO: Namespace well-formedness
960     $pi = $doc-><M::Document.createProcessingInstruction>
961     ($name);
962     }
963 wakaba 1.4 }
964    
965     ~ (S) {
966     ?lexmode 'PIData';
967    
968 wakaba 1.6 my $tdata;
969    
970 wakaba 1.4 ~? (DATA) {
971 wakaba 1.6 lang:Perl ($data => $token.value) {
972     $tdata = $data;
973     }
974     } else {
975     lang:Perl {
976     $tdata = '';
977     }
978     }
979    
980     lang:Perl {
981     $pi-><AS::Node.nodeValue> ($tdata);
982 wakaba 1.4 }
983     }
984    
985 wakaba 1.6 lang:Perl {
986     $doctype-><M::Node.appendChild> ($pi);
987     }
988    
989 wakaba 1.4 ~ (PIC) {
990     ?lexmode DTD;
991     } else {
992     ?lexmode DTD;
993     }
994     } // _ProcessingInstructionDTD
995 wakaba 1.1
996     /*
997     Element content parsing mode
998    
999     element := EmptyElemTag /
1000     STag content ETag ;; [39]
1001     content := (CharData / element / Reference / CDSect /
1002     PI / Comment) ;; [43]
1003     */
1004 wakaba 1.6 rule Element_ ($doc, $parent, $ns) : standalone {
1005 wakaba 1.1 ?lexmode 'ElementContent';
1006    
1007     my $node; // Current "parent" node
1008     my $nodes; // Node stack (w/o $current_node)
1009     my $type; // Current "parent" element type QName
1010     my $types; // Element type stack (w/o $current_type)
1011 wakaba 1.6 //my $ns; // Current in-scope namespace bindings
1012 wakaba 1.1 my $nses; // Namespace binding stack (w/o $current_ns)
1013    
1014     lang:Perl {
1015     $node = $parent;
1016     $nodes = [];
1017     $type = '';
1018     $types = [];
1019 wakaba 1.6 $ns ||= {
1020 wakaba 1.1 xml => <Q::xml:>,
1021     xmlns => <Q::xmlns:>,
1022     };
1023     $nses = [];
1024     }
1025    
1026     ~* : name => CONTENT
1027     (CharData) {
1028     // Character data
1029     lang:Perl ($data => $token.value) {
1030     $node-><M::Node.appendChild>
1031     ($doc-><M::Document.createTextNode> ($data));
1032     }
1033     } (STAGO) {
1034     // Start tag or empty element tag
1035    
1036     ?lexmode 'StartTag';
1037    
1038     ~ (Name) {
1039     my $attrs;
1040     lang:Perl ($name => $token.value) {
1041     push @{$types}, $type;
1042     $type = $name;
1043     $attrs = {};
1044     }
1045    
1046     ~? (S) {
1047     &AttributeSpecificationList
1048     ($doc => $doc, $attrs => $attrs);
1049     }
1050    
1051     my $el;
1052 wakaba 1.9
1053     /*
1054     Note that this implementation does not perform
1055     attribute value tokenization (but does white space
1056     normalization common to attribute types) and
1057     construct the tree as is. DOM Level 3 Core spec
1058     is unclear on this point. With tokenization,
1059     entity references cannot be preserved.
1060    
1061     The manakai Node.nodeValue and Attr.value attributes
1062     do tokenization according to attribute types.
1063     */
1064    
1065     /*
1066     ISSUE: Should |xml:id| attribute be typed?
1067     */
1068 wakaba 1.1
1069     lang:Perl {
1070     push @{$nses}, $ns;
1071     $ns = {%$ns};
1072    
1073     my %gattr;
1074     my %lattr;
1075     for my $atqname (keys %$attrs) {
1076     my ($pfx, $lname) = split /:/, $atqname;
1077 wakaba 1.9 $attrs->{$atqname}->{def} = $self->{attr}->{$type}->{$atqname};
1078 wakaba 1.1 if (defined $lname) { ## Global attribute
1079     ## TODO: Namespace well-formedness (lname is NCName)
1080     if ($pfx eq 'xmlns') {
1081     my $nsuri = $attrs->{$atqname}->{value};
1082     if ($lname eq 'xml' and
1083     $nsuri ne <Q::xml:>) {
1084     ## TODO: error
1085     } elsif ($lname eq 'xmlns') {
1086     ## TODO: error
1087     }
1088     if ($nsuri eq '') {
1089     ## TODO: error in XML 1.0
1090     } elsif ($nsuri eq <Q::xml:> and
1091     $lname ne 'xml') {
1092     ## TODO: error
1093     } elsif ($nsuri eq <Q::xmlns:>) {
1094     ## TODO: error
1095     }
1096     $ns->{$lname} = $attrs->{$atqname}->{value};
1097 wakaba 1.9 if ($attrs->{$atqname}->{def}) {
1098     my $dt = $attrs->{$atqname}->{def}-><AG::ATDef.declaredType>;
1099     if ({
1100     <C::ATDef.ID_ATTR> => true,
1101     <C::ATDef.IDREF_ATTR> => true,
1102     <C::ATDef.IDREFS_ATTR> => true,
1103     <C::ATDef.ENTITY_ATTR> => true,
1104     <C::ATDef.ENTITIES_ATTR> => true,
1105     <C::ATDef.NMTOKEN_ATTR> => true,
1106     <C::ATDef.NMTOKENS_ATTR> => true,
1107     <C::ATDef.NOTATION_ATTR> => true,
1108     <C::ATDef.ENUMERATION_ATTR> => true,
1109     }->{$dt}) {
1110     ## Tokenization (XML 1 3.3.3)
1111     for ($ns->{$lname}) {
1112     s/^\x20+//;
1113     s/\x20+\z//;
1114     s/\x20+/ /g;
1115     }
1116     }
1117     }
1118 wakaba 1.1 delete $ns->{$lname} unless length $ns->{$lname};
1119     } elsif ($pfx eq '') {
1120     ## TODO: pfx is not NCName error
1121     } else {
1122     if ($gattr{$pfx}->{$lname}) {
1123     ## TODO: Namespace well-formedness error
1124     }
1125     }
1126     $gattr{$pfx}->{$lname} = $attrs->{$atqname};
1127     } else { ## Local attribute
1128     if ($pfx eq 'xmlns') {
1129     $ns->{''} = $attrs->{xmlns}->{value};
1130 wakaba 1.9 if ($attrs->{$atqname}->{def}) {
1131     my $dt = $attrs->{$atqname}->{def}-><AG::ATDef.declaredType>;
1132     if ({
1133     <C::ATDef.ID_ATTR> => true,
1134     <C::ATDef.IDREF_ATTR> => true,
1135     <C::ATDef.IDREFS_ATTR> => true,
1136     <C::ATDef.ENTITY_ATTR> => true,
1137     <C::ATDef.ENTITIES_ATTR> => true,
1138     <C::ATDef.NMTOKEN_ATTR> => true,
1139     <C::ATDef.NMTOKENS_ATTR> => true,
1140     <C::ATDef.NOTATION_ATTR> => true,
1141     <C::ATDef.ENUMERATION_ATTR> => true,
1142     }->{$dt}) {
1143     ## Tokenization (XML 1 3.3.3)
1144     for ($ns->{''}) {
1145     s/^\x20+//;
1146     s/\x20+\z//;
1147     s/\x20+/ /g;
1148     }
1149     }
1150     }
1151 wakaba 1.1 delete $ns->{''} unless length $ns->{''};
1152     } else {
1153     $lattr{$pfx} = $attrs->{$atqname};
1154     }
1155     }
1156     }
1157    
1158     my ($pfx, $lname) = split /:/, $type;
1159     my $nsuri;
1160     ## TODO: lname is NCName?
1161     if (defined $lname) { ## Prefixed namespace
1162     if ($pfx eq '') {
1163     ## TODO: pfx is not NCName error
1164     }
1165     if (defined $ns->{$pfx}) {
1166     $nsuri = $ns->{$pfx};
1167     } else {
1168     ## TODO: namespace ill-formed
1169     }
1170     } else { ## Default namespace
1171     $nsuri = $ns->{''};
1172     }
1173    
1174     $el = $doc-><M::Document.createElementNS>
1175     ($nsuri, $type);
1176    
1177     if ($attrs->{xmlns}) {
1178     my $attr = $doc-><M::Document.createAttributeNS>
1179     (<Q::xmlns:>, 'xmlns');
1180     for (@{$attrs->{xmlns}->{nodes}}) {
1181     $attr-><M::Node.appendChild> ($_);
1182     }
1183 wakaba 1.9 if ($attrs->{xmlns}->{def}) {
1184     __CODE{t|setAttrType::
1185     $attr => $attr,
1186     $type => {$attrs->{xmlns}->{def}-><AG::ATDef.declaredType>},
1187     }__;
1188     }
1189 wakaba 1.1 $el-><M::Element.setAttributeNodeNS> ($attr);
1190     }
1191    
1192     for my $lname (keys %lattr) {
1193     my $attr = $doc-><M::Document.createAttributeNS>
1194     (null, $lname);
1195     for (@{$lattr{$lname}->{nodes}}) {
1196     $attr-><M::Node.appendChild> ($_);
1197     }
1198 wakaba 1.9 if ($attrs->{$lname}->{def}) {
1199     __CODE{t|setAttrType::
1200     $attr => $attr,
1201     $type => {$attrs->{$lname}->{def}-><AG::ATDef.declaredType>},
1202     }__;
1203     }
1204 wakaba 1.1 $el-><M::Element.setAttributeNodeNS> ($attr);
1205     }
1206    
1207     for my $pfx (keys %gattr) {
1208     for my $lname (keys %{$gattr{$pfx}}) {
1209     my $attr = $doc-><M::Document.createAttributeNS>
1210     ($ns->{$pfx}, $pfx.':'.$lname);
1211     for (@{$gattr{$pfx}->{$lname}->{nodes}}) {
1212     $attr-><M::Node.appendChild> ($_);
1213     }
1214 wakaba 1.9 if ($attrs->{$pfx}->{$lname}->{def}) {
1215     __CODE{t|setAttrType::
1216     $attr => $attr,
1217     $type => {$attrs->{$pfx}->{$lname}
1218     ->{def}-><AG::ATDef.declaredType>},
1219     }__;
1220     }
1221 wakaba 1.1 $el-><M::Element.setAttributeNodeNS> ($attr);
1222     }
1223     }
1224    
1225     $node-><M::Node.appendChild> ($el);
1226     }
1227    
1228     ~ (TAGC) {
1229     lang:Perl {
1230     push @{$nodes}, $node;
1231     $node = $el;
1232     }
1233     ?lexmode ElementContent;
1234 wakaba 1.6 } (NESTC) {
1235     my $is_docel;
1236 wakaba 1.1 lang:Perl {
1237     $ns = pop @{$nses};
1238     $type = pop @{$types};
1239 wakaba 1.6 $is_docel = (@{$types} == 0);
1240     }
1241    
1242     if-true ($is_docel) {
1243     return;
1244     }
1245    
1246     ~ (TAGC) {
1247     ?lexmode ElementContent;
1248     } else {
1249     ?lexmode ElementContent;
1250 wakaba 1.1 }
1251     } else {
1252     ?lexmode ElementContent;
1253     }
1254     } else {
1255     ?lexmode ElementContent;
1256     }
1257    
1258     } (ETAGO) {
1259     // End tag
1260    
1261     ?lexmode 'EndTag';
1262    
1263     my $is_docel;
1264    
1265     ~ (Name) {
1266 wakaba 1.3 lang:Perl ($name => $token.value) : has-error {
1267 wakaba 1.1 if ($name eq $type) {
1268     $type = pop @{$types};
1269     if ($type eq '') {
1270     $is_docel = true;
1271     }
1272     $node = pop @{$nodes};
1273     $ns = pop @{$nses};
1274     } else {
1275 wakaba 1.3 my $location;
1276     __CODE{xp|get-location-from-token::
1277     $token => $token,
1278     $result => $location,
1279     }__;
1280     my $continue = __DOMCore:ERROR{xp|wf-element-type-match::
1281     DOMCore:location => {$location},
1282     xp|token => {$token},
1283     xp|expected-element-type => {$type},
1284     xp|actual-element-type => {$name},
1285     xp|node => {$node},
1286     }__;
1287     unless ($continue) {
1288     __EXCEPTION{DOMLS|PARSE_ERR}__;
1289     }
1290     $self->{has_error} = true;
1291 wakaba 1.1 }
1292     }
1293     }
1294    
1295     ~? (S) { }
1296    
1297     if-true ($is_docel) {
1298 wakaba 1.3 lang:Perl : has-error {
1299 wakaba 1.1 if (@{$types}) {
1300 wakaba 1.3 my $location;
1301     __CODE{xp|get-location-from-token::
1302     $token => $token,
1303     $result => $location,
1304     }__;
1305     for my $type (reverse @{$types}) {
1306     my $continue = __DOMCore:ERROR{xp|wf-no-end-tag::
1307     DOMCore:location => {$location},
1308     xp|token => {$token},
1309     xp|expected-element-type => {$type},
1310     xp|node => {$node},
1311     }__;
1312     unless ($continue) {
1313     __EXCEPTION{DOMLS|PARSE_ERR}__;
1314     }
1315     $node = shift @{$nodes};
1316     }
1317     $self->{has_error} = true;
1318 wakaba 1.1 }
1319     }
1320     return;
1321     }
1322    
1323     ~ (TAGC) {
1324     ?lexmode ElementContent;
1325     } else {
1326     ?lexmode 'ElementContent';
1327     }
1328    
1329     } (HCRO) {
1330     &_HexadecimalCharacterReference_
1331     ($doc => $doc, $parent => $node);
1332    
1333     ~ (REFC) {
1334     ?lexmode 'ElementContent';
1335     } else {
1336     ?lexmode ElementContent;
1337     }
1338     } (CRO) {
1339     &_NumericCharacterReference_
1340     ($doc => $doc, $parent => $node);
1341    
1342     ~ (REFC) {
1343     ?lexmode 'ElementContent';
1344     } else {
1345     ?lexmode ElementContent;
1346     }
1347     } (ERO) {
1348 wakaba 1.6 &_GeneralEntityReferenceEC
1349     ($doc => $doc, $parent => $node, $ns => $ns);
1350 wakaba 1.1 } (CDO) {
1351     &_CommentDeclaration_ ($doc => $doc, $parent => $node);
1352    
1353     ~ (MDC) {
1354     ?lexmode ElementContent;
1355     } else {
1356     ?lexmode ElementContent;
1357     }
1358     } (CDSO) {
1359     &_CDATASection_ ($doc => $doc, $parent => $node);
1360    
1361     ~ (MSE) {
1362     ?lexmode 'ElementContent';
1363     } else {
1364     ?lexmode ElementContent;
1365     }
1366     } (PIO) {
1367     &_ProcessingInstruction_ ($doc => $doc, $parent => $node);
1368    
1369     ~ (PIC) {
1370     ?lexmode 'ElementContent';
1371     } else {
1372     ?lexmode ElementContent;
1373     }
1374     }
1375 wakaba 1.3
1376     ~ (#NONE) { }
1377 wakaba 1.1 } // Element_
1378 wakaba 1.11
1379     /*
1380     content := [CharData]
1381     *((element / Reference / CDSect / PI / Comment) [CharData])
1382     */
1383     rule content ($parent, $ns) {
1384     // ?lexmode ElementContent;
1385    
1386     my $doc;
1387     lang:Perl {
1388     $doc = $self->{doc};
1389     }
1390    
1391     ~* (CharData) {
1392     lang:Perl ($data => $token.value) {
1393     $parent-><M::Node.appendChild>
1394     ($self->{doc}-><M::Document.createTextNode> ($data));
1395     }
1396     } (STAGO) {
1397     &Element_ ($doc => $doc, $parent => $parent, $ns => $ns)
1398     : unshift-current-token;
1399     ~ (TAGC) {
1400     ?lexmode ElementContent;
1401     } else {
1402     ?lexmode ElementContent;
1403     }
1404     } (HCRO) {
1405     &_HexadecimalCharacterReference_
1406     ($doc => $doc, $parent => $parent);
1407    
1408     ~ (REFC) {
1409     ?lexmode 'ElementContent';
1410     } else {
1411     ?lexmode ElementContent;
1412     }
1413     } (CRO) {
1414     &_NumericCharacterReference_
1415     ($doc => $doc, $parent => $parent);
1416    
1417     ~ (REFC) {
1418     ?lexmode 'ElementContent';
1419     } else {
1420     ?lexmode ElementContent;
1421     }
1422     } (ERO) {
1423     &_GeneralEntityReferenceEC
1424     ($doc => $doc, $parent => $parent, $ns => $ns);
1425     } (CDO) {
1426     &_CommentDeclaration_ ($doc => $doc, $parent => $parent);
1427    
1428     ~ (MDC) {
1429     ?lexmode ElementContent;
1430     } else {
1431     ?lexmode ElementContent;
1432     }
1433     } (CDSO) {
1434     &_CDATASection_ ($doc => $doc, $parent => $parent);
1435    
1436     ~ (MSE) {
1437     ?lexmode 'ElementContent';
1438     } else {
1439     ?lexmode ElementContent;
1440     }
1441     } (PIO) {
1442     &_ProcessingInstruction_ ($doc => $doc, $parent => $parent);
1443    
1444     ~ (PIC) {
1445     ?lexmode 'ElementContent';
1446     } else {
1447     ?lexmode ElementContent;
1448     }
1449     }
1450     } // content
1451 wakaba 1.1
1452     rule AttributeSpecificationList ($doc, $attrs)
1453     : standalone
1454     {
1455     ?lexmode 'StartTag';
1456    
1457     my $i;
1458     lang:Perl {
1459     $i = 0;
1460     }
1461    
1462     ~* (Name) {
1463     my $atqname;
1464     lang:Perl ($name => $token.value) {
1465     $atqname = $name;
1466     }
1467    
1468     my $vals;
1469     lang:Perl {
1470     if ($attrs->{$atqname}) {
1471 wakaba 1.3 my $location;
1472     __CODE{xp|get-location-from-token::
1473     $token => $token,
1474     $result => $location,
1475     }__;
1476     my $continue = __DOMCore:ERROR{xp|wf-unique-att-spec::
1477     DOMCore:location => {$location},
1478     xp|token => {$token},
1479     xp|name => {$atqname},
1480     }__;
1481     unless ($continue) {
1482     __EXCEPTION{DOMLS|PARSE_ERR}__;
1483     }
1484     $self->{has_error} = true;
1485 wakaba 1.1 }
1486    
1487     $vals = $attrs->{$atqname} = {
1488     nodes => [],
1489     value => '',
1490     index => $i++,
1491     };
1492     }
1493 wakaba 1.3
1494     ~? (S) { }
1495     ~ (VI) { }
1496     ~? (S) { }
1497 wakaba 1.1
1498     ~ (LIT) {
1499     &_AttributeValueSpecification_
1500     ($doc => $doc, $vals => $vals);
1501    
1502     ~ (LIT) {
1503     ?lexmode StartTag;
1504     } else {
1505     ?lexmode StartTag;
1506     }
1507     } (LITA) {
1508     &_AttributeValueSpecificationA_
1509     ($doc => $doc, $vals => $vals);
1510    
1511     ~ (LITA) {
1512     ?lexmode StartTag;
1513     } else {
1514     ?lexmode StartTag;
1515     }
1516     }
1517     } (S) : separator : terminator? { }
1518     } // AttributeSpecificationList
1519    
1520     rule _AttributeValueSpecification_ ($doc, $vals) {
1521     // ~ (LIT) { }
1522     ?lexmode 'AttributeValueLiteral';
1523    
1524     ~* (STRING) {
1525     lang:Perl ($value => $token.value) {
1526     $value =~ s/[\x09\x0A\x0D]/ /g;
1527     my $text = $doc-><M::Document.createTextNode> ($value);
1528     push @{$vals->{nodes}}, $text;
1529     $vals->{value} .= $value;
1530     }
1531     } (HCRO) {
1532     &_HexadecimalCharacterReferenceV_
1533     ($doc => $doc, $vals => $vals);
1534    
1535     ~ (REFC) {
1536     ?lexmode AttributeValueLiteral;
1537     } else {
1538     ?lexmode AttributeValueLiteral;
1539     }
1540     } (CRO) {
1541     &_NumericCharacterReferenceV_
1542     ($doc => $doc, $vals => $vals);
1543    
1544     ~ (REFC) {
1545     ?lexmode AttributeValueLiteral;
1546     } else {
1547     ?lexmode AttributeValueLiteral;
1548     }
1549     } (ERO) {
1550     // TODO: Attribute value normalization
1551     &_GeneralEntityReferenceV_
1552     ($doc => $doc, $vals => $vals);
1553    
1554     ~ (REFC) {
1555     ?lexmode AttributeValueLiteral;
1556     } else {
1557     ?lexmode AttributeValueLiteral;
1558     }
1559     }
1560    
1561     // ~ (LIT) { } (LITA) { }
1562     } // _AttributeValueSpecification_
1563    
1564     rule _AttributeValueSpecificationA_ ($doc, $vals) {
1565     // ~ (LITA) { }
1566     ?lexmode 'AttributeValueLiteralA';
1567    
1568     ~* (STRING) {
1569     lang:Perl ($value => $token.value) {
1570     $value =~ s/[\x09\x0A\x0D]/ /g;
1571     my $text = $doc-><M::Document.createTextNode> ($value);
1572     push @{$vals->{nodes}}, $text;
1573     $vals->{value} .= $value;
1574     }
1575     } (HCRO) {
1576     &_HexadecimalCharacterReferenceV_
1577     ($doc => $doc, $vals => $vals);
1578    
1579     ~ (REFC) {
1580     ?lexmode AttributeValueLiteralA;
1581     } else {
1582     ?lexmode AttributeValueLiteralA;
1583     }
1584     } (CRO) {
1585     &_NumericCharacterReferenceV_
1586     ($doc => $doc, $vals => $vals);
1587    
1588     ~ (REFC) {
1589     ?lexmode AttributeValueLiteralA;
1590     } else {
1591     ?lexmode AttributeValueLiteralA;
1592     }
1593     } (ERO) {
1594     // TODO: Attribute value normalization
1595     &_GeneralEntityReferenceV_
1596     ($doc => $doc, $vals => $vals);
1597    
1598     ~ (REFC) {
1599     ?lexmode AttributeValueLiteralA;
1600     } else {
1601     ?lexmode AttributeValueLiteralA;
1602     }
1603     }
1604    
1605     // ~ (LITA) { }
1606     } // _AttributeValueSpecificationA_
1607    
1608     /*
1609 wakaba 1.11 Parsing replacement text of an entity referenced in
1610     an attribute value specification.
1611     */
1612     rule AttributeValueLiteralE_ ($parent, $vals)
1613     : recursive
1614     {
1615     // ?lexmode AttributeValueLiteralE;
1616    
1617     ~* (STRING) {
1618     lang:Perl ($value => $token.value) {
1619     $value =~ s/[\x09\x0A\x0D]/ /g;
1620     my $text = $self->{doc}-><M::Document.createTextNode> ($value);
1621     $parent-><M::Node.appendChild> ($text);
1622     $vals->{value} .= $value;
1623     }
1624     } (HCRO) {
1625     &_HexadecimalCharacterReferenceAE_
1626     ($parent => $parent, $vals => $vals);
1627    
1628     ~ (REFC) {
1629     ?lexmode AttributeValueLiteralE;
1630     } else {
1631     ?lexmode AttributeValueLiteralE;
1632     }
1633     } (CRO) {
1634     &_NumericCharacterReferenceAE_
1635     ($parent => $parent, $vals => $vals);
1636    
1637     ~ (REFC) {
1638     ?lexmode AttributeValueLiteralE;
1639     } else {
1640     ?lexmode AttributeValueLiteralE;
1641     }
1642     } (ERO) {
1643     &_GeneralEntityReferenceAE_ ($parent => $parent, $vals => $vals);
1644    
1645     ~ (REFC) {
1646     ?lexmode AttributeValueLiteralE;
1647     } else {
1648     ?lexmode AttributeValueLiteralE;
1649     }
1650     }
1651    
1652     // ~ (#EOF) { }
1653     } // AttributeValueLiteralE_
1654    
1655     /*
1656 wakaba 1.1 CDATA Section Content Parsing Mode
1657     */
1658     rule _CDATASection_ ($doc, $parent) {
1659     ?lexmode 'CDATASectionContent';
1660    
1661     my $cdata;
1662    
1663 wakaba 1.2 ~? (CData) {
1664 wakaba 1.1 lang:Perl ($data => $token.value) {
1665     $cdata = $data;
1666     }
1667     } else {
1668     lang:Perl {
1669     $cdata = '';
1670     }
1671     }
1672    
1673     lang:Perl {
1674     my $cdsect = $doc-><M::Document.createCDATASection>
1675     ($cdata);
1676     $parent-><M::Node.appendChild> ($cdsect);
1677     }
1678    
1679     // ~ (MSE) { }
1680     } // _CDATASection_
1681    
1682     rule _NumericCharacterReference_ ($doc, $parent) {
1683     ?lexmode 'NumericCharacterReference';
1684    
1685     ~ (NUMBER) {
1686 wakaba 1.3 lang:Perl ($num => $token.value) : has-error {
1687     $num += 0;
1688     unless (
1689     ($self->{xml_version} eq '1.0' and
1690     ((0x0020 <= $num and $num <= 0xD7FF) or
1691     (0xE000 <= $num and $num <= 0xFFFD) or
1692     (0x10000 <= $num and $num <= 0x10FFFF) or
1693     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1694     ($self->{xml_version} eq '1.1' and
1695     ((0x0001 <= $num and $num <= 0xD7FF) or
1696     (0xE000 <= $num and $num <= 0xFFFD) or
1697     (0x10000 <= $num and $num <= 0x10FFFF)))
1698     ) {
1699     my $location;
1700     __CODE{xp|get-location-from-token::
1701     $token => $token,
1702     $result => $location,
1703     }__;
1704     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1705     DOMCore:location => {$location},
1706     xp|token => {$token},
1707     xp|character-number => {$num},
1708     xp|parent => {$parent},
1709     }__;
1710     unless ($continue) {
1711     __EXCEPTION{DOMLS|PARSE_ERR}__;
1712     }
1713     $self->{has_error} = true;
1714     }
1715     my $ncr = $doc-><M::Document.createTextNode> (chr $num);
1716 wakaba 1.1 $parent-><M::Node.appendChild> ($ncr);
1717     }
1718     }
1719    
1720     // ~ (REFC) { }
1721     } // _NumericCharacterReference_
1722    
1723     rule _NumericCharacterReferenceV_ ($doc, $vals) {
1724     ?lexmode 'NumericCharacterReference';
1725    
1726     ~ (NUMBER) {
1727 wakaba 1.3 lang:Perl ($num => $token.value) : has-error {
1728     $num += 0;
1729     unless (
1730     ($self->{xml_version} eq '1.0' and
1731     ((0x0020 <= $num and $num <= 0xD7FF) or
1732     (0xE000 <= $num and $num <= 0xFFFD) or
1733     (0x10000 <= $num and $num <= 0x10FFFF) or
1734     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1735     ($self->{xml_version} eq '1.1' and
1736     ((0x0001 <= $num and $num <= 0xD7FF) or
1737     (0xE000 <= $num and $num <= 0xFFFD) or
1738     (0x10000 <= $num and $num <= 0x10FFFF)))
1739     ) {
1740     my $location;
1741     __CODE{xp|get-location-from-token::
1742     $token => $token,
1743     $result => $location,
1744     }__;
1745     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1746     DOMCore:location => {$location},
1747     xp|token => {$token},
1748     xp|character-number => {$num},
1749     }__;
1750     unless ($continue) {
1751     __EXCEPTION{DOMLS|PARSE_ERR}__;
1752     }
1753     $self->{has_error} = true;
1754     }
1755 wakaba 1.1 my $ncr = $doc-><M::Document.createTextNode>
1756 wakaba 1.9 (my $char = chr $num);
1757 wakaba 1.1 push @{$vals->{nodes}}, $ncr;
1758     $vals->{value} .= $char;
1759     }
1760     }
1761    
1762     // ~ (REFC) { }
1763     } // _NumericCharacterReferenceV_
1764    
1765 wakaba 1.11 /*
1766     Numeric character reference in the replacement text
1767     of the entity referenced in an attribute value specification
1768     */
1769     rule _NumericCharacterReferenceAE_ ($parent, $vals)
1770     {
1771     ?lexmode NumericCharacterReference;
1772    
1773     ~ (NUMBER) {
1774     lang:Perl ($num => $token.value) : has-error {
1775     $num += 0;
1776     unless (
1777     ($self->{xml_version} eq '1.0' and
1778     ((0x0020 <= $num and $num <= 0xD7FF) or
1779     (0xE000 <= $num and $num <= 0xFFFD) or
1780     (0x10000 <= $num and $num <= 0x10FFFF) or
1781     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1782     ($self->{xml_version} eq '1.1' and
1783     ((0x0001 <= $num and $num <= 0xD7FF) or
1784     (0xE000 <= $num and $num <= 0xFFFD) or
1785     (0x10000 <= $num and $num <= 0x10FFFF)))
1786     ) {
1787     my $location;
1788     __CODE{xp|get-location-from-token::
1789     $token => $token,
1790     $result => $location,
1791     }__;
1792     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1793     DOMCore:location => {$location},
1794     xp|token => {$token},
1795     xp|character-number => {$num},
1796     }__;
1797     unless ($continue) {
1798     __EXCEPTION{DOMLS|PARSE_ERR}__;
1799     }
1800     $self->{has_error} = true;
1801     }
1802     my $ncr = $self->{doc}-><M::Document.createTextNode>
1803     (my $char = chr $num);
1804     $parent-><M::Node.appendChild> ($ncr);
1805     $vals->{value} .= $char;
1806     }
1807     }
1808    
1809     // ~ (REFC) { }
1810     } // _NumericCharacterReferenceAE_
1811    
1812     rule _NumericCharacterReferenceEV_ ($vals)
1813     {
1814     ?lexmode 'NumericCharacterReference';
1815    
1816     ~ (NUMBER) {
1817     lang:Perl ($num => $token.value) : has-error {
1818     $num += 0;
1819     unless (
1820     ($self->{xml_version} eq '1.0' and
1821     ((0x0020 <= $num and $num <= 0xD7FF) or
1822     (0xE000 <= $num and $num <= 0xFFFD) or
1823     (0x10000 <= $num and $num <= 0x10FFFF) or
1824     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1825     ($self->{xml_version} eq '1.1' and
1826     ((0x0001 <= $num and $num <= 0xD7FF) or
1827     (0xE000 <= $num and $num <= 0xFFFD) or
1828     (0x10000 <= $num and $num <= 0x10FFFF)))
1829     ) {
1830     my $location;
1831     __CODE{xp|get-location-from-token::
1832     $token => $token,
1833     $result => $location,
1834     }__;
1835     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1836     DOMCore:location => {$location},
1837     xp|token => {$token},
1838     xp|character-number => {$num},
1839     }__;
1840     unless ($continue) {
1841     __EXCEPTION{DOMLS|PARSE_ERR}__;
1842     }
1843     $self->{has_error} = true;
1844     }
1845     push @{$vals}, chr $num;
1846     }
1847     }
1848    
1849     // ~ (REFC) { }
1850     } // _NumericCharacterReferenceEV_
1851    
1852 wakaba 1.1 rule _HexadecimalCharacterReference_ ($doc, $parent) {
1853     ?lexmode 'HexadecimalCharacterReference';
1854    
1855     ~ (Hex) {
1856 wakaba 1.9 lang:Perl ($v => $token.value) : has-error {
1857     my $num = hex $v;
1858 wakaba 1.3 unless (
1859     ($self->{xml_version} eq '1.0' and
1860     ((0x0020 <= $num and $num <= 0xD7FF) or
1861     (0xE000 <= $num and $num <= 0xFFFD) or
1862     (0x10000 <= $num and $num <= 0x10FFFF) or
1863     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1864     ($self->{xml_version} eq '1.1' and
1865     ((0x0001 <= $num and $num <= 0xD7FF) or
1866     (0xE000 <= $num and $num <= 0xFFFD) or
1867     (0x10000 <= $num and $num <= 0x10FFFF)))
1868     ) {
1869     my $location;
1870     __CODE{xp|get-location-from-token::
1871     $token => $token,
1872     $result => $location,
1873     }__;
1874     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1875     DOMCore:location => {$location},
1876     xp|token => {$token},
1877     xp|character-number => {$num},
1878     xp|parent => {$parent},
1879     }__;
1880     unless ($continue) {
1881     __EXCEPTION{DOMLS|PARSE_ERR}__;
1882     }
1883     $self->{has_error} = true;
1884     }
1885 wakaba 1.1 my $ncr = $doc-><M::Document.createTextNode>
1886 wakaba 1.9 (chr $num);
1887 wakaba 1.1 $parent-><M::Node.appendChild> ($ncr);
1888     }
1889     }
1890    
1891     // ~ (REFC) { }
1892     } // _HexadecimalCharacterReference_
1893    
1894 wakaba 1.3 rule _HexadecimalCharacterReferenceV_ ($doc, $vals) {
1895 wakaba 1.1 ?lexmode 'HexadecimalCharacterReference';
1896    
1897     ~ (Hex) {
1898 wakaba 1.9 lang:Perl ($v => $token.value) : has-error {
1899     my $num = hex $v;
1900 wakaba 1.3 unless (
1901     ($self->{xml_version} eq '1.0' and
1902     ((0x0020 <= $num and $num <= 0xD7FF) or
1903     (0xE000 <= $num and $num <= 0xFFFD) or
1904     (0x10000 <= $num and $num <= 0x10FFFF) or
1905     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1906     ($self->{xml_version} eq '1.1' and
1907     ((0x0001 <= $num and $num <= 0xD7FF) or
1908     (0xE000 <= $num and $num <= 0xFFFD) or
1909     (0x10000 <= $num and $num <= 0x10FFFF)))
1910     ) {
1911     my $location;
1912     __CODE{xp|get-location-from-token::
1913     $token => $token,
1914     $result => $location,
1915     }__;
1916     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1917     DOMCore:location => {$location},
1918     xp|token => {$token},
1919     xp|character-number => {$num},
1920     }__;
1921     unless ($continue) {
1922     __EXCEPTION{DOMLS|PARSE_ERR}__;
1923     }
1924     $self->{has_error} = true;
1925     }
1926 wakaba 1.1 my $ncr = $doc-><M::Document.createTextNode>
1927 wakaba 1.9 (my $char = chr $num);
1928 wakaba 1.1 push @{$vals->{nodes}}, $ncr;
1929     $vals->{value} .= $char;
1930     }
1931     }
1932    
1933     // ~ (REFC) { }
1934 wakaba 1.11 } // _HexadecimalCharacterReferenceV_
1935    
1936     /*
1937     Hexadecimal character reference in the replacement text
1938     of the entity referenced in an attribute value literal
1939     */
1940     rule _HexadecimalCharacterReferenceAE_ ($parent, $vals)
1941     {
1942     ?lexmode HexadecimalCharacterReference;
1943    
1944     ~ (Hex) {
1945     lang:Perl ($v => $token.value) : has-error {
1946     my $num = hex $v;
1947     unless (
1948     ($self->{xml_version} eq '1.0' and
1949     ((0x0020 <= $num and $num <= 0xD7FF) or
1950     (0xE000 <= $num and $num <= 0xFFFD) or
1951     (0x10000 <= $num and $num <= 0x10FFFF) or
1952     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1953     ($self->{xml_version} eq '1.1' and
1954     ((0x0001 <= $num and $num <= 0xD7FF) or
1955     (0xE000 <= $num and $num <= 0xFFFD) or
1956     (0x10000 <= $num and $num <= 0x10FFFF)))
1957     ) {
1958     my $location;
1959     __CODE{xp|get-location-from-token::
1960     $token => $token,
1961     $result => $location,
1962     }__;
1963     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
1964     DOMCore:location => {$location},
1965     xp|token => {$token},
1966     xp|character-number => {$num},
1967     }__;
1968     unless ($continue) {
1969     __EXCEPTION{DOMLS|PARSE_ERR}__;
1970     }
1971     $self->{has_error} = true;
1972     }
1973     my $ncr = $self->{doc}-><M::Document.createTextNode>
1974     (my $char = chr $num);
1975     $parent-><M::Node.appendChild> ($ncr);
1976     $vals->{value} .= $char;
1977     }
1978     }
1979    
1980     // ~ (REFC) { }
1981     } // _HexadecimalCharacterReferenceAE_
1982    
1983     rule _HexadecimalCharacterReferenceEV_ ($vals) {
1984     ?lexmode HexadecimalCharacterReference;
1985    
1986     ~ (Hex) {
1987     lang:Perl ($v => $token.value) : has-error {
1988     my $num = hex $v;
1989     unless (
1990     ($self->{xml_version} eq '1.0' and
1991     ((0x0020 <= $num and $num <= 0xD7FF) or
1992     (0xE000 <= $num and $num <= 0xFFFD) or
1993     (0x10000 <= $num and $num <= 0x10FFFF) or
1994     $num == 0x9 or $num == 0xA or $num == 0xD)) or
1995     ($self->{xml_version} eq '1.1' and
1996     ((0x0001 <= $num and $num <= 0xD7FF) or
1997     (0xE000 <= $num and $num <= 0xFFFD) or
1998     (0x10000 <= $num and $num <= 0x10FFFF)))
1999     ) {
2000     my $location;
2001     __CODE{xp|get-location-from-token::
2002     $token => $token,
2003     $result => $location,
2004     }__;
2005     my $continue = __DOMCore:ERROR{xp|wf-legal-character::
2006     DOMCore:location => {$location},
2007     xp|token => {$token},
2008     xp|character-number => {$num},
2009     }__;
2010     unless ($continue) {
2011     __EXCEPTION{DOMLS|PARSE_ERR}__;
2012     }
2013     $self->{has_error} = true;
2014     }
2015     push @{$vals}, chr $num;
2016     }
2017     }
2018    
2019     // ~ (REFC) { }
2020     } // _HexadecimalCharacterReferenceEV_
2021    
2022     /*
2023     General entity reference in element's content
2024     */
2025     rule _GeneralEntityReferenceEC ($doc, $parent, $ns)
2026     : recursive
2027     {
2028     ?lexmode 'EntityReference';
2029    
2030     ~ (Name == 'lt') {
2031     lang:Perl {
2032     $parent-><M::Node.appendChild>
2033     ($self->{doc}-><M::Document.createTextNode> ('<'));
2034     }
2035     } (Name == 'gt') {
2036     lang:Perl {
2037     $parent-><M::Node.appendChild>
2038     ($self->{doc}-><M::Document.createTextNode> ('>'));
2039     }
2040     } (Name == 'amp') {
2041     lang:Perl {
2042     $parent-><M::Node.appendChild>
2043     ($self->{doc}-><M::Document.createTextNode> ('&'));
2044     }
2045     } (Name == 'quot') {
2046     lang:Perl {
2047     $parent-><M::Node.appendChild>
2048     ($self->{doc}-><M::Document.createTextNode> ('"'));
2049     }
2050     } (Name == 'apos') {
2051     lang:Perl {
2052     $parent-><M::Node.appendChild>
2053     ($self->{doc}-><M::Document.createTextNode> ("'"));
2054     }
2055     } (Name) {
2056     my $er;
2057     lang:Perl ($name => $token.value) {
2058     ## TODO: Namespace well-formedness
2059     ## TODO: Entity declared constraints
2060     $er = $doc-><M::Document.createEntityReference>
2061     ($name);
2062     $parent-><M::Node.appendChild> ($er);
2063     push @{$self->{entity}}, <Code::getCopyOfEntityState::
2064     $entity_type = 'general_entity',
2065     $entity_name = $name>;
2066     push @{$self->{entity_token}}, $self->{token};
2067     $self->{token} = [];
2068     push @{$self->{entity_char}}, $self->{char};
2069     $self->{char} = [];
2070     }
2071    
2072     ?lexmode ElementContent;
2073     &content ($doc => $doc, $parent => $er, $ns => $ns);
2074     ~ (#EOF) { }
2075     lang:Perl {
2076     $self->{token} = pop @{$self->{entity_token}};
2077     $self->{char} = pop @{$self->{entity_char}};
2078     pop @{$self->{entity}};
2079     }
2080    
2081     // TODO: Set read-only flag
2082    
2083     ?lexmode EntityReference;
2084     ?requires-next-token;
2085     }
2086    
2087     ~ (REFC) {
2088     ?lexmode ElementContent;
2089     } else {
2090     ?lexmode ElementContent;
2091     }
2092     } // _GeneralEntityReferenceEC
2093    
2094     /*
2095     General entity reference in an attribute value literal
2096     */
2097     rule _GeneralEntityReferenceV_ ($vals) {
2098     ?lexmode EntityReference;
2099    
2100     ~ (Name == 'lt') {
2101     lang:Perl {
2102     push @{$vals->{nodes}}, $self->{doc}-><M::Document.createTextNode>
2103     ('<');
2104     $vals->{value} .= '<';
2105     }
2106     } (Name == 'gt') {
2107     lang:Perl {
2108     push @{$vals->{nodes}}, $self->{doc}-><M::Document.createTextNode>
2109     ('>');
2110     $vals->{value} .= '>';
2111     }
2112     } (Name == 'amp') {
2113     lang:Perl {
2114     push @{$vals->{nodes}}, $self->{doc}-><M::Document.createTextNode>
2115     ('&');
2116     $vals->{value} .= '&';
2117     }
2118     } (Name == 'quot') {
2119     lang:Perl {
2120     push @{$vals->{nodes}}, $self->{doc}-><M::Document.createTextNode>
2121     ('"');
2122     $vals->{value} .= '"';
2123     }
2124     } (Name == 'apos') {
2125     lang:Perl {
2126     push @{$vals->{nodes}}, $self->{doc}-><M::Document.createTextNode>
2127     ("'");
2128     $vals->{value} .= "'";
2129     }
2130     } (Name) {
2131     my $er;
2132     lang:Perl ($name => $token.value) {
2133     ## TODO: Namespace well-formedness
2134     ## TODO: Entity declared constraints
2135     ## TODO: No external entity constraint
2136     $er = $self->{doc}-><M::Document.createEntityReference> ($name);
2137     push @{$vals->{nodes}}, $er;
2138     push @{$self->{entity}}, <Code::getCopyOfEntityState::
2139     $entity_type = 'general_entity',
2140     $entity_name = $name>;
2141     push @{$self->{entity_token}}, $self->{token};
2142     $self->{token} = [];
2143     push @{$self->{entity_char}}, $self->{char};
2144     $self->{char} = [];
2145     }
2146    
2147     ?lexmode AttributeValueLiteralE;
2148     &AttributeValueLiteralE_ ($parent => $er, $vals => $vals);
2149     ~ (#EOF) { }
2150     lang:Perl {
2151     $self->{token} = pop @{$self->{entity_token}};
2152     $self->{char} = pop @{$self->{entity_char}};
2153     pop @{$self->{entity}};
2154     }
2155    
2156     // TODO: Set read-only flag
2157    
2158     ?lexmode EntityReference;
2159     ?requires-next-token;
2160     }
2161    
2162     // ~ (REFC) { }
2163     } // _GeneralEntityReferenceV_
2164 wakaba 1.1
2165 wakaba 1.6 /*
2166 wakaba 1.11 General entity reference in the replacement text
2167     of the entity referenced in an attribute value literal
2168 wakaba 1.6 */
2169 wakaba 1.11 rule _GeneralEntityReferenceAE_ ($parent, $vals)
2170 wakaba 1.6 {
2171 wakaba 1.11 ?lexmode EntityReference;
2172 wakaba 1.1
2173 wakaba 1.11 ~ (Name == 'lt') {
2174     lang:Perl {
2175     $parent-><M::Node.appendChild>
2176     ($self->{doc}-><M::Document.createTextNode> ('<'));
2177     $vals->{value} .= '<';
2178     }
2179     } (Name == 'gt') {
2180     lang:Perl {
2181     $parent-><M::Node.appendChild>
2182     ($self->{doc}-><M::Document.createTextNode> ('>'));
2183     $vals->{value} .= '>';
2184     }
2185     } (Name == 'amp') {
2186     lang:Perl {
2187     $parent-><M::Node.appendChild>
2188     ($self->{doc}-><M::Document.createTextNode> ('&'));
2189     $vals->{value} .= '&';
2190     }
2191     } (Name == 'quot') {
2192     lang:Perl {
2193     $parent-><M::Node.appendChild>
2194     ($self->{doc}-><M::Document.createTextNode> ('"'));
2195     $vals->{value} .= '"';
2196     }
2197     } (Name == 'apos') {
2198     lang:Perl {
2199     $parent-><M::Node.appendChild>
2200     ($self->{doc}-><M::Document.createTextNode> ("'"));
2201     $vals->{value} .= "'";
2202     }
2203     } (Name) {
2204 wakaba 1.6 my $er;
2205 wakaba 1.1 lang:Perl ($name => $token.value) {
2206     ## TODO: Namespace well-formedness
2207     ## TODO: Entity declared constraints
2208 wakaba 1.11 ## TODO: No external entity constraint
2209     $er = $self->{doc}-><M::Document.createEntityReference> ($name);
2210 wakaba 1.1 $parent-><M::Node.appendChild> ($er);
2211 wakaba 1.6 push @{$self->{entity}}, <Code::getCopyOfEntityState::
2212     $entity_type = 'general_entity',
2213     $entity_name = $name>;
2214     push @{$self->{entity_token}}, $self->{token};
2215     $self->{token} = [];
2216     push @{$self->{entity_char}}, $self->{char};
2217     $self->{char} = [];
2218     }
2219    
2220 wakaba 1.11 ?lexmode AttributeValueLiteralE;
2221     &AttributeValueLiteralE_ ($parent => $er, $vals => $vals);
2222 wakaba 1.6 ~ (#EOF) { }
2223     lang:Perl {
2224     $self->{token} = pop @{$self->{entity_token}};
2225     $self->{char} = pop @{$self->{entity_char}};
2226     pop @{$self->{entity}};
2227     }
2228    
2229 wakaba 1.11 // TODO: Set read-only flag
2230    
2231 wakaba 1.6 ?lexmode EntityReference;
2232     ?requires-next-token;
2233 wakaba 1.1 }
2234    
2235     // ~ (REFC) { }
2236 wakaba 1.11 } // _GeneralEntityReferenceAE_
2237 wakaba 1.6
2238     /*
2239     General entity reference in literal entity value
2240     */
2241 wakaba 1.11 rule _GeneralEntityReferenceEV_ ($vals) {
2242 wakaba 1.6 ?lexmode 'EntityReference';
2243    
2244     ~ (Name) {
2245     lang:Perl ($name => $token.value) {
2246     ## TODO: Namespace well-formedness
2247     ## TODO: Entity declared constraints
2248     push @$vals, $name;
2249     }
2250     }
2251 wakaba 1.11
2252     // No expansion
2253 wakaba 1.6
2254     // ~ (REFC) { }
2255     } // _GeneralEntityReferenceEV_
2256 wakaba 1.1
2257     /*
2258 wakaba 1.4 Document Type Declaration
2259 wakaba 1.1 */
2260 wakaba 1.4 rule _DocumentTypeDeclaration_ ($doc) {
2261     ?lexmode MarkupDeclaration;
2262    
2263     ~ (Name == 'DOCTYPE') { }
2264    
2265     ~ (S) { }
2266    
2267 wakaba 1.6 my $node;
2268 wakaba 1.4 // Document type name
2269 wakaba 1.6 my $name;
2270 wakaba 1.4 ~ (Name) {
2271 wakaba 1.6 lang:Perl ($v => $token.value) {
2272     $name = $v;
2273     }
2274     }
2275     lang:Perl {
2276 wakaba 1.11 $self->{docx} = $self->{doc}
2277     -><M::Node.getFeature> (<Q::fe:XDoctype>, '3.0');
2278     $node = $self->{docx}-><M::DocumentXDoctype.createDocumentTypeDefinition>
2279     ($name);
2280 wakaba 1.4 }
2281    
2282     ~? (S) {
2283     ~? (Name == 'PUBLIC') {
2284     ~ (S) { }
2285    
2286     &PubidLiteral ($doc => $doc);
2287    
2288     ~ (S) { }
2289    
2290     &SystemLiteral ($doc => $doc);
2291    
2292     ~? (S) { }
2293     } (Name == 'SYSTEM') {
2294     ~ (S) { }
2295    
2296     &SystemLiteral ($doc => $doc);
2297    
2298     ~? (S) { }
2299     }
2300     }
2301    
2302 wakaba 1.11 lang:Perl {
2303     $self->{dtdef} = $node;
2304     $doc-><M::Node.appendChild> ($node);
2305     $doc-><AG::Document.domConfig>
2306     -><M::c|DOMConfiguration.setParameter>
2307     ('schema-type' => <Q::xml-dtd:>);
2308     }
2309    
2310 wakaba 1.4 ~? (DSO) {
2311 wakaba 1.6 &InternalSubset ($doc => $doc, $doctype => $node);
2312 wakaba 1.4
2313     ~ (DSC) {
2314     ?lexmode MarkupDeclaration;
2315     } else {
2316     ?lexmode MarkupDeclaration;
2317     }
2318    
2319     ~? (S) { }
2320     }
2321    
2322     // TODO: set $self->{standalone} true if only internal subset
2323     // with no param ref
2324    
2325     // ~ (MDC) { }
2326     } // _DocumentTypeDeclaration_
2327    
2328     rule PubidLiteral ($doc) {
2329     ~ (LIT) {
2330     ?lexmode SystemLiteral;
2331    
2332     ~? (STRING) {
2333     // TODO: Charrange check & normalization is required
2334    
2335     }
2336    
2337     ~ (LIT) {
2338     ?lexmode MarkupDeclaration;
2339     } else {
2340     ?lexmode MarkupDeclaration;
2341     }
2342     } (LITA) {
2343     ?lexmode SystemLiteralA;
2344    
2345     ~? (STRING) {
2346     // TODO: Charrange check & normalization is required
2347    
2348     }
2349    
2350     ~ (LITA) {
2351     ?lexmode MarkupDeclaration;
2352     } else {
2353     ?lexmode MarkupDeclaration;
2354     }
2355     }
2356     } // PubidLiteral
2357    
2358     rule SystemLiteral ($doc) {
2359     ~ (LIT) {
2360     ?lexmode SystemLiteral;
2361     &_SystemLiteral ($doc => $doc);
2362     } (LITA) {
2363     ?lexmode SystemLiteralA;
2364     &_SystemLiteral ($doc => $doc);
2365     }
2366     } // SystemLiteral
2367    
2368     rule _SystemLiteral ($doc) {
2369     ~? (STRING) {
2370    
2371     }
2372    
2373     ~ (LIT) {
2374     ?lexmode MarkupDeclaration;
2375     } (LITA) {
2376     ?lexmode MarkupDeclaration;
2377     } else {
2378     ?lexmode MarkupDeclaration;
2379     }
2380     } // _SystemLiteral
2381    
2382     /*
2383     DTD Internal Subset
2384    
2385     intSubset := *(markupdecl / DeclSep) ;; [28b]
2386     */
2387 wakaba 1.6 rule InternalSubset ($doc, $doctype) {
2388 wakaba 1.4 ?lexmode DTD;
2389    
2390     ~* (MDO) {
2391     ?lexmode MarkupDeclaration;
2392    
2393     ~ (Name == 'ELEMENT') {
2394     &_ElementDeclaration ($doc => $doc);
2395     } (Name == 'ATTLIST') {
2396 wakaba 1.8 &_AttlistDeclaration ($doc => $doc, $doctype => $doctype);
2397 wakaba 1.4 } (Name == 'ENTITY') {
2398     &_EntityDeclaration ($doc => $doc);
2399     } (Name == 'NOTATION') {
2400     &_NotationDeclaration ($doc => $doc);
2401     }
2402     } (S) {
2403     //
2404     } (CDO) {
2405     &_CommentDeclarationDTD ($doc => $doc);
2406     } (PIO) {
2407 wakaba 1.6 &_ProcessingInstructionDTD ($doc => $doc, $doctype => $doctype);
2408 wakaba 1.4 } (PERO) {
2409     ?lexmode EntityReference;
2410    
2411     ~ (Name) {
2412    
2413     }
2414    
2415     ~ (REFC) {
2416     ?lexmode DTD;
2417     } else {
2418     ?lexmode DTD;
2419     }
2420     }
2421     } // InternalSubset
2422    
2423     rule _ElementDeclaration ($doc) {
2424     // ~ (MDO) { }
2425     // ?lexmode MarkupDeclaration
2426     // ~ (Name == 'Element') { }
2427    
2428     ~ (S) { }
2429    
2430     ~ (Name) {
2431    
2432     }
2433    
2434     ?lexmode ElementDeclaration;
2435    
2436     ~ (S) { }
2437    
2438     // contentspec
2439     ~ (MGO) {
2440     &_ContentModel ($doc => $doc);
2441     } (Name == 'EMPTY') {
2442    
2443     } (Name == 'ANY') {
2444    
2445     }
2446    
2447     ~? (S) { }
2448    
2449     ~ (MDC) {
2450     ?lexmode DTD;
2451     } else {
2452     ?lexmode DTD;
2453     }
2454     } // _ElementDeclaration
2455    
2456     rule _ContentModel ($doc) {
2457     // ~ (MGO) { }
2458    
2459     ~? (S) { }
2460    
2461     ~ (Name) {
2462     // Element content model
2463     &_ModelGroup ($doc => $doc)
2464     : unshift-current-token;
2465    
2466     ~? (OPT) {
2467    
2468     } (REP) {
2469    
2470     } (PLUS) {
2471    
2472     }
2473    
2474     } (MDO) {
2475     &_ModelGroup ($doc => $doc)
2476     : unshift-current-token;
2477    
2478     ~? (OPT) {
2479    
2480     } (REP) {
2481    
2482     } (PLUS) {
2483    
2484     }
2485    
2486     } (PCDATA) {
2487     // Mixed content declaration
2488     ~? (S) { }
2489    
2490     ~* (OR) {
2491     ~? (S) { }
2492    
2493     ~ (Name) {
2494    
2495     }
2496    
2497     ~? (S) { }
2498     }
2499    
2500     ~ (MGC) { }
2501    
2502     ~? (REP) {
2503    
2504     } else {
2505     // TODO: error if |Name|
2506     }
2507    
2508    
2509     }
2510     } // _ContentModel
2511    
2512     rule _ModelGroup ($doc)
2513     : standalone
2514     : recursive
2515     {
2516     // ~ (MGO) { }
2517     // ~? (S) { }
2518    
2519     &ContentParticle ($doc => $doc);
2520    
2521     ~? (S) { }
2522    
2523     ~? (OR) {
2524     ~? (S) { }
2525    
2526     &ContentParticle ($doc => $doc);
2527    
2528     ~? (S) { }
2529    
2530     ~* (OR) {
2531     ~? (S) { }
2532    
2533     &ContentParticle ($doc => $doc);
2534    
2535     ~? (S) { }
2536     }
2537    
2538     } (SEQ) {
2539     ~? (S) { }
2540    
2541     &ContentParticle ($doc => $doc);
2542    
2543     ~? (S) { }
2544    
2545     ~* (SEQ) {
2546     ~? (S) { }
2547    
2548     &ContentParticle ($doc => $doc);
2549    
2550     ~? (S) { }
2551     }
2552    
2553     }
2554    
2555     ~ (MGC) { }
2556     } // _ModelGroup
2557    
2558     rule ContentParticle ($doc) {
2559     ~ (Name) {
2560    
2561     } (MGO) {
2562     ~? (S) { }
2563    
2564     &_ModelGroup ($doc => $doc);
2565     }
2566    
2567     ~? (OPT) {
2568    
2569     } (REP) {
2570    
2571     } (PLUS) {
2572    
2573     }
2574     } // ContentParticle
2575    
2576 wakaba 1.8 /*
2577     Attribute list declaration
2578     */
2579     rule _AttlistDeclaration ($doc, $doctype) {
2580 wakaba 1.4 // ~ (MDO) { }
2581     // ~ (Name == 'ATTLIST') { }
2582    
2583     ?lexmode AttlistDeclaration;
2584    
2585     ~ (S) { }
2586    
2587 wakaba 1.8 my $name;
2588 wakaba 1.4 ~ (Name) {
2589 wakaba 1.8 lang:Perl ($v => $token.value) {
2590     $name = $v;
2591     }
2592     } else {
2593     lang:Perl { $name = '#ILLEGAL' }
2594     }
2595 wakaba 1.4
2596 wakaba 1.8 my $docxd;
2597     my $et;
2598     lang:Perl {
2599     $et = $doctype-><M::DTDef.getElementTypeDefinitionNode> ($name);
2600     unless ($et) {
2601 wakaba 1.11 $docxd = $doc-><M::Node.getFeature> (<Q::fe:XDoctype>, '3.0');
2602 wakaba 1.8 $et = $docxd-><M::DocumentXDoctype.createElementTypeDefinition>
2603     ($name);
2604     $doctype-><M::DTDef.setElementTypeDefinitionNode> ($et)
2605     unless $name eq '#ILLEGAL';
2606     }
2607 wakaba 1.4 }
2608    
2609     ~? (S) { }
2610    
2611     ~* (Name) {
2612 wakaba 1.8 my $at;
2613     lang:Perl ($v => $token.value) {
2614     $docxd ||= $doc-><M::Node.getFeature>
2615 wakaba 1.11 (<Q::fe:XDoctype>, '3.0');
2616 wakaba 1.8 $at = $docxd-><M::DocumentXDoctype.createAttributeDefinition> ($v);
2617 wakaba 1.9 unless (exists $et-><AG::ETDef.attributeDefinitions>->{$v}) {
2618     $et-><M::ETDef.setAttributeDefinitionNode> ($at);
2619     $self->{attr}->{$name}->{$v} = $at;
2620     }
2621 wakaba 1.8 }
2622 wakaba 1.4
2623     ~ (S) { }
2624    
2625     // AttType
2626     ~ (Name == 'NOTATION') {
2627     ~ (S) { }
2628    
2629 wakaba 1.8 my $kwd;
2630     lang:Perl {
2631     $at-><AS::ATDef.declaredType> (<C::ATDef.NOTATION_ATTR>);
2632     $kwd = $at-><AG::ATDef.allowedTokens>;
2633     }
2634    
2635 wakaba 1.4 ~ (EGO) {
2636     ~? (S) { }
2637    
2638 wakaba 1.8 ~+ (Name) {
2639     lang:Perl ($v => $token.value) {
2640     push @$kwd, $v;
2641     }
2642 wakaba 1.4
2643     ~? (S) { }
2644     } (OR) : separator {
2645     ~? (S) { }
2646     }
2647    
2648     ~ (EGC) { }
2649     }
2650 wakaba 1.8
2651 wakaba 1.4 } (Name) {
2652 wakaba 1.8 my $type;
2653     lang:Perl ($v => $token.value) : has-error {
2654     my $map = {
2655     CDATA => <C::ATDef.CDATA_ATTR>,
2656     ID => <C::ATDef.ID_ATTR>,
2657     IDREF => <C::ATDef.IDREF_ATTR>,
2658     IDREFS => <C::ATDef.IDREFS_ATTR>,
2659     ENTITY => <C::ATDef.ENTITY_ATTR>,
2660     ENTITIES => <C::ATDef.ENTITIES_ATTR>,
2661     NMTOKEN => <C::ATDef.NMTOKEN_ATTR>,
2662     NMTOKENS => <C::ATDef.NMTOKENS_ATTR>,
2663     };
2664     if ($map->{$v}) {
2665     $at-><AS::ATDef.declaredType> ($map->{$v});
2666     } else {
2667     ## TODO: Exception
2668     }
2669     }
2670 wakaba 1.4
2671     } (EGO) {
2672     ?lexmode Enumeration;
2673    
2674     ~? (S) { }
2675    
2676 wakaba 1.8 my $kwd;
2677     lang:Perl {
2678     $at-><AS::ATDef.declaredType> (<C::ATDef.ENUMERATION_ATTR>);
2679     $kwd = $at-><AG::ATDef.allowedTokens>;
2680     }
2681    
2682     ~+ (Nmtoken) {
2683     lang:Perl ($v => $token.value) {
2684     push @$kwd, $v;
2685     }
2686 wakaba 1.4
2687     ~? (S) { }
2688     } (OR) : separator {
2689     ~? (S) { }
2690     }
2691    
2692     ~ (EGC) {
2693     ?lexmode AttlistDeclaration;
2694     } else {
2695     ?lexmode AttlistDeclaration;
2696     }
2697    
2698     }
2699    
2700     ~ (S) { }
2701    
2702     // DefaultDecl
2703     ~ (RNI) {
2704     ~ (Name == 'REQUIRED') {
2705 wakaba 1.8 lang:Perl {
2706     $at-><AS::ATDef.defaultType> (<C::ATDef.REQUIRED_DEFAULT>);
2707     }
2708 wakaba 1.4 } (Name == 'IMPLIED') {
2709 wakaba 1.8 lang:Perl {
2710     $at-><AS::ATDef.defaultType> (<C::ATDef.IMPLIED_DEFAULT>);
2711     }
2712 wakaba 1.4 } (Name == 'FIXED') {
2713     ~ (S) { }
2714 wakaba 1.8
2715     lang:Perl {
2716     $at-><AS::ATDef.defaultType> (<C::ATDef.FIXED_DEFAULT>);
2717     }
2718 wakaba 1.4
2719     ~ (LIT) {
2720     my $vals;
2721     lang:Perl {
2722 wakaba 1.8 $vals = {nodes => [], value => ''};
2723 wakaba 1.4 }
2724    
2725     &_AttributeValueSpecification_ ($doc => $doc, $vals => $vals);
2726    
2727 wakaba 1.8 lang:Perl {
2728     for (@{$vals->{nodes}}) {
2729     $at-><M::Node.appendChild> ($_);
2730     }
2731     }
2732    
2733 wakaba 1.4 ~ (LIT) {
2734     ?lexmode AttlistDeclaration;
2735     } else {
2736     ?lexmode AttlistDeclaration;
2737     }
2738     } (LITA) {
2739     my $vals;
2740     lang:Perl {
2741 wakaba 1.8 $vals = {nodes => [], value => ''};
2742 wakaba 1.4 }
2743    
2744     &_AttributeValueSpecificationA_ ($doc => $doc, $vals => $vals);
2745    
2746 wakaba 1.8 lang:Perl {
2747     for (@{$vals->{nodes}}) {
2748     $at-><M::Node.appendChild> ($_);
2749     }
2750     }
2751    
2752     ~ (LITA) {
2753 wakaba 1.4 ?lexmode AttlistDeclaration;
2754     } else {
2755     ?lexmode AttlistDeclaration;
2756     }
2757     }
2758     }
2759    
2760     } (LIT) {
2761     my $vals;
2762     lang:Perl {
2763 wakaba 1.8 $at-><AS::ATDef.defaultType> (<C::ATDef.EXPLICIT_DEFAULT>);
2764     $vals = {nodes => [], value => ''};
2765 wakaba 1.4 }
2766    
2767     &_AttributeValueSpecification_ ($doc => $doc, $vals => $vals);
2768    
2769 wakaba 1.8 lang:Perl {
2770     for (@{$vals->{nodes}}) {
2771     $at-><M::Node.appendChild> ($_);
2772     }
2773     }
2774    
2775 wakaba 1.4 ~ (LIT) {
2776     ?lexmode AttlistDeclaration;
2777     } else {
2778     ?lexmode AttlistDeclaration;
2779     }
2780     } (LITA) {
2781     my $vals;
2782     lang:Perl {
2783 wakaba 1.8 $at-><AS::ATDef.defaultType> (<C::ATDef.EXPLICIT_DEFAULT>);
2784     $vals = {nodes => [], value => ''};
2785 wakaba 1.4 }
2786    
2787     &_AttributeValueSpecificationA_ ($doc => $doc, $vals => $vals);
2788    
2789 wakaba 1.8 lang:Perl {
2790     for (@{$vals->{nodes}}) {
2791     $at-><M::Node.appendChild> ($_);
2792     }
2793     }
2794    
2795 wakaba 1.4 ~ (LITA) {
2796     ?lexmode AttlistDeclaration;
2797     } else {
2798     ?lexmode AttlistDeclaration;
2799     }
2800     }
2801    
2802     } (S) : separator : terminator? {
2803     //
2804     }
2805    
2806     ~ (MDC) {
2807     ?lexmode DTD;
2808     } else {
2809     ?lexmode DTD;
2810     }
2811     } // _AttlistDeclaration
2812    
2813 wakaba 1.11 /*
2814     Entity declaration
2815     */
2816 wakaba 1.4 rule _EntityDeclaration ($doc) {
2817     // ~ (MDO) { }
2818     // ~ (Name == ENTITY) { }
2819    
2820     ~ (S) { }
2821    
2822 wakaba 1.6 my $decl;
2823 wakaba 1.11 lang:Perl { $decl = { name => '#ILLEGAL' }; }
2824 wakaba 1.6
2825 wakaba 1.4 ~? (PERO) {
2826     ~ (S) { }
2827 wakaba 1.6 lang:Perl {
2828     $decl->{is_param_entity} = true;
2829     }
2830 wakaba 1.4 }
2831    
2832     ~ (Name) {
2833 wakaba 1.6 lang:Perl ($v => $token.value) {
2834     $decl->{name} = $v;
2835     }
2836 wakaba 1.4 }
2837    
2838 wakaba 1.11 lang:Perl {
2839     $decl->{node} = $self->{docx}-><M::DocumentXDoctype.createGeneralEntity>
2840     ($decl->{name});
2841     ## TODO: Parameter entity...
2842     }
2843    
2844 wakaba 1.4 ~ (S) { }
2845    
2846     ~ (LIT) {
2847 wakaba 1.6 &_EntityValue ($doc => $doc, $decl => $decl);
2848 wakaba 1.4 } (LITA) {
2849 wakaba 1.6 &_EntityValueA ($doc => $doc, $decl => $decl);
2850 wakaba 1.4 } (Name == 'PUBLIC') {
2851     ~ (S) { }
2852    
2853 wakaba 1.6 &PubidLiteral ($doc => $doc, $decl => $decl);
2854 wakaba 1.4
2855     ~ (S) { }
2856    
2857 wakaba 1.6 &SystemLiteral ($doc => $doc, $decl => $decl);
2858 wakaba 1.4 } (Name == 'SYSTEM') {
2859     ~ (S) { }
2860    
2861 wakaba 1.6 &SystemLiteral ($doc => $doc, $decl => $decl);
2862 wakaba 1.4 }
2863    
2864     ~? (S) {
2865     ~? (Name == 'NDATA') {
2866     // TODO: error if parameter entity
2867    
2868     ~ (S) { }
2869    
2870     ~ (Name) {
2871 wakaba 1.6 lang:Perl ($v => $token.value) {
2872     $decl->{notation} = $v;
2873 wakaba 1.11 $decl->{node}-><AG::x|Entity.notationName> ($v);
2874 wakaba 1.6 }
2875 wakaba 1.4 }
2876    
2877     ~? (S) { }
2878     }
2879     }
2880    
2881 wakaba 1.6 lang:Perl {
2882     if ($self->{$decl->{is_param_entity} ? 'param_entity' : 'general_entity'}
2883     ->{$decl->{name}}) {
2884 wakaba 1.11 ## TODO: warning
2885     ## TODO: predefined entity error check
2886 wakaba 1.6 } else {
2887     $self->{$decl->{is_param_entity} ? 'param_entity' : 'general_entity'}
2888     ->{$decl->{name}} = $decl;
2889 wakaba 1.11 $self->{dtdef}-><M::DTDef.setGeneralEntityNode> ($decl->{node})
2890     unless $decl->{is_param_entity};
2891 wakaba 1.6 }
2892     }
2893    
2894 wakaba 1.4 ~ (MDC) {
2895     ?lexmode DTD;
2896     } else {
2897     ?lexmode DTD;
2898     }
2899     } // _EntityDeclaration
2900    
2901     rule _NotationDeclaration ($doc) {
2902     // ~ (MDO) { }
2903     // ~ (Name == NOTATION) { }
2904    
2905     ~ (S) { }
2906    
2907     ~ (Name) {
2908    
2909     }
2910    
2911     ~ (S) { }
2912    
2913     ~ (Name == 'PUBLIC') {
2914     ~ (S) { }
2915    
2916     &PubidLiteral ($doc => $doc);
2917    
2918     ~? (S) {
2919     ~? (LIT) {
2920     ?lexmode SystemLiteral;
2921     &_SystemLiteral ($doc => $doc);
2922    
2923     ~? (S) { }
2924     } (LITA) {
2925     ?lexmode SystemLiteralA;
2926     &_SystemLiteral ($doc => $doc);
2927    
2928     ~? (S) { }
2929     }
2930     }
2931     } (Name == 'SYSTEM') {
2932     ~ (S) { }
2933    
2934     &SystemLiteral ($doc => $doc);
2935    
2936     ~? (S) { }
2937     }
2938    
2939     ~ (MDC) {
2940     ?lexmode DTD;
2941     } else {
2942     ?lexmode DTD;
2943     }
2944     } // _NotationDeclaration
2945    
2946 wakaba 1.11 rule _EntityValue ($decl) {
2947 wakaba 1.4 ?lexmode EntityValue;
2948    
2949     my $vals;
2950 wakaba 1.6 my $reptxt;
2951 wakaba 1.4 lang:Perl {
2952     $vals = [];
2953 wakaba 1.6 $reptxt = '';
2954 wakaba 1.4 }
2955    
2956     ~* (STRING) {
2957 wakaba 1.6 lang:Perl ($v => $token.value) {
2958     $reptxt .= $v;
2959     }
2960 wakaba 1.4 } (PERO) {
2961     ?lexmode EntityDeclaration;
2962 wakaba 1.6
2963     // TODO: Expand or wferror if internal subset
2964 wakaba 1.4
2965     ~ (Name) {
2966    
2967     }
2968    
2969     ~ (REFC) {
2970     ?lexmode EntityValue;
2971     } else {
2972     ?lexmode EntityValue;
2973     }
2974     } (HCRO) {
2975 wakaba 1.11 &_HexadecimalCharacterReferenceEV_ ($vals => $vals);
2976 wakaba 1.4
2977 wakaba 1.6 lang:Perl {
2978 wakaba 1.11 $reptxt .= $vals->[-1];
2979 wakaba 1.6 }
2980    
2981 wakaba 1.4 ~ (REFC) {
2982     ?lexmode EntityValue;
2983     } else {
2984     ?lexmode EntityValue;
2985     }
2986     } (CRO) {
2987 wakaba 1.11 &_NumericCharacterReferenceEV_ ($vals => $vals);
2988 wakaba 1.6
2989     lang:Perl {
2990 wakaba 1.11 $reptxt .= $vals->[-1];
2991 wakaba 1.6 }
2992 wakaba 1.4
2993     ~ (REFC) {
2994     ?lexmode EntityValue;
2995     } else {
2996     ?lexmode EntityValue;
2997     }
2998     } (ERO) {
2999 wakaba 1.11 &_GeneralEntityReferenceEV_ ($vals => $vals);
3000 wakaba 1.4
3001 wakaba 1.6 lang:Perl {
3002 wakaba 1.11 $reptxt .= '&' . $vals->[-1] . ';';
3003 wakaba 1.6 }
3004    
3005 wakaba 1.4 ~ (REFC) {
3006     ?lexmode EntityValue;
3007     } else {
3008     ?lexmode EntityValue;
3009     }
3010     }
3011    
3012     ~ (LIT) {
3013     ?lexmode MarkupDeclaration;
3014     } (LITA) {
3015     ?lexmode MarkupDeclaration;
3016     } else {
3017     ?lexmode MarkupDeclaration;
3018     }
3019 wakaba 1.6
3020     lang:Perl {
3021     $decl->{reptxt} = \$reptxt;
3022     }
3023 wakaba 1.4 } // _EntityValue
3024    
3025 wakaba 1.11 rule _EntityValueA ($decl) {
3026 wakaba 1.4 ?lexmode EntityValueA;
3027    
3028     my $vals;
3029 wakaba 1.6 my $reptxt;
3030 wakaba 1.4 lang:Perl {
3031     $vals = [];
3032 wakaba 1.6 $reptxt = '';
3033 wakaba 1.4 }
3034    
3035     ~* (STRING) {
3036 wakaba 1.6 lang:Perl ($v => $token.value) {
3037     $reptxt .= $v;
3038     }
3039 wakaba 1.4 } (PERO) {
3040     ?lexmode EntityDeclaration;
3041    
3042 wakaba 1.6 // TODO: implement this
3043 wakaba 1.4 ~ (Name) {
3044    
3045     }
3046    
3047     ~ (REFC) {
3048     ?lexmode EntityValueA;
3049     } else {
3050     ?lexmode EntityValueA;
3051     }
3052     } (HCRO) {
3053 wakaba 1.11 &_HexadecimalCharacterReferenceEV_ ($vals => $vals);
3054 wakaba 1.4
3055 wakaba 1.6 lang:Perl {
3056 wakaba 1.11 $reptxt .= $vals->[-1];
3057 wakaba 1.6 }
3058    
3059    
3060 wakaba 1.4 ~ (REFC) {
3061     ?lexmode EntityValueA;
3062     } else {
3063     ?lexmode EntityValueA;
3064     }
3065     } (CRO) {
3066 wakaba 1.11 &_NumericCharacterReferenceEV_ ($vals => $vals);
3067 wakaba 1.4
3068 wakaba 1.6 lang:Perl {
3069 wakaba 1.11 $reptxt .= $vals->[-1];
3070 wakaba 1.6 }
3071    
3072 wakaba 1.4 ~ (REFC) {
3073     ?lexmode EntityValueA;
3074     } else {
3075     ?lexmode EntityValueA;
3076     }
3077     } (ERO) {
3078 wakaba 1.11 &_GeneralEntityReferenceEV_ ($vals => $vals);
3079 wakaba 1.4
3080 wakaba 1.6 lang:Perl {
3081 wakaba 1.11 $reptxt .= '&' . $vals->[-1] . ';';
3082 wakaba 1.6 }
3083    
3084 wakaba 1.4 ~ (REFC) {
3085     ?lexmode EntityValueA;
3086     } else {
3087     ?lexmode EntityValueA;
3088     }
3089     }
3090    
3091     ~ (LITA) {
3092     ?lexmode MarkupDeclaration;
3093     } else {
3094     ?lexmode MarkupDeclaration;
3095     }
3096 wakaba 1.6
3097     lang:Perl {
3098     $decl->{reptxt} = \$reptxt;
3099     }
3100 wakaba 1.4 } // _EntityValueA
3101    
3102    
3103     /*
3104     XML Name
3105     */
3106     lexmode NameChar {
3107     $NameStartChar10 := [
3108     '_' ':'
3109     // Letter
3110     // BaseChar
3111     U+0041..U+005A U+0061..U+007A U+00C0..U+00D6
3112     U+00D8..U+00F6 U+00F8..U+00FF U+0100..U+0131
3113     U+0134..U+013E U+0141..U+0148 U+014A..U+017E
3114     U+0180..U+01C3 U+01CD..U+01F0 U+01F4..U+01F5
3115     U+01FA..U+0217 U+0250..U+02A8 U+02BB..U+02C1
3116     U+0386 U+0388..U+038A U+038C U+038E..U+03A1
3117     U+03A3..U+03CE U+03D0..U+03D6 U+03DA U+03DC
3118     U+03DE U+03E0 U+03E2..U+03F3 U+0401..U+040C
3119     U+040E..U+044F U+0451..U+045C U+045E..U+0481
3120     U+0490..U+04C4 U+04C7..U+04C8 U+04CB..U+04CC
3121     U+04D0..U+04EB U+04EE..U+04F5 U+04F8..U+04F9
3122     U+0531..U+0556 U+0559 U+0561..U+0586
3123     U+05D0..U+05EA U+05F0..U+05F2 U+0621..U+063A
3124     U+0641..U+064A U+0671..U+06B7 U+06BA..U+06BE
3125     U+06C0..U+06CE U+06D0..U+06D3 U+06D5
3126     U+06E5..U+06E6 U+0905..U+0939 U+093D
3127     U+0958..U+0961 U+0985..U+098C U+098F..U+0990
3128     U+0993..U+09A8 U+09AA..U+09B0 U+09B2
3129     U+09B6..U+09B9 U+09DC..U+09DD U+09DF..U+09E1
3130     U+09F0..U+09F1 U+0A05..U+0A0A U+0A0F..U+0A10
3131     U+0A13..U+0A28 U+0A2A..U+0A30 U+0A32..U+0A33
3132     U+0A35..U+0A36 U+0A38..U+0A39 U+0A59..U+0A5C
3133     U+0A5E U+0A72..U+0A74 U+0A85..U+0A8B U+0A8D
3134     U+0A8F..U+0A91 U+0A93..U+0AA8 U+0AAA..U+0AB0
3135     U+0AB2..U+0AB3 U+0AB5..U+0AB9 U+0ABD U+0AE0
3136     U+0B05..U+0B0C U+0B0F..U+0B10 U+0B13..U+0B28
3137     U+0B2A..U+0B30 U+0B32..U+0B33 U+0B36..U+0B39
3138     U+0B3D U+0B5C..U+0B5D U+0B5F..U+0B61
3139     U+0B85..U+0B8A U+0B8E..U+0B90 U+0B92..U+0B95
3140     U+0B99..U+0B9A U+0B9C U+0B9E..U+0B9F
3141     U+0BA3..U+0BA4 U+0BA8..U+0BAA U+0BAE..U+0BB5
3142     U+0BB7..U+0BB9 U+0C05..U+0C0C U+0C0E..U+0C10
3143     U+0C12..U+0C28 U+0C2A..U+0C33 U+0C35..U+0C39
3144     U+0C60..U+0C61 U+0C85..U+0C8C U+0C8E..U+0C90
3145     U+0C92..U+0CA8 U+0CAA..U+0CB3 U+0CB5..U+0CB9
3146     U+0CDE U+0CE0..U+0CE1 U+0D05..U+0D0C
3147     U+0D0E..U+0D10 U+0D12..U+0D28 U+0D2A..U+0D39
3148     U+0D60..U+0D61 U+0E01..U+0E2E U+0E30
3149     U+0E32..U+0E33 U+0E40..U+0E45 U+0E81..U+0E82
3150     U+0E84 U+0E87..U+0E88 U+0E8A U+0E8D
3151     U+0E94..U+0E97 U+0E99..U+0E9F U+0EA1..U+0EA3
3152     U+0EA5 U+0EA7 U+0EAA..U+0EAB U+0EAD..U+0EAE
3153     U+0EB0 U+0EB2..U+0EB3 U+0EBD U+0EC0..U+0EC4
3154     U+0F40..U+0F47 U+0F49..U+0F69 U+10A0..U+10C5
3155     U+10D0..U+10F6 U+1100 U+1102..U+1103
3156     U+1105..U+1107 U+1109 U+110B..U+110C
3157     U+110E..U+1112 U+113C U+113E U+1140 U+114C
3158     U+114E U+1150 U+1154..U+1155 U+1159
3159     U+115F..U+1161 U+1163 U+1165 U+1167 U+1169
3160     U+116D..U+116E U+1172..U+1173 U+1175 U+119E
3161     U+11A8 U+11AB U+11AE..U+11AF U+11B7..U+11B8
3162     U+11BA U+11BC..U+11C2 U+11EB U+11F0 U+11F9
3163     U+1E00..U+1E9B U+1EA0..U+1EF9 U+1F00..U+1F15
3164     U+1F18..U+1F1D U+1F20..U+1F45 U+1F48..U+1F4D
3165     U+1F50..U+1F57 U+1F59 U+1F5B U+1F5D
3166     U+1F5F..U+1F7D U+1F80..U+1FB4 U+1FB6..U+1FBC
3167     U+1FBE U+1FC2..U+1FC4 U+1FC6..U+1FCC
3168     U+1FD0..U+1FD3 U+1FD6..U+1FDB U+1FE0..U+1FEC
3169     U+1FF2..U+1FF4 U+1FF6..U+1FFC U+2126
3170     U+212A..U+212B U+212E U+2180..U+2182
3171     U+3041..U+3094 U+30A1..U+30FA U+3105..U+312C
3172     U+AC00..U+D7A3
3173     // Ideographic
3174     U+4E00..U+9FA5 U+3007 U+3021..U+3029
3175     ];
3176     $NameChar10 := [
3177     '.' '-' '_' ':'
3178     // Letter
3179     // BaseChar
3180     U+0041..U+005A U+0061..U+007A U+00C0..U+00D6
3181     U+00D8..U+00F6 U+00F8..U+00FF U+0100..U+0131
3182     U+0134..U+013E U+0141..U+0148 U+014A..U+017E
3183     U+0180..U+01C3 U+01CD..U+01F0 U+01F4..U+01F5
3184     U+01FA..U+0217 U+0250..U+02A8 U+02BB..U+02C1
3185     U+0386 U+0388..U+038A U+038C U+038E..U+03A1
3186     U+03A3..U+03CE U+03D0..U+03D6 U+03DA U+03DC
3187     U+03DE U+03E0 U+03E2..U+03F3 U+0401..U+040C
3188     U+040E..U+044F U+0451..U+045C U+045E..U+0481
3189     U+0490..U+04C4 U+04C7..U+04C8 U+04CB..U+04CC
3190     U+04D0..U+04EB U+04EE..U+04F5 U+04F8..U+04F9
3191     U+0531..U+0556 U+0559 U+0561..U+0586
3192     U+05D0..U+05EA U+05F0..U+05F2 U+0621..U+063A
3193     U+0641..U+064A U+0671..U+06B7 U+06BA..U+06BE
3194     U+06C0..U+06CE U+06D0..U+06D3 U+06D5
3195     U+06E5..U+06E6 U+0905..U+0939 U+093D
3196     U+0958..U+0961 U+0985..U+098C U+098F..U+0990
3197     U+0993..U+09A8 U+09AA..U+09B0 U+09B2
3198     U+09B6..U+09B9 U+09DC..U+09DD U+09DF..U+09E1
3199     U+09F0..U+09F1 U+0A05..U+0A0A U+0A0F..U+0A10
3200     U+0A13..U+0A28 U+0A2A..U+0A30 U+0A32..U+0A33
3201     U+0A35..U+0A36 U+0A38..U+0A39 U+0A59..U+0A5C
3202     U+0A5E U+0A72..U+0A74 U+0A85..U+0A8B U+0A8D
3203     U+0A8F..U+0A91 U+0A93..U+0AA8 U+0AAA..U+0AB0
3204     U+0AB2..U+0AB3 U+0AB5..U+0AB9 U+0ABD U+0AE0
3205     U+0B05..U+0B0C U+0B0F..U+0B10 U+0B13..U+0B28
3206     U+0B2A..U+0B30 U+0B32..U+0B33 U+0B36..U+0B39
3207     U+0B3D U+0B5C..U+0B5D U+0B5F..U+0B61
3208     U+0B85..U+0B8A U+0B8E..U+0B90 U+0B92..U+0B95
3209     U+0B99..U+0B9A U+0B9C U+0B9E..U+0B9F
3210     U+0BA3..U+0BA4 U+0BA8..U+0BAA U+0BAE..U+0BB5
3211     U+0BB7..U+0BB9 U+0C05..U+0C0C U+0C0E..U+0C10
3212     U+0C12..U+0C28 U+0C2A..U+0C33 U+0C35..U+0C39
3213     U+0C60..U+0C61 U+0C85..U+0C8C U+0C8E..U+0C90
3214     U+0C92..U+0CA8 U+0CAA..U+0CB3 U+0CB5..U+0CB9
3215     U+0CDE U+0CE0..U+0CE1 U+0D05..U+0D0C
3216     U+0D0E..U+0D10 U+0D12..U+0D28 U+0D2A..U+0D39
3217     U+0D60..U+0D61 U+0E01..U+0E2E U+0E30
3218     U+0E32..U+0E33 U+0E40..U+0E45 U+0E81..U+0E82
3219     U+0E84 U+0E87..U+0E88 U+0E8A U+0E8D
3220     U+0E94..U+0E97 U+0E99..U+0E9F U+0EA1..U+0EA3
3221     U+0EA5 U+0EA7 U+0EAA..U+0EAB U+0EAD..U+0EAE
3222     U+0EB0 U+0EB2..U+0EB3 U+0EBD U+0EC0..U+0EC4
3223     U+0F40..U+0F47 U+0F49..U+0F69 U+10A0..U+10C5
3224     U+10D0..U+10F6 U+1100 U+1102..U+1103
3225     U+1105..U+1107 U+1109 U+110B..U+110C
3226     U+110E..U+1112 U+113C U+113E U+1140 U+114C
3227     U+114E U+1150 U+1154..U+1155 U+1159
3228     U+115F..U+1161 U+1163 U+1165 U+1167 U+1169
3229     U+116D..U+116E U+1172..U+1173 U+1175 U+119E
3230     U+11A8 U+11AB U+11AE..U+11AF U+11B7..U+11B8
3231     U+11BA U+11BC..U+11C2 U+11EB U+11F0 U+11F9
3232     U+1E00..U+1E9B U+1EA0..U+1EF9 U+1F00..U+1F15
3233     U+1F18..U+1F1D U+1F20..U+1F45 U+1F48..U+1F4D
3234     U+1F50..U+1F57 U+1F59 U+1F5B U+1F5D
3235     U+1F5F..U+1F7D U+1F80..U+1FB4 U+1FB6..U+1FBC
3236     U+1FBE U+1FC2..U+1FC4 U+1FC6..U+1FCC
3237     U+1FD0..U+1FD3 U+1FD6..U+1FDB U+1FE0..U+1FEC
3238     U+1FF2..U+1FF4 U+1FF6..U+1FFC U+2126
3239     U+212A..U+212B U+212E U+2180..U+2182
3240     U+3041..U+3094 U+30A1..U+30FA U+3105..U+312C
3241     U+AC00..U+D7A3
3242     // Ideographic
3243     U+4E00..U+9FA5 U+3007 U+3021..U+3029
3244     // Digit
3245     U+0030..U+0039 U+0660..U+0669 U+06F0..U+06F9
3246     U+0966..U+096F U+09E6..U+09EF U+0A66..U+0A6F
3247     U+0AE6..U+0AEF U+0B66..U+0B6F U+0BE7..U+0BEF
3248     U+0C66..U+0C6F U+0CE6..U+0CEF U+0D66..U+0D6F
3249     U+0E50..U+0E59 U+0ED0..U+0ED9 U+0F20..U+0F29
3250     // CombiningChar
3251     U+0300..U+0345 U+0360..U+0361 U+0483..U+0486
3252     U+0591..U+05A1 U+05A3..U+05B9 U+05BB..U+05BD
3253     U+05BF U+05C1..U+05C2 U+05C4 U+064B..U+0652
3254     U+0670 U+06D6..U+06DC U+06DD..U+06DF
3255     U+06E0..U+06E4 U+06E7..U+06E8 U+06EA..U+06ED
3256     U+0901..U+0903 U+093C U+093E..U+094C U+094D
3257     U+0951..U+0954 U+0962..U+0963 U+0981..U+0983
3258     U+09BC U+09BE U+09BF U+09C0..U+09C4
3259     U+09C7..U+09C8 U+09CB..U+09CD U+09D7
3260     U+09E2..U+09E3 U+0A02 U+0A3C U+0A3E U+0A3F
3261     U+0A40..U+0A42 U+0A47..U+0A48 U+0A4B..U+0A4D
3262     U+0A70..U+0A71 U+0A81..U+0A83 U+0ABC
3263     U+0ABE..U+0AC5 U+0AC7..U+0AC9 U+0ACB..U+0ACD
3264     U+0B01..U+0B03 U+0B3C U+0B3E..U+0B43
3265     U+0B47..U+0B48 U+0B4B..U+0B4D U+0B56..U+0B57
3266     U+0B82..U+0B83 U+0BBE..U+0BC2 U+0BC6..U+0BC8
3267     U+0BCA..U+0BCD U+0BD7 U+0C01..U+0C03
3268     U+0C3E..U+0C44 U+0C46..U+0C48 U+0C4A..U+0C4D
3269     U+0C55..U+0C56 U+0C82..U+0C83 U+0CBE..U+0CC4
3270     U+0CC6..U+0CC8 U+0CCA..U+0CCD U+0CD5..U+0CD6
3271     U+0D02..U+0D03 U+0D3E..U+0D43 U+0D46..U+0D48
3272     U+0D4A..U+0D4D U+0D57 U+0E31 U+0E34..U+0E3A
3273     U+0E47..U+0E4E U+0EB1 U+0EB4..U+0EB9
3274     U+0EBB..U+0EBC U+0EC8..U+0ECD U+0F18..U+0F19
3275     U+0F35 U+0F37 U+0F39 U+0F3E U+0F3F
3276     U+0F71..U+0F84 U+0F86..U+0F8B U+0F90..U+0F95
3277     U+0F97 U+0F99..U+0FAD U+0FB1..U+0FB7 U+0FB9
3278     U+20D0..U+20DC U+20E1 U+302A..U+302F U+3099
3279     U+309A
3280     // Extender
3281     U+00B7 U+02D0 U+02D1 U+0387 U+0640 U+0E46
3282     U+0EC6 U+3005 U+3031..U+3035 U+309D..U+309E
3283     U+30FC..U+30FE
3284     ];
3285 wakaba 1.1
3286     $NameStartChar11 := [
3287     ':' '_'
3288     'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M'
3289     'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z'
3290     'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm'
3291     'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z'
3292     U+00C0..U+00D6 U+00D8..U+00F6 U+00F8..U+02FF
3293     U+0370..U+037D U+037F..U+1FFF U+200C..U+200D
3294     U+2070..U+218F U+2C00..U+2FEF U+3001..U+D7FF
3295     U+F900..U+FDCF U+FDF0..U+FFFD U+10000..U+EFFFF
3296     ];
3297     $NameChar11 := [
3298     '-' '.' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9'
3299     U+00B7 U+0300..U+036F U+203F..U+2040
3300     // NameStartChar
3301     ':' '_'
3302     'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M'
3303     'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z'
3304     'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm'
3305     'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z'
3306     U+00C0..U+00D6 U+00D8..U+00F6 U+00F8..U+02FF
3307     U+0370..U+037D U+037F..U+1FFF U+200C..U+200D
3308     U+2070..U+218F U+2C00..U+2FEF U+3001..U+D7FF
3309     U+F900..U+FDCF U+FDF0..U+FFFD U+10000..U+EFFFF
3310     ];
3311 wakaba 1.4 } // NameChar
3312    
3313     lexmode Name
3314     : extends => 'NameChar'
3315     {
3316 wakaba 1.1 Name : value := $NameStartChar11 $NameChar11*;
3317     } // Name
3318 wakaba 1.4
3319     lexmode Nmtoken
3320     : extends => 'NameChar'
3321     {
3322     Nmtoken : value := $NameChar11*;
3323     } // Nmtoken
3324 wakaba 1.1
3325     /*
3326     Space
3327     */
3328     lexmode S {
3329     S := [U+0009 U+000A U+000D U+0020]+;
3330     } // S
3331    
3332     /*
3333     Document end scanning mode
3334     */
3335     lexmode DocumentEnd
3336     : standalone
3337     : extends => 'S'
3338     {
3339     /*
3340     Processing instruction
3341     */
3342     PIO := ['<'] ['?'];
3343    
3344     /*
3345     Comment declaration
3346     */
3347     CDO := ['<'] ['!'] ['-'] ['-'];
3348     } // DocumentEnd
3349    
3350     /*
3351     Document misc scanning mode
3352    
3353     This mode scans |Misc| constructions as well
3354     as document element's start tag.
3355     */
3356     lexmode DocumentMisc
3357     : standalone
3358     : extends => 'DocumentEnd'
3359     {
3360     /*
3361     Document element start tag
3362     */
3363     STAGO := ['<'];
3364     } // DocumentMisc
3365    
3366     /*
3367     Document prolog scanning mode
3368     */
3369     lexmode DocumentProlog
3370     : standalone
3371     : extends => 'DocumentMisc'
3372     {
3373     /*
3374     |DOCTYPE| declaration
3375     */
3376     MDO := ['<'] ['!'];
3377     } // DocumentProlog
3378    
3379     /*
3380     Document start scanning mode
3381     */
3382     lexmode DocumentStart
3383     : initial
3384     : standalone
3385     : extends => 'DocumentProlog'
3386     {
3387     /*
3388     XML declaration
3389     */
3390     XDO := ['<'] ['?'] ['x'] ['m'] ['l'];
3391     } // DocumentStart
3392    
3393     /*
3394     Comment declaration scanning mode
3395     */
3396     lexmode CommentDeclaration
3397     : standalone
3398     {
3399     /*
3400     Comment close
3401     */
3402     COM := ['-'] ['-'];
3403    
3404     /*
3405     Comment data
3406     */
3407     $string := ['-']? [^'-'];
3408     STRING : value := $string+;
3409     } // CommentDeclaration
3410    
3411     /*
3412     Processing instruction name and |S| scanning mode
3413     */
3414     lexmode PIName
3415     : standalone
3416     : extends => 'Name'
3417     : extends => 'S'
3418     {
3419     /*
3420     Processing instruction close
3421     */
3422     PIC := ['?'] ['>'];
3423     } // PIName
3424    
3425     /*
3426     Processing instruction data scanning mode
3427     */
3428     lexmode PIData
3429     : standalone
3430     {
3431     /*
3432     Processing instruction close
3433     */
3434     PIC := ['?'] ['>'];
3435    
3436     /*
3437     Processing instruction target data
3438     */
3439 wakaba 1.2 ?default-token DATA : value;
3440 wakaba 1.1 } // PIData
3441    
3442     /*
3443     Content of element scanning mode
3444     */
3445     lexmode ElementContent
3446     : standalone
3447     {
3448     /*
3449     Start tag open
3450     */
3451     STAGO := ['<'];
3452    
3453     /*
3454     End tag open
3455     */
3456     ETAGO := ['<'] ['/'];
3457    
3458     /*
3459     Hexadecimal character reference open
3460     */
3461     HCRO := ['&'] ['#'] ['x'];
3462    
3463     /*
3464     Numeric character reference open
3465     */
3466     CRO := ['&'] ['#'];
3467    
3468     /*
3469     General entity reference open
3470     */
3471     ERO := ['&'];
3472    
3473     /*
3474     Comment declaration open
3475     */
3476     CDO := ['<'] ['!'] ['-'] ['-'];
3477    
3478     /*
3479     CDATA section open
3480     */
3481     CDSO := ['<'] ['!'] ['[']
3482     ['C'] ['D'] ['A'] ['T'] ['A'] ['['];
3483    
3484     /*
3485     Processing instruction open
3486     */
3487     PIO := ['<'] ['?'];
3488 wakaba 1.2
3489     /*
3490     Markup section end
3491     */
3492     MSE := [']'] [']'] ['>'];
3493    
3494     /*
3495     Character data
3496     */
3497     /*
3498     Character data and/or |MSE|
3499     */
3500     ?default-token CharData : value;
3501 wakaba 1.1 } // ElementContent
3502    
3503     /*
3504     CDATA section content scanning mode
3505     */
3506     lexmode CDATASectionContent
3507     : standalone
3508     {
3509     /*
3510     Markup section end
3511     */
3512     MSE := [']'] [']'] ['>'];
3513    
3514     /*
3515     Character data
3516 wakaba 1.2 */
3517     ?default-token CData : value;
3518 wakaba 1.1 } // CDATASectionContent
3519    
3520     lexmode EntityReference
3521     : standalone
3522     : extends => 'Name'
3523     {
3524     /*
3525     Reference close
3526     */
3527     REFC := [';'];
3528     } // EntityReference
3529    
3530     lexmode NumericCharacterReference
3531     : standalone
3532     {
3533     /*
3534     Decimal number
3535     */
3536     $digit := ['0' '1' '2' '3' '4' '5' '6' '7' '8' '9'];
3537     NUMBER : value := $digit+;
3538    
3539     /*
3540     Reference close
3541     */
3542     REFC := [';'];
3543     } // NumericCharacterReference
3544    
3545     lexmode HexadecimalCharacterReference
3546     : standalone
3547     {
3548     /*
3549     Hexadecimal number
3550     */
3551     $hexdigit := ['0' '1' '2' '3' '4' '5' '6' '7' '8' '9'
3552     'A' 'B' 'C' 'D' 'E' 'F'
3553     'a' 'b' 'c' 'd' 'e' 'f'];
3554     Hex : value := $hexdigit+;
3555    
3556     /*
3557     Reference close
3558     */
3559     REFC := [';'];
3560     } // HexadecimalCharacterReference
3561    
3562 wakaba 1.3 lexmode XMLDeclaration
3563     : standalone
3564     : extends => 'Name'
3565     : extends => 'S'
3566     {
3567    
3568     /*
3569     Value indicator
3570     */
3571     VI := ['='];
3572    
3573     /*
3574     Literal open
3575     */
3576     LIT := ['"'];
3577     LITA := [U+0027];
3578    
3579     /*
3580     Processing instruction close
3581     */
3582     PIC := ['?'] ['>'];
3583     } // XMLDeclaration
3584    
3585 wakaba 1.1 lexmode StartTag
3586     : standalone
3587     : extends => 'Name'
3588     : extends => 'S'
3589     {
3590    
3591     /*
3592     Value indicator
3593     */
3594     VI := ['='];
3595    
3596     /*
3597     Literal open
3598     */
3599     LIT := ['"'];
3600     LITA := [U+0027];
3601    
3602     /*
3603     Tag close
3604     */
3605     TAGC := ['>'];
3606    
3607     /*
3608 wakaba 1.6 Null end-tag enabled start-tag close
3609 wakaba 1.1 */
3610 wakaba 1.6 NESTC := ['/'];
3611 wakaba 1.1 } // StartTag
3612    
3613     lexmode EndTag
3614     : standalone
3615     : extends => 'Name'
3616     : extends => 'S'
3617     {
3618     /*
3619     Tag close
3620     */
3621     TAGC := ['>'];
3622     } // EndTag
3623    
3624     lexmode AttributeValueLiteral_ {
3625     ERO := ['&'];
3626     CRO := ['&'] ['#'];
3627     HCRO := ['&'] ['#'] ['x'];
3628     } // AttributeValueLiteral_
3629    
3630     lexmode AttributeValueLiteral
3631     : standalone
3632     : extends => 'AttributeValueLiteral_'
3633     {
3634     LIT := ['"'];
3635 wakaba 1.3 STRING : value := [^'"' '&' '<']+;
3636 wakaba 1.1 } // AttributeValueLiteral
3637    
3638     lexmode AttributeValueLiteralA
3639     : standalone
3640     : extends => 'AttributeValueLiteral_'
3641     {
3642 wakaba 1.4 LITA := [U+0027];
3643 wakaba 1.3 STRING : value := [^U+0027 '&' '<']+;
3644 wakaba 1.1 } // AttributeValueLiteralA
3645 wakaba 1.11
3646     lexmode AttributeValueLiteralE
3647     : standalone
3648     : extends => 'AttributeValueLiteral_'
3649     {
3650     STRING : value := [^'&' '<']+;
3651     } // AttributeValueLiteralE
3652 wakaba 1.4
3653     lexmode EntityValue_ {
3654     PERO := ['%'];
3655     ERO := ['&'];
3656     CRO := ['&'] ['#'];
3657     HCRO := ['&'] ['#'] ['x'];
3658     } // EntityValue_
3659    
3660     lexmode EntityValue
3661     : standalone
3662     : extends => 'EntityValue_'
3663     {
3664     LIT := ['"'];
3665     STRING : value := [^'"' '&' '%']+;
3666     } // EntityValue
3667    
3668     lexmode EntityValueA
3669     : standalone
3670     : extends => 'EntityValue_'
3671     {
3672     LITA := [U+0027];
3673     STRING : value := [^U+0027 '&' '%']+;
3674     } // EntityValueA
3675    
3676     lexmode SystemLiteral
3677     : standalone
3678     {
3679     LIT := ['"'];
3680     ?default-token STRING : value;
3681     } // SystemLiteral
3682    
3683     lexmode SystemLiteralA
3684     : standalone
3685     {
3686     LITA := [U+0027];
3687     ?default-token STRING : value;
3688     } // SystemLiteralA
3689    
3690     lexmode DTD
3691     : standalone
3692     : extends => 'S'
3693     {
3694     /*
3695     Markup declaration open
3696     */
3697     MDO := ['<'] ['!'];
3698    
3699     /*
3700     Comment declaration open
3701     */
3702     CDO := ['<'] ['!'] ['-'] ['-'];
3703    
3704     /*
3705     Processing instruction open
3706     */
3707     PIO := ['<'] ['?'];
3708    
3709     /*
3710     Parameter entity reference open
3711     */
3712     PERO := ['%'];
3713    
3714     /*
3715     Declaration subset close
3716     */
3717     DSC := [']'];
3718    
3719     /*
3720     Contition section open
3721     */
3722     CSO := ['<'] ['!'] ['['];
3723     } // DTD
3724    
3725     /*
3726     Markup declaration scanning mode
3727    
3728     This mode is used to recognize |MDC| that terminates
3729     a comment declaration as well as the base |lexmode|
3730     for e.g. document type declaration scanning mode.
3731     */
3732     lexmode MarkupDeclaration
3733     : standalone
3734     : extends => 'Name'
3735     : extends => 'S'
3736     {
3737     /*
3738     Markup declaration close
3739     */
3740     MDC := ['>'];
3741    
3742     /*
3743     Literal open
3744     */
3745     LIT := ['"'];
3746    
3747     /*
3748     Alternative literal open
3749     */
3750     LITA := [U+0027];
3751    
3752     /*
3753     Parameter entity reference open
3754     */
3755     PERO := ['%'];
3756    
3757     /*
3758     Declaration subset open
3759     */
3760     DSO := ['['];
3761     } // MarkupDeclaration
3762    
3763     lexmode ElementDeclaration
3764     : standalone
3765     : extends => 'MarkupDeclaration'
3766     {
3767     /*
3768     Model group open
3769     */
3770     MGO := ['('];
3771    
3772     /*
3773     Model group close
3774     */
3775     MGC := [')'];
3776    
3777     /*
3778     Reserved name indicator
3779     */
3780     RNI := ['#'];
3781    
3782     /*
3783     Occurence indicators
3784     */
3785     OPT := ['?'];
3786     REP := ['*'];
3787     PLUS := ['+'];
3788    
3789     /*
3790     Connectors
3791     */
3792     OR := ['|'];
3793     SEQ := [','];
3794     } // ElementDeclaration
3795    
3796     lexmode AttlistDeclaration
3797     : standalone
3798     : extends => 'MarkupDeclaration'
3799     {
3800     /*
3801     Enumeration group open
3802     */
3803     EGO := ['('];
3804    
3805     /*
3806     Enumeration group close
3807     */
3808     EGC := [')'];
3809    
3810     /*
3811     Enumeration choice delimiter
3812     */
3813     OR := ['|'];
3814    
3815     /*
3816     Reserved name indicator
3817     */
3818     RNI := ['#'];
3819     } // AttlistDeclaration
3820    
3821     lexmode Enumeration
3822     : standalone
3823     : extends => 'Nmtoken'
3824     : extends => 'S'
3825     {
3826     /*
3827     Enumeration group close
3828     */
3829     EGC := [')'];
3830    
3831     /*
3832     Enumeration choice delimiter
3833     */
3834     OR := ['|'];
3835     } // Enumeration
3836    
3837 wakaba 1.1
3838     token-error default : default {
3839     lang:Perl {
3840 wakaba 1.3 my $location;
3841     __CODE{xp|get-location-from-token::
3842     $token => {$token},
3843     $result => {$location},
3844     }__;
3845     my $continue = __DOMCore:ERROR{xp|wf-syntax-error::
3846 wakaba 1.1 xp|error-token => {$token},
3847     DOMCore|location => {$location},
3848     }__;
3849     unless ($continue) {
3850     __EXCEPTION{DOMLS|PARSE_ERR::
3851     }__;
3852     }
3853     $self->{has_error} = true;
3854     }
3855     } // default
3856 wakaba 1.5
3857     @XMLTests:
3858     @@XMLTest:
3859 wakaba 1.12 @@@QName: xp.syntax.empty.test
3860     @@@DEnt:
3861     @@@@test:value: \
3862     @@@c:erred:
3863     <[[xp:wf-syntax-error]]> { (1, 1); }
3864     @@XMLTest:
3865     @@@QName: xp.syntax.space.test
3866     @@@DEnt:
3867 wakaba 1.13 @@@@test:value: \
3868 wakaba 1.12 @@@c:erred:
3869     <[[xp:wf-syntax-error]]> { (1, 4); }
3870     @@XMLTest:
3871     @@@QName: xp.syntax.newlines.test
3872     @@@DEnt:
3873     @@@@test:value:
3874     \
3875     \
3876     \
3877     @@@c:erred:
3878     <[[xp:wf-syntax-error]]> { (3, 1); }
3879    
3880     @@XMLTest:
3881 wakaba 1.6 @@@QName: xp.only.docel.test
3882 wakaba 1.5 @@@DEnt:
3883     @@@@test:value:
3884     <p></p>
3885     @@@test:domTree:
3886     document {
3887     xml-version: '1.0';
3888 wakaba 1.6 xml-encoding: null;
3889     xml-standalone: false;
3890     element {
3891     namespace-uri: null;
3892     prefix: null;
3893     local-name: 'p';
3894     text-content: '';
3895     }
3896     }
3897     @@XMLTest:
3898     @@@QName: xp.only.docel.emptyelemtag.test
3899     @@@DEnt:
3900     @@@@test:value:
3901     <p/>
3902     @@@test:domTree:
3903     document {
3904     xml-version: '1.0';
3905     xml-encoding: null;
3906     xml-standalone: false;
3907 wakaba 1.5 element {
3908     namespace-uri: null;
3909     prefix: null;
3910     local-name: 'p';
3911     text-content: '';
3912     }
3913     }
3914 wakaba 1.13
3915     @@XMLTest:
3916     @@@QName: xp.xmldecl.version.1.0.test
3917     @@@DEnt:
3918     @@@@test:value:
3919     <?xml version="1.0"?>
3920     <p></p>
3921     @@@test:domTree:
3922     document {
3923     xml-version: '1.0';
3924     xml-encoding: null;
3925     xml-standalone: false;
3926     element { }
3927     }
3928     @@XMLTest:
3929     @@@QName: xp.xmldecl.version.1.0.lita.test
3930     @@@DEnt:
3931     @@@@test:value:
3932     <?xml version='1.0'?>
3933     <p></p>
3934     @@@test:domTree:
3935     document {
3936     xml-version: '1.0';
3937     xml-encoding: null;
3938     xml-standalone: false;
3939     element { }
3940     }
3941     @@XMLTest:
3942     @@@QName: xp.xmldecl.version.1.0.s.test
3943     @@@DEnt:
3944     @@@@test:value:
3945     <?xml version = "1.0" ?>
3946     <p></p>
3947     @@@test:domTree:
3948     document {
3949     xml-version: '1.0';
3950     xml-encoding: null;
3951     xml-standalone: false;
3952     element { }
3953     }
3954     @@XMLTest:
3955     @@@QName: xp.xmldecl.version.1.1.test
3956     @@@DEnt:
3957     @@@@test:value:
3958     <?xml version="1.1"?>
3959     <p></p>
3960     @@@test:domTree:
3961     document {
3962     xml-version: '1.1';
3963     xml-encoding: null;
3964     xml-standalone: false;
3965     element { }
3966     }
3967    
3968     @@XMLTest:
3969     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.test
3970     @@@DEnt:
3971     @@@@test:value:
3972     <?xml version="1.0" encoding="US-ascii"?>
3973     <p></p>
3974     @@@test:domTree:
3975     document {
3976     xml-version: '1.0';
3977     xml-encoding: 'US-ascii';
3978     xml-standalone: false;
3979     element { }
3980     }
3981     @@XMLTest:
3982     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.lita.test
3983     @@@DEnt:
3984     @@@@test:value:
3985     <?xml version="1.0" encoding='US-ascii'?>
3986     <p></p>
3987     @@@test:domTree:
3988     document {
3989     xml-version: '1.0';
3990     xml-encoding: 'US-ascii';
3991     xml-standalone: false;
3992     element { }
3993     }
3994     @@XMLTest:
3995     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.s.test
3996     @@@DEnt:
3997     @@@@test:value:
3998     <?xml version="1.0" encoding = "US-ascii" ?>
3999     <p></p>
4000     @@@test:domTree:
4001     document {
4002     xml-version: '1.0';
4003     xml-encoding: 'US-ascii';
4004     xml-standalone: false;
4005     element { }
4006     }
4007    
4008     @@XMLTest:
4009     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.standalone.yes.test
4010     @@@DEnt:
4011     @@@@test:value:
4012     <?xml version="1.0" encoding="us-ascii" standalone="yes"?>
4013     <p></p>
4014     @@@test:domTree:
4015     document {
4016     xml-version: '1.0';
4017     xml-encoding: 'us-ascii';
4018     xml-standalone: true;
4019     element { }
4020     }
4021     @@XMLTest:
4022     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.standalone.no.test
4023     @@@DEnt:
4024     @@@@test:value:
4025     <?xml version="1.0" encoding="us-ascii" standalone="no"?>
4026     <p></p>
4027     @@@test:domTree:
4028     document {
4029     xml-version: '1.0';
4030     xml-encoding: 'us-ascii';
4031     xml-standalone: false;
4032     element { }
4033     }
4034     @@XMLTest:
4035     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.standalone.yes.lita.test
4036     @@@DEnt:
4037     @@@@test:value:
4038     <?xml version="1.0" encoding="us-ascii" standalone='yes'?>
4039     <p></p>
4040     @@@test:domTree:
4041     document {
4042     xml-version: '1.0';
4043     xml-encoding: 'us-ascii';
4044     xml-standalone: true;
4045     element { }
4046     }
4047     @@XMLTest:
4048     @@@QName: xp.xmldecl.version.1.0.encoding.usascii.standalone.yes.s.test
4049     @@@DEnt:
4050     @@@@test:value:
4051     <?xml version="1.0" encoding="us-ascii" standalone = "yes" ?>
4052     <p></p>
4053     @@@test:domTree:
4054     document {
4055     xml-version: '1.0';
4056     xml-encoding: 'us-ascii';
4057     xml-standalone: true;
4058     element { }
4059     }
4060 wakaba 1.6
4061     @@XMLTest:
4062     @@@QName: xp.doctype.empty.test
4063     @@@DEnt:
4064     @@@@test:value:
4065     <!DOCTYPE a>
4066     <a></a>
4067     @@@test:domTree:
4068     document {
4069     xml-version: '1.0';
4070     xml-encoding: null;
4071     xml-standalone: false;
4072     document-type {
4073     node-name: 'a';
4074     }
4075     element {
4076     namespace-uri: null;
4077     prefix: null;
4078     local-name: 'a';
4079     text-content: '';
4080     }
4081     }
4082    
4083     @@XMLTest:
4084     @@@QName: xp.doctype.intsubset.empty.test
4085     @@@DEnt:
4086     @@@@test:value:
4087     <!DOCTYPE a [
4088    
4089     ]>
4090     <a></a>
4091     @@@test:domTree:
4092     document {
4093     xml-version: '1.0';
4094     xml-encoding: null;
4095     xml-standalone: false;
4096     document-type {
4097     node-name: 'a';
4098     }
4099     element {
4100     namespace-uri: null;
4101     prefix: null;
4102     local-name: 'a';
4103     text-content: '';
4104     }
4105     }
4106    
4107     @@XMLTest:
4108     @@@QName: xp.doctype.intsubset.pi.test
4109     @@@DEnt:
4110     @@@@test:value:
4111     <!DOCTYPE a [
4112     <?pi data ?>
4113     ]>
4114     <a></a>
4115     @@@test:domTree:
4116     document {
4117     xml-version: '1.0';
4118     xml-encoding: null;
4119     xml-standalone: false;
4120     document-type {
4121     node-name: 'a';
4122     pi {
4123     target: 'pi';
4124     data: 'data ';
4125     }
4126     }
4127     element {
4128     namespace-uri: null;
4129     prefix: null;
4130     local-name: 'a';
4131     text-content: '';
4132     }
4133     }
4134     @@@enImplNote:
4135     A DOM PI node in doctype node is a manakai extension.
4136    
4137    
4138     @@XMLTest:
4139     @@@QName: xp.doctype.intsubset.entity.general.internal.test
4140     @@@DEnt:
4141     @@@@test:value:
4142     <!DOCTYPE a [
4143     <!ENTITY entity "entity value">
4144     ]>
4145     <a></a>
4146     @@@test:domTree:
4147     document {
4148     xml-version: '1.0';
4149     xml-encoding: null;
4150     xml-standalone: false;
4151     document-type {
4152     node-name: 'a';
4153 wakaba 1.11 general-entity {
4154     node-name: 'entity';
4155     text-content: 'entity value';
4156     has-replacement-tree: true;
4157     }
4158 wakaba 1.6 }
4159     element {
4160     namespace-uri: null;
4161     prefix: null;
4162     local-name: 'a';
4163     text-content: '';
4164     }
4165     }
4166     @@XMLTest:
4167     @@@QName: xp.doctype.intsubset.entity.parameter.internal.test
4168     @@@DEnt:
4169     @@@@test:value:
4170     <!DOCTYPE a [
4171     <!ENTITY % entity "entity value">
4172     ]>
4173     <a></a>
4174     @@@test:domTree:
4175     document {
4176     xml-version: '1.0';
4177     xml-encoding: null;
4178     xml-standalone: false;
4179     document-type {
4180     node-name: 'a';
4181     }
4182     element {
4183     namespace-uri: null;
4184     prefix: null;
4185     local-name: 'a';
4186     text-content: '';
4187     }
4188     }
4189    
4190     @@XMLTest:
4191     @@@QName: xp.doctype.internal.entity.root.element.text.only.test
4192     @@@DEnt:
4193     @@@@test:value:
4194     <!DOCTYPE a [
4195     <!ENTITY entity "entity value">
4196     ]>
4197     <a>&entity;</a>
4198     @@@test:domTree:
4199     document {
4200     xml-version: '1.0';
4201     xml-encoding: null;
4202     xml-standalone: false;
4203     document-type {
4204     node-name: 'a';
4205 wakaba 1.11 general-entity {
4206     node-name: 'entity';
4207     text-content: 'entity value';
4208     has-replacement-tree: true;
4209     }
4210 wakaba 1.6 }
4211     element {
4212     namespace-uri: null;
4213     prefix: null;
4214     local-name: 'a';
4215     general-entity-reference {
4216     node-name: 'entity';
4217     text {
4218     data: 'entity value';
4219     }
4220     }
4221     }
4222     }
4223     @@XMLTest:
4224     @@@QName: xp.doctype.internal.entity.root.element.text.mult.test
4225     @@@DEnt:
4226     @@@@test:value:
4227     <!DOCTYPE a [
4228     <!ENTITY entity "entity value">
4229     ]>
4230     <a>&entity; and &entity;</a>
4231     @@@test:domTree:
4232     document {
4233     xml-version: '1.0';
4234     xml-encoding: null;
4235     xml-standalone: false;
4236     document-type {
4237     node-name: 'a';
4238 wakaba 1.11 general-entity {
4239     node-name: 'entity';
4240     text-content: 'entity value';
4241     has-replacement-tree: true;
4242     }
4243 wakaba 1.6 }
4244     element {
4245     namespace-uri: null;
4246     prefix: null;
4247     local-name: 'a';
4248     general-entity-reference {
4249     node-name: 'entity';
4250     text {
4251     data: 'entity value';
4252     }
4253     }
4254     text { data: ' and '; }
4255     general-entity-reference {
4256     node-name: 'entity';
4257     text {
4258     data: 'entity value';
4259     }
4260     }
4261     }
4262     }
4263     @@XMLTest:
4264     @@@QName: xp.doctype.internal.entity.root.element.text.element.test
4265     @@@DEnt:
4266     @@@@test:value:
4267     <!DOCTYPE a [
4268     <!ENTITY entity "entity <p>value</p> with <e>element</e> ">
4269     ]>
4270     <a>&entity;</a>
4271     @@@test:domTree:
4272     document {
4273     xml-version: '1.0';
4274     xml-encoding: null;
4275     xml-standalone: false;
4276     document-type {
4277     node-name: 'a';
4278 wakaba 1.11 general-entity {
4279     node-name: 'entity';
4280     has-replacement-tree: true;
4281     text { data: 'entity '; }
4282     element {
4283     node-name: 'p';
4284     text-content: 'value';
4285     }
4286     text { data: ' with '; }
4287     element {
4288     node-name: 'e';
4289     text-content: 'element';
4290     }
4291     }
4292 wakaba 1.6 }
4293     element {
4294     namespace-uri: null;
4295     prefix: null;
4296     local-name: 'a';
4297     general-entity-reference {
4298     node-name: 'entity';
4299     text {
4300     data: 'entity ';
4301     }
4302     element {
4303     namespace-uri: null;
4304     prefix: null;
4305     local-name: 'p';
4306     text {
4307     data: 'value';
4308     }
4309     }
4310     text {
4311     data: ' with ';
4312     }
4313     element {
4314     namespace-uri: null;
4315     prefix: null;
4316     local-name: 'e';
4317     text {
4318     data: 'element';
4319     }
4320     }
4321     text {
4322     data: ' ';
4323     }
4324     }
4325     }
4326     }
4327     @@XMLTest:
4328     @@@QName: xp.doctype.internal.entity.root.element.text.in.ent.test
4329     @@@DEnt:
4330     @@@@test:value:
4331     <!DOCTYPE a [
4332     <!ENTITY entity1 "entity value">
4333     <!ENTITY entity2 "e&entity1;n">
4334     ]>
4335     <a>&entity2;</a>
4336     @@@test:domTree:
4337     document {
4338     xml-version: '1.0';
4339     xml-encoding: null;
4340     xml-standalone: false;
4341     document-type {
4342     node-name: 'a';
4343 wakaba 1.11 general-entity {
4344     node-name: 'entity1';
4345     text-content: 'entity value';
4346     }
4347     general-entity {
4348     node-name: 'entity2';
4349     text { data: 'e'; }
4350     general-entity-reference {
4351     node-name: 'entity1';
4352     text-content: 'entity value';
4353     is-expanded: true;
4354     }
4355     text { data: 'n'; }
4356     }
4357 wakaba 1.6 }
4358     element {
4359     namespace-uri: null;
4360     prefix: null;
4361     local-name: 'a';
4362     general-entity-reference {
4363     node-name: 'entity2';
4364     text { data: 'e'; }
4365     general-entity-reference {
4366     node-name: 'entity1';
4367     text {
4368     data: 'entity value';
4369     }
4370     }
4371     text { data: 'n'; }
4372     }
4373 wakaba 1.8 }
4374     }
4375 wakaba 1.11
4376     @@XMLTest:
4377     @@@QName: xp.doctype.entity.value.charref.test
4378     @@@DEnt:
4379     @@@@test:value:
4380     <!DOCTYPE a [
4381     <!ENTITY entity1 "entity &#x21;value&#35;">
4382     <!ENTITY entity2 '&#x21;value&#35;'>
4383     ]>
4384     <a></a>
4385     @@@test:domTree:
4386     document {
4387     document-type {
4388     general-entity {
4389     node-name: 'entity1';
4390     text-content: 'entity !value#';
4391     has-replacement-tree: true;
4392     }
4393     general-entity {
4394     node-name: 'entity2';
4395     text-content: '!value#';
4396     has-replacement-tree: true;
4397     }
4398     }
4399     element { }
4400     }
4401    
4402     @@XMLTest:
4403     @@@QName: xp.predefined.in.content.test
4404     @@@DEnt:
4405     @@@@test:value:
4406     <a>_&lt;_&gt;_&quot;_&apos;_&amp;_</a>
4407     @@@test:domTree:
4408     document {
4409     element {
4410     text-content: '_<_>_"_' U+0027 '_&_';
4411     }
4412     }
4413     @@XMLTest:
4414     @@@QName: xp.predefined.in.attr.test
4415     @@@DEnt:
4416     @@@@test:value:
4417     <a at="_&lt;_&gt;_&quot;_&apos;_&amp;_"></a>
4418     @@@test:domTree:
4419     document {
4420     element {
4421     attribute {
4422     node-name: 'at';
4423     text-content: '_<_>_"_' U+0027 '_&_';
4424     }
4425     }
4426     }
4427     @@XMLTest:
4428     @@@QName: xp.predefined.in.content.in.entity.test
4429     @@@DEnt:
4430     @@@@test:value:
4431     <!DOCTYPE a [
4432     <!ENTITY ent "_&lt;_&gt;_&quot;_&apos;_&amp;_">
4433     ]>
4434     <a>&ent;</a>
4435     @@@test:domTree:
4436     document {
4437     document-type {
4438     general-entity {
4439     node-name: 'ent';
4440     text-content: '_<_>_"_' U+0027 '_&_';
4441     }
4442     }
4443     element {
4444     text-content: '_<_>_"_' U+0027 '_&_';
4445     }
4446     }
4447     @@XMLTest:
4448     @@@QName: xp.predefined.decl.ignore.test
4449     @@@DEnt:
4450     @@@@test:value:
4451     <!DOCTYPE a [
4452     <!ENTITY lt "&#x26;#x3C;">
4453     <!ENTITY gt "&#x3E;">
4454     <!ENTITY amp "&#x26;#x26;">
4455     <!ENTITY quot "&#x22;">
4456     <!ENTITY apos "&#x27;">
4457     <!ENTITY other "other">
4458     ]>
4459     <a>_&lt;_&gt;_&quot;_&apos;_&amp;_&other;_</a>
4460     @@@test:domTree:
4461     document {
4462     document-type {
4463     general-entity {
4464     node-name: 'other';
4465     text-content: 'other';
4466     }
4467     }
4468     element {
4469     text-content: '_<_>_"_' U+0027 '_&_other_';
4470     }
4471     }
4472    
4473 wakaba 1.8 @@XMLTest:
4474     @@@QName: xp.doctype.internal.attr.empty.test
4475     @@@DEnt:
4476     @@@@test:value:
4477     <!DOCTYPE a [
4478     <!ATTLIST a>
4479     ]>
4480     <a></a>
4481     @@@test:domTree:
4482     document {
4483     xml-version: '1.0';
4484     xml-encoding: null;
4485     xml-standalone: false;
4486     document-type {
4487     node-name: 'a';
4488     element-type-definition {
4489     node-name: 'a';
4490     }
4491     }
4492     element {
4493     namespace-uri: null;
4494     local-name: 'a';
4495     }
4496     }
4497     @@XMLTest:
4498     @@@QName: xp.doctype.internal.attr.cdata.implied.test
4499     @@@DEnt:
4500     @@@@test:value:
4501     <!DOCTYPE a [
4502     <!ATTLIST a
4503     at CDATA #IMPLIED
4504     >
4505     ]>
4506     <a></a>
4507     @@@test:domTree:
4508     document {
4509     xml-version: '1.0';
4510     xml-encoding: null;
4511     xml-standalone: false;
4512     document-type {
4513     node-name: 'a';
4514     element-type-definition {
4515     node-name: 'a';
4516     attribute-definition {
4517     node-name: 'at';
4518     declared-type: const (CDATA_ATTR);
4519     allowed-tokens: DOMStringList ();
4520     default-type: const (IMPLIED_DEFAULT);
4521     text-content: '';
4522     }
4523     }
4524     }
4525     element {
4526     namespace-uri: null;
4527     local-name: 'a';
4528     }
4529     }
4530     @@XMLTest:
4531     @@@QName: xp.doctype.internal.attr.types.implied.test
4532     @@@DEnt:
4533     @@@@test:value:
4534     <!DOCTYPE a [
4535     <!ATTLIST a
4536     at1 ID #IMPLIED
4537     at2 IDREF #IMPLIED
4538     at3 IDREFS #IMPLIED
4539     at4 ENTITY #IMPLIED
4540     at5 ENTITIES #IMPLIED
4541     at6 NMTOKEN #IMPLIED
4542     at7 NMTOKENS #IMPLIED
4543     at8 NOTATION (n1 | n2|n3) #IMPLIED
4544     at9 (e1| e2| e3 ) #IMPLIED
4545     >
4546     ]>
4547     <a></a>
4548     @@@test:domTree:
4549     document {
4550     xml-version: '1.0';
4551     xml-encoding: null;
4552     xml-standalone: false;
4553     document-type {
4554     node-name: 'a';
4555     element-type-definition {
4556     node-name: 'a';
4557     attribute-definition {
4558     node-name: 'at1';
4559     declared-type: const (ID_ATTR);
4560     allowed-tokens: DOMStringList ();
4561     default-type: const (IMPLIED_DEFAULT);
4562     text-content: '';
4563     }
4564     attribute-definition {
4565     node-name: 'at2';
4566     declared-type: const (IDREF_ATTR);
4567     allowed-tokens: DOMStringList ();
4568     default-type: const (IMPLIED_DEFAULT);
4569     text-content: '';
4570     }
4571     attribute-definition {
4572     node-name: 'at3';
4573     declared-type: const (IDREFS_ATTR);
4574     allowed-tokens: DOMStringList ();
4575     default-type: const (IMPLIED_DEFAULT);
4576     text-content: '';
4577     }
4578     attribute-definition {
4579     node-name: 'at4';
4580     declared-type: const (ENTITY_ATTR);
4581     allowed-tokens: DOMStringList ();
4582     default-type: const (IMPLIED_DEFAULT);
4583     text-content: '';
4584     }
4585     attribute-definition {
4586     node-name: 'at5';
4587     declared-type: const (ENTITIES_ATTR);
4588     allowed-tokens: DOMStringList ();
4589     default-type: const (IMPLIED_DEFAULT);
4590     text-content: '';
4591     }
4592     attribute-definition {
4593     node-name: 'at6';
4594     declared-type: const (NMTOKEN_ATTR);
4595     allowed-tokens: DOMStringList ();
4596     default-type: const (IMPLIED_DEFAULT);
4597     text-content: '';
4598     }
4599     attribute-definition {
4600     node-name: 'at7';
4601     declared-type: const (NMTOKENS_ATTR);
4602     allowed-tokens: DOMStringList ();
4603     default-type: const (IMPLIED_DEFAULT);
4604     text-content: '';
4605     }
4606     attribute-definition {
4607     node-name: 'at8';
4608     declared-type: const (NOTATION_ATTR);
4609     allowed-tokens: DOMStringList ('n1', 'n2', 'n3');
4610     default-type: const (IMPLIED_DEFAULT);
4611     text-content: '';
4612     }
4613     attribute-definition {
4614     node-name: 'at9';
4615     declared-type: const (ENUMERATION_ATTR);
4616     allowed-tokens: DOMStringList ('e1', 'e2', 'e3');
4617     default-type: const (IMPLIED_DEFAULT);
4618     text-content: '';
4619     }
4620     }
4621     }
4622     element {
4623     namespace-uri: null;
4624     local-name: 'a';
4625     }
4626     }
4627     @@XMLTest:
4628     @@@QName: xp.doctype.internal.attr.cdata.defaults.test
4629     @@@DEnt:
4630     @@@@test:value:
4631     <!DOCTYPE a [
4632     <!ATTLIST a
4633     at1 CDATA #IMPLIED
4634     at2 CDATA #REQUIRED
4635     at3 CDATA #FIXED "value3"
4636     at4 CDATA "value4"
4637     at5 CDATA #FIXED 'value5'
4638     at6 CDATA 'value6'
4639     >
4640     ]>
4641     <a></a>
4642     @@@test:domTree:
4643     document {
4644     xml-version: '1.0';
4645     xml-encoding: null;
4646     xml-standalone: false;
4647     document-type {
4648     node-name: 'a';
4649     element-type-definition {
4650     node-name: 'a';
4651     attribute-definition {
4652     node-name: 'at1';
4653     declared-type: const (CDATA_ATTR);
4654     allowed-tokens: DOMStringList ();
4655     default-type: const (IMPLIED_DEFAULT);
4656     text-content: '';
4657     }
4658     attribute-definition {
4659     node-name: 'at2';
4660     declared-type: const (CDATA_ATTR);
4661     allowed-tokens: DOMStringList ();
4662     default-type: const (REQUIRED_DEFAULT);
4663     text-content: '';
4664     }
4665     attribute-definition {
4666     node-name: 'at3';
4667     declared-type: const (CDATA_ATTR);
4668     allowed-tokens: DOMStringList ();
4669     default-type: const (FIXED_DEFAULT);
4670     text-content: 'value3';
4671     }
4672     attribute-definition {
4673     node-name: 'at4';
4674     declared-type: const (CDATA_ATTR);
4675     allowed-tokens: DOMStringList ();
4676     default-type: const (EXPLICIT_DEFAULT);
4677     text-content: 'value4';
4678     }
4679     attribute-definition {
4680     node-name: 'at5';
4681     declared-type: const (CDATA_ATTR);
4682     allowed-tokens: DOMStringList ();
4683     default-type: const (FIXED_DEFAULT);
4684     text-content: 'value5';
4685     }
4686     attribute-definition {
4687     node-name: 'at6';
4688     declared-type: const (CDATA_ATTR);
4689     allowed-tokens: DOMStringList ();
4690     default-type: const (EXPLICIT_DEFAULT);
4691     text-content: 'value6';
4692     }
4693     }
4694     }
4695     element {
4696     namespace-uri: null;
4697     local-name: 'a';
4698 wakaba 1.10 attribute {
4699     node-name: 'at3';
4700     text-content: 'value3';
4701     specified: false;
4702     }
4703     attribute {
4704     node-name: 'at4';
4705     text-content: 'value4';
4706     specified: false;
4707     }
4708     attribute {
4709     node-name: 'at5';
4710     text-content: 'value5';
4711     specified: false;
4712     }
4713     attribute {
4714     node-name: 'at6';
4715     text-content: 'value6';
4716     specified: false;
4717     }
4718 wakaba 1.9 }
4719     }
4720    
4721     @@XMLTest:
4722     @@@QName: xp.doctype.internal.attr.cdata.default.normalize.test
4723     @@@DEnt:
4724     @@@@test:value:
4725     <!DOCTYPE a [
4726     <!ATTLIST a
4727     at CDATA " default &#x0A;value "
4728     >
4729     ]>
4730     <a></a>
4731     @@@test:domTree:
4732     document {
4733     xml-version: '1.0';
4734     xml-encoding: null;
4735     xml-standalone: false;
4736     document-type {
4737     node-name: 'a';
4738     element-type-definition {
4739     node-name: 'a';
4740     attribute-definition {
4741     node-name: 'at';
4742     declared-type: const (CDATA_ATTR);
4743     allowed-tokens: DOMStringList ();
4744     default-type: const (EXPLICIT_DEFAULT);
4745     text-content: ' default ' U+000A 'value ';
4746     }
4747     }
4748     }
4749     element {
4750     namespace-uri: null;
4751     local-name: 'a';
4752 wakaba 1.10 attribute {
4753     node-name: 'at';
4754     text-content: ' default ' U+000A 'value ';
4755     specified: false;
4756     }
4757 wakaba 1.9 }
4758     }
4759     @@XMLTest:
4760     @@@QName: xp.doctype.internal.attr.nmtoken.default.normalize.test
4761     @@@DEnt:
4762     @@@@test:value:
4763     <!DOCTYPE a [
4764     <!ATTLIST a
4765     at NMTOKEN " default &#x0A;value "
4766     >
4767     ]>
4768     <a></a>
4769     @@@test:domTree:
4770     document {
4771     xml-version: '1.0';
4772     xml-encoding: null;
4773     xml-standalone: false;
4774     document-type {
4775     node-name: 'a';
4776     element-type-definition {
4777     node-name: 'a';
4778     attribute-definition {
4779     node-name: 'at';
4780     declared-type: const (NMTOKEN_ATTR);
4781     allowed-tokens: DOMStringList ();
4782     default-type: const (EXPLICIT_DEFAULT);
4783     text-content: ' default ' U+000A 'value ';
4784     }
4785     }
4786     }
4787     element {
4788     namespace-uri: null;
4789     local-name: 'a';
4790 wakaba 1.10 attribute {
4791     node-name: 'at';
4792     text-content: ' default ' U+000A 'value ';
4793     specified: false;
4794     }
4795 wakaba 1.9 }
4796     }
4797    
4798     @@XMLTest:
4799     @@@QName: xp.doctype.attrtype.no-value.test
4800     @@@DEnt:
4801     @@@@test:value:
4802     <!DOCTYPE a>
4803     <a at=" at value "></a>
4804     @@@test:domTree:
4805     document {
4806     xml-version: '1.0';
4807     xml-encoding: null;
4808     xml-standalone: false;
4809     document-type { }
4810     element {
4811     namespace-uri: null;
4812     local-name: 'a';
4813     attribute {
4814     namespace-uri: null;
4815     local-name: 'at';
4816     value: ' at value ';
4817     text {
4818     data: ' at value ';
4819     }
4820     schema-type-info: TypeInfo (null, null);
4821 wakaba 1.10 specified: true;
4822 wakaba 1.9 }
4823     }
4824     }
4825     @@XMLTest:
4826     @@@QName: xp.doctype.attrtype.cdata.test
4827     @@@DEnt:
4828     @@@@test:value:
4829     <!DOCTYPE a [
4830     <!ATTLIST a
4831     at CDATA #IMPLIED
4832     >
4833     ]>
4834     <a at=" at value "></a>
4835     @@@test:domTree:
4836     document {
4837     xml-version: '1.0';
4838     xml-encoding: null;
4839     xml-standalone: false;
4840     document-type { }
4841     element {
4842     namespace-uri: null;
4843     local-name: 'a';
4844     attribute {
4845     namespace-uri: null;
4846     local-name: 'at';
4847     value: ' at value ';
4848     text {
4849     data: ' at value ';
4850     }
4851     schema-type-info:
4852     TypeInfo ('http://www.w3.org/TR/REC-xml', 'CDATA');
4853 wakaba 1.10 specified: true;
4854 wakaba 1.9 }
4855     }
4856     }
4857     @@XMLTest:
4858     @@@QName: xp.doctype.attrtype.nmtoken.test
4859     @@@DEnt:
4860     @@@@test:value:
4861     <!DOCTYPE a [
4862     <!ATTLIST a
4863     at NMTOKEN #IMPLIED
4864     >
4865     ]>
4866     <a at=" at value "></a>
4867     @@@test:domTree:
4868     document {
4869     xml-version: '1.0';
4870     xml-encoding: null;
4871     xml-standalone: false;
4872     document-type { }
4873     element {
4874     namespace-uri: null;
4875     local-name: 'a';
4876     attribute {
4877     namespace-uri: null;
4878     local-name: 'at';
4879     value: 'at value';
4880     text {
4881     data: ' at value ';
4882     }
4883     schema-type-info:
4884     TypeInfo ('http://www.w3.org/TR/REC-xml', 'NMTOKEN');
4885 wakaba 1.10 specified: true;
4886 wakaba 1.9 }
4887     }
4888     }
4889    
4890     @@XMLTest:
4891     @@@QName: xp.doctype.attr.normalization.1.test
4892     @@@DEnt:
4893     @@@@test:value:
4894     <a at=" at &#xA;value "></a>
4895     @@@test:domTree:
4896     document {
4897     element {
4898     attribute {
4899 wakaba 1.10 node-name: 'at';
4900 wakaba 1.9 value: ' at ' U+000A 'value ';
4901     schema-type-info: TypeInfo (null, null);
4902 wakaba 1.10 specified: true;
4903 wakaba 1.9 }
4904     }
4905     }
4906     @@XMLTest:
4907     @@@QName: xp.doctype.attr.normalization.2.test
4908     @@@DEnt:
4909     @@@@test:value:
4910     <a at=" at &#xD;value "></a>
4911     @@@test:domTree:
4912     document {
4913     element {
4914     attribute {
4915     value: ' at ' U+000D 'value ';
4916     schema-type-info: TypeInfo (null, null);
4917 wakaba 1.10 specified: true;
4918 wakaba 1.9 }
4919     }
4920     }
4921     @@XMLTest:
4922     @@@QName: xp.doctype.attr.normalization.3.test
4923     @@@DEnt:
4924     @@@@test:value:
4925     <a at=" at &#x9;value "></a>
4926     @@@test:domTree:
4927     document {
4928     element {
4929     attribute {
4930 wakaba 1.10 node-name: 'at';
4931 wakaba 1.9 value: ' at ' U+0009 'value ';
4932     schema-type-info: TypeInfo (null, null);
4933 wakaba 1.10 specified: true;
4934     }
4935     }
4936     }
4937    
4938     @@XMLTest:
4939     @@@QName: xp.doctype.attr.specified.1.test
4940     @@@DEnt:
4941     @@@@test:value:
4942     <!DOCTYPE a [
4943     <!ATTLIST a
4944     at CDATA "default"
4945     >
4946     ]>
4947     <a></a>
4948     @@@test:domTree:
4949     document {
4950     document-type { }
4951     element {
4952     attribute {
4953     node-name: 'at';
4954     value: 'default';
4955     specified: false;
4956     }
4957     }
4958     }
4959     @@XMLTest:
4960     @@@QName: xp.doctype.attr.specified.2.test
4961     @@@DEnt:
4962     @@@@test:value:
4963     <!DOCTYPE a [
4964     <!ATTLIST a
4965     at CDATA "default"
4966     >
4967     ]>
4968     <a at2="specified"></a>
4969     @@@test:domTree:
4970     document {
4971     document-type { }
4972     element {
4973     attribute {
4974     node-name: 'at';
4975     value: 'default';
4976     specified: false;
4977     }
4978     attribute {
4979     node-name: 'at2';
4980     value: 'specified';
4981     specified: true;
4982     }
4983     }
4984     }
4985     @@XMLTest:
4986     @@@QName: xp.doctype.attr.specified.3.test
4987     @@@DEnt:
4988     @@@@test:value:
4989     <!DOCTYPE a [
4990     <!ATTLIST a
4991     at CDATA "default"
4992     >
4993     ]>
4994     <a at="specified"></a>
4995     @@@test:domTree:
4996     document {
4997     document-type { }
4998     element {
4999     attribute {
5000     node-name: 'at';
5001     value: 'specified';
5002     specified: true;
5003 wakaba 1.11 }
5004     }
5005     }
5006    
5007     @@XMLTest:
5008     @@@QName: xp.attr.literal.charref.test
5009     @@@DEnt:
5010     @@@@test:value:
5011     <a at1 = "value&#33;_&#x25;value"
5012     at2 = 'value&#x25;_&#33;value'></a>
5013     @@@test:domTree:
5014     document {
5015     element {
5016     attribute {
5017     node-name: 'at1';
5018     text-content: 'value!_%value';
5019     }
5020     attribute {
5021     node-name: 'at2';
5022     text-content: 'value%_!value';
5023     }
5024     }
5025     }
5026     @@XMLTest:
5027     @@@QName: xp.attr.literal.entref.test
5028     @@@DEnt:
5029     @@@@test:value:
5030     <!DOCTYPE a [
5031     <!ENTITY ent "entity&#x26;#33;_&#x26;#x29;value">
5032     ]>
5033     <a at1 = "value&ent;value"
5034     at2 = 'value&ent;value'></a>
5035     @@@test:domTree:
5036     document {
5037     document-type {
5038     general-entity {
5039     node-name: 'ent';
5040     text-content: 'entity!_)value';
5041     }
5042     }
5043     element {
5044     attribute {
5045     node-name: 'at1';
5046     text-content: 'valueentity!_)valuevalue';
5047     }
5048     attribute {
5049     node-name: 'at2';
5050     text-content: 'valueentity!_)valuevalue';
5051     }
5052     }
5053     }
5054     @@XMLTest:
5055     @@@QName: xp.attr.literal.entref.nest.test
5056     @@@DEnt:
5057     @@@@test:value:
5058     <!DOCTYPE a [
5059     <!ENTITY ent1 "entity&#x26;#33;_&#x26;#x29;value">
5060     <!ENTITY ent2 "@&ent1;@">
5061     ]>
5062     <a at1 = "value&ent2;value"
5063     at2 = 'value&ent2;value'></a>
5064     @@@test:domTree:
5065     document {
5066     document-type {
5067     general-entity {
5068     node-name: 'ent1';
5069     text-content: 'entity!_)value';
5070     }
5071     general-entity {
5072     node-name: 'ent2';
5073     text-content: '@entity!_)value@';
5074     }
5075     }
5076     element {
5077     attribute {
5078     node-name: 'at1';
5079     text-content: 'value@entity!_)value@value';
5080     }
5081     attribute {
5082     node-name: 'at2';
5083     text-content: 'value@entity!_)value@value';
5084 wakaba 1.9 }
5085 wakaba 1.6 }
5086     }
5087    
5088 wakaba 1.5 @@PerlDef:
5089     my $impl = $Message::DOM::ImplementationRegistry->get_implementation ({
5090     'Core' => '3.0',
5091     'XML' => '3.0',
5092     'XMLVersion' => ['1.0', '1.1'],
5093     });
5094     my $parser = <Class::ManakaiXMLParser>->new ($impl);
5095    
5096     for my $test_data (@$TestData) {
5097     $test->start_new_test ($test_data->{uri});
5098     my $doc_ent = $test_data->{entity}->{$test_data->{root_uri}};
5099 wakaba 1.12
5100     $parser->dom_config->set_parameter ('error-handler' => sub ($$) {
5101     my (undef, $err) = @_;
5102     my $err_type = $err->type;
5103     if ($test_data->{dom_error}->{$err_type}) {
5104     $test->assert_error_equals
5105     (actual_value => $err,
5106     expected_hash => pop @{$test_data->{dom_error}
5107     ->{$err_type}});
5108     } else { # Uncatched error
5109     warn $err;
5110     }
5111     return true; # continue as far as possible
5112     });
5113    
5114     if ($test_data->{dom_tree}) { # Successful test
5115     try {
5116     my $doc = $parser->parse_string ($doc_ent->{<H::test:value>});
5117     $test->assert_dom_tree_equals
5118     (actual_value => $doc,
5119     expected_hash => $test_data->{dom_tree});
5120     my $has_error;
5121     for (values %{$test_data->{dom_error}||{}}) {
5122     if (@$_) {
5123     $test->failure_comment
5124     (@$_.' |DOMError|s of type |'.
5125 wakaba 1.13 $_->[0]->{type}->{value}.'| are not reported');
5126 wakaba 1.12 $has_error = true;
5127     }
5128     }
5129     $has_error ? $test->not_ok : $test->ok;
5130     } catch Message::Util::IF::DTException with {
5131     #
5132     } catch Message::DOM::IF::LSException with {
5133     $test->assert_never;
5134     };
5135     } else {
5136     try {
5137     my $doc = $parser->parse_string ($doc_ent->{<H::test:value>});
5138     $test->assert_never;
5139     } catch Message::Util::IF::DTException with {
5140     #
5141     } catch Message::DOM::IF::LSException with {
5142     #
5143     };
5144     my $has_error;
5145     for (values %{$test_data->{dom_error}||{}}) {
5146     if (@$_) {
5147     $test->failure_comment
5148     (@$_.' |DOMError|s of type |'.
5149 wakaba 1.13 $_->[0]->{type}->{value}.'| are not reported');
5150 wakaba 1.12 $has_error = true;
5151     }
5152     }
5153     $has_error ? $test->not_ok : $test->ok;
5154     }
5155 wakaba 1.5 }
5156 wakaba 1.6
5157     @ResourceDef:
5158     @@QName: getCopyOfEntityState
5159     @@rdf:type: DISPerl|InlineCode
5160     @@ForCheck: ManakaiDOM|ForClass
5161     @@PerlDef:
5162     {%{$self->{$entity_type}->{$entity_name}},
5163     line => 1, column => 1, pos => 0}
5164 wakaba 1.1 ##ManakaiXMLParser
5165 wakaba 1.5
5166     ElementTypeBinding:
5167     @Name: XMLTests
5168     @ElementType:
5169     dis:ResourceDef
5170     @ShadowContent:
5171     @@ForCheck: ManakaiDOM|ForClass
5172     @@rdf:type: test|ParserTestSet
5173    
5174     ElementTypeBinding:
5175     @Name: XMLTest
5176     @ElementType:
5177     dis:ResourceDef
5178     @ShadowContent:
5179     @@ForCheck: ManakaiDOM|ForClass
5180     @@rdf:type: test|ParserTest
5181    
5182     ElementTypeBinding:
5183     @Name: DEnt
5184     @ElementType:
5185     dis:ResourceDef
5186     @ShadowContent:
5187     @@rdf:type: test|RootEntity
5188    
5189     ElementTypeBinding:
5190     @Name: Ent
5191     @ElementType:
5192     dis:ResourceDef
5193     @ShadowContent:
5194     @@rdf:type: test|Entity
5195 wakaba 1.1
5196 wakaba 1.3 ResourceDef:
5197     @QName: xp|get-location-from-token
5198     @rdf:type: DISPerl|BlockCode
5199     @enDesc:
5200     Creates a <IF::DOMCore:DOMLocator> object from a token.
5201     @PerlDef:
5202     $result = {
5203 wakaba 1.6 utf32_offset => $self->{entity}->[-1]->{pos},
5204 wakaba 1.13 line_number => $self->{entity}->[-1]->{line},
5205     column_number => $self->{entity}->[-1]->{column},
5206 wakaba 1.3 };
5207     @For: ManakaiDOM|ManakaiDOM3
5208 wakaba 1.1
5209     ElementTypeBinding:
5210     @Name: RuleDef
5211     @ElementType:
5212     dis:ResourceDef
5213     @ShadowContent:
5214     @@ForCheck: ManakaiDOM|ForClass
5215     @@rdf:type: Muf2003|RuleDefClass
5216    
5217     ElementTypeBinding:
5218     @Name: RuleParam
5219     @ElementType:
5220     dis:ResourceDef
5221     @ShadowContent:
5222     @@rdf:type: Muf2003|RuleParameter
5223    
5224     ElementTypeBinding:
5225     @Name: enImplNote
5226     @ElementType:
5227     dis:ImplNote
5228     @ShadowContent:
5229     @@lang:en
5230    
5231     ElementTypeBinding:
5232     @Name: ErrDef
5233     @ElementType:
5234     dis:ResourceDef
5235     @ShadowContent:
5236     @@rdf:type: DOMCore|DOMErrorType
5237     @@For: ManakaiDOM|DOM3
5238     @@ecore:textFormatter: ManakaiXMLParserExceptionFormatter
5239    
5240 wakaba 1.3 ElementTypeBinding:
5241     @Name: WFErrDef
5242     @ElementType:
5243     dis:ResourceDef
5244     @ShadowContent:
5245     @@rdf:type: DOMCore|DOMErrorType
5246     @@For: ManakaiDOM|DOM3
5247     @@ecore:textFormatter: ManakaiXMLParserExceptionFormatter
5248    
5249     WFErrDef:
5250     @QName: xp|wf-syntax-error
5251     @enDesc:
5252     The entity does not match to the production rule; it is not
5253     well-formed.
5254     @DOMCore:severity: DOMCore|SEVERITY_FATAL_ERROR
5255     @enMufDef:
5256     |%xp-error-token-type;|%xp-error-token-value
5257     (prefix => { (|}, suffix => {|)}); is not
5258     allowed%xp-error-lines (prefix => { (|}, suffix => {|)});
5259     @ecore:hasParameter:
5260     @@@: xp|error-token
5261     @@enDesc:
5262     The token that is not allowed.
5263    
5264     WFErrDef:
5265     @QName: xp|wf-pi-target-is-xml
5266     @enDesc:
5267     A processing instruction has its <CODE::PITarget> of
5268     <XML::xml> (in any case) which is not allowed.
5269     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5270     @enMufDef:
5271     Processing instruction target name cannot be |%p
5272     (name => {<Q::xp|name>});|
5273     @ecore:hasParameter:
5274     @@@: xp|error-token
5275     @@enDesc:
5276     The token that contains the name.
5277     @ecore:hasParameter:
5278     @@@: xp|name
5279     @@enDesc:
5280     A string that is specified as target name of the
5281     processing instruction.
5282     @ecore:hasParameter: xp|parent
5283    
5284     WFErrDef:
5285     @QName: xp|wf-no-end-tag
5286     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5287     @enDesc:
5288     An end-tag is not found.
5289     @enMufDef:
5290     End-tag |</%p (name => {<Q::xp|expected-element-type>});>| is required
5291     @ecore:hasParameter: xp|error-token
5292     @ecore:hasParameter:
5293     @@@: xp|node
5294     @@enDesc:
5295     The element node that is not closed.
5296     @ecore:hasParameter:
5297     @@@: xp|expected-element-type
5298     @@enDesc:
5299     The element type name of the element that is not closed.
5300    
5301     WFErrDef:
5302     @QName: xp|wf-unsupported-xml-version
5303     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5304     @enDesc:
5305     The XML version specified in the version declaration is not supported.
5306     @enMufDef:
5307     XML version |%p (name => {<Q::infoset|version>});| is not supported
5308     @ecore:hasParameter: xp|bad-token
5309     @ecore:hasParameter:
5310     @@@: xp|parent
5311     @@enDesc:
5312     The document node.
5313     @ecore:hasParameter:
5314     @@@: infoset|version
5315     @@enDesc:
5316     The specified XML version.
5317    
5318     WFErrDef:
5319     @QName: xp|wf-malformed-enc-name
5320     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5321     @enDesc:
5322     An <XA::encoding> pseudo-attribute value does not match
5323     to the procduction rule <CODE::EncName>.
5324     @enMufDef:
5325     Encoding name |%p (name => {<Q::xp|name>});| is not allowed
5326     @ecore:hasParameter: xp|error-token
5327     @ecore:hasParameter:
5328     @@@: xp|parent
5329     @@enDesc: The document node.
5330     @ecore:hasParameter:
5331     @@@: xp|name
5332     @@enDesc:
5333     The <XA::encoding> value.
5334    
5335     WFErrDef:
5336     @QName: xp|wf-malformed-xml-standalone
5337     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5338     @enDesc:
5339     An <XA::standalone> pseudo-attribute value is neither <XML::yes>
5340     or <XML::no>.
5341     @enMufDef:
5342     |standalone| pseudo-attribute value |%p (name => {<Q::xp|name>});|
5343     is not allowed
5344     @ecore:hasParameter: xp|error-token
5345     @ecore:hasParameter:
5346     @@@: xp|parent
5347     @@enDesc: The document node.
5348     @ecore:hasParameter:
5349     @@@: xp|name
5350     @@enDesc:
5351     The <XA::standalone> value.
5352    
5353     WFErrDef:
5354     @QName: xp|wf-legal-literal-character
5355     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5356     @enDesc:
5357     Each character in XML entity must match to the production
5358     rule <CODE::Char - RestrictedChar>.
5359     @enMufDef:
5360     Character %character-code-point
5361     (v => {<Q::xp|character-number>}); is not allowed
5362     @ecore:hasParameter:
5363     @@@: xp|character-number
5364     @@enDesc:
5365     The code position of the character being referred.
5366    
5367     WFErrDef:
5368     @QName: xp|wf-element-type-match
5369     @DOMCore:severity: DOMCore|SEVERITY_FATAL_ERROR
5370 wakaba 1.1 @enDesc:
5371 wakaba 1.3 The <CODE::Name> in an element's end-tag must match the element type
5372     in the start-tag.
5373     @enMufDef:
5374     End-tag |</%p (name => {<Q::xp|actual-element-type>});>| does
5375     not match to start-tag |<%p (name => {<Q::xp|expected-element-type>});>|
5376     @ecore:hasParameter: xp|error-token
5377     @ecore:hasParameter:
5378     @@@: xp|node
5379     @@enDesc:
5380     The current opening element node.
5381     @ecore:hasParameter:
5382     @@@: xp|expected-element-type
5383     @@enDesc:
5384     The element type name of the current element.
5385     @ecore:hasParameter:
5386     @@@: xp|actual-element-type
5387     @@enDesc:
5388     The <CODE::Name> occurs in the end-tag.
5389    
5390     WFErrDef:
5391     @QName: xp|wf-unique-att-spec
5392 wakaba 1.1 @DOMCore:severity: DOMCore|SEVERITY_ERROR
5393 wakaba 1.3 @enDesc:
5394     An attribute name <kwd:MUST-NOT> appear more than once in
5395     the same start-tag or empty-element tag.
5396 wakaba 1.1 @enMufDef:
5397 wakaba 1.3 Attribute |%p (name => {<Q::xp|name>});| is specified more
5398     than once in the same tag
5399     @ecore:hasParameter: xp|error-token
5400     @ecore:hasParameter:
5401     @@@: xp|name
5402     @@enDesc:
5403     The name of the attribute.
5404    
5405     WFErrDef:
5406     @QName: xp|wf-legal-character
5407     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5408     @enDesc:
5409     Characters referred to using character references <kwd:MUST>
5410     match the production for <CODE::Char>.
5411     @enMufDef:
5412     Reference to character %character-code-point
5413     (v => {<Q::xp|character-number>}); is not allowed
5414     @ecore:hasParameter: xp|error-token
5415     @ecore:hasParameter:
5416     @@@: xp|character-number
5417     @@enDesc:
5418     The code position of the character being referred.
5419     @ecore:hasParameter:
5420     @@@: xp|parent
5421     @@enDesc:
5422     The parent node in which the character reference has
5423     occurred, if available.
5424 wakaba 1.1
5425 wakaba 1.3 XWParam:
5426 wakaba 1.1 @QName: xp|error-token
5427     @enDesc:
5428     The token where the parser found an error.
5429    
5430 wakaba 1.3 XWParam:
5431     @QName: xp|name
5432     @enDesc:
5433     A name.
5434    
5435     XWParam:
5436     @QName: xp|parent
5437     @enDesc:
5438     The parent node in which the error occurs.
5439    
5440     XWParam:
5441     @QName: xp|node
5442     @enDesc:
5443     The current node.
5444    
5445     XWParam:
5446     @QName: xp|actual-element-type
5447     @enDesc:
5448     The actual element type name occured in the source.
5449    
5450     XWParam:
5451     @QName: xp|expected-element-type
5452 wakaba 1.1 @enDesc:
5453 wakaba 1.3 The element type name expected.
5454    
5455     XWParam:
5456     @QName: xp|character-number
5457     @enDesc:
5458     The character code position.
5459    
5460     ElementTypeBinding:
5461     @Name: XWParam
5462     @ElementType:
5463     dis:ResourceDef
5464     @ShadowContent:
5465     @@For: =ManakaiDOM|all
5466     @@rdf:type: ecore|Parameter
5467 wakaba 1.1
5468     ElementTypeBinding:
5469     @Name:enMufDef
5470     @ElementType:
5471     ecore:defaultMessage
5472     @ShadowContent:
5473     @@lang:en
5474     @@ContentType:
5475     lang:muf
5476    
5477     ResourceDef:
5478     @QName: DOMImpl
5479     @AliasFor: DOMCore|DOMImplementation
5480     @For: ManakaiDOM|DOM
5481    
5482     ElementTypeBinding:
5483     @Name: Attr
5484     @ElementType:
5485     dis:ResourceDef
5486     @ShadowContent:
5487     @@rdf:type: DISLang|Attribute
5488     @@ForCheck: !=ManakaiDOM|ManakaiDOM
5489    
5490     ElementTypeBinding:
5491     @Name: Get
5492     @ElementType:
5493     dis:ResourceDef
5494     @ShadowContent:
5495     @@rdf:type: DISLang|AttributeGet
5496    
5497     ElementTypeBinding:
5498     @Name: Set
5499     @ElementType:
5500     dis:ResourceDef
5501     @ShadowContent:
5502     @@rdf:type: DISLang|AttributeSet
5503    
5504     ElementTypeBinding:
5505     @Name: enDesc
5506     @ElementType:
5507     dis:Description
5508     @ShadowContent:
5509     @@lang:en
5510    
5511     ElementTypeBinding:
5512     @Name: Method
5513     @ElementType:
5514     dis:ResourceDef
5515     @ShadowContent:
5516     @@rdf:type: DISLang|Method
5517     @@For: !=ManakaiDOM|ManakaiDOM
5518    
5519     ElementTypeBinding:
5520     @Name: Return
5521     @ElementType:
5522     dis:ResourceDef
5523     @ShadowContent:
5524     @@rdf:type: DISLang|MethodReturn
5525    
5526     ElementTypeBinding:
5527     @Name: Param
5528     @ElementType:
5529     dis:ResourceDef
5530     @ShadowContent:
5531     @@rdf:type: DISLang|MethodParameter
5532    
5533     ElementTypeBinding:
5534     @Name: PerlDef
5535     @ElementType:
5536     dis:Def
5537     @ShadowContent:
5538     @@ContentType: lang|Perl
5539    
5540     ElementTypeBinding:
5541     @Name: PropDef
5542     @ElementType:
5543     dis:ResourceDef
5544     @ShadowContent:
5545     @@rdf:type: rdf|Property
5546    
5547     ClsDef:
5548     @ClsQName: ManakaiXMLParserExceptionFormatter
5549    
5550     @ClsISA: ecore|MUErrorFormatter||ManakaiDOM|Perl
5551    
5552     @RuleDef:
5553     @@Name: xp-error-token-type
5554     @@enDesc:
5555     The type of the token the parser is encountered.
5556    
5557     @@Method:
5558     @@@Name: after
5559     @@@Param:
5560     @@@@Name: name
5561     @@@@Type: DOMString
5562     @@@@enDesc: The name of the method.
5563     @@@Param:
5564     @@@@Name: p
5565     @@@@Type: DISPerl|HASH
5566     @@@@enDesc: The set of the parameters to the method.
5567     @@@Param:
5568     @@@@Name: o
5569     @@@@Type: DISPerl|HASH
5570     @@@@enDesc: The option value.
5571     @@@Return:
5572     @@@@PerlDef:
5573     $p->{-result} = $o->{<H::xp|error-token>}->{type}
5574     if defined $o->{<H::xp|error-token>}->{type};
5575    
5576     @RuleDef:
5577     @@Name: xp-error-token-value
5578     @@enDesc:
5579     The value of the token the parser is encountered, if any.
5580    
5581     @@Method:
5582     @@@Name: after
5583     @@@Param:
5584     @@@@Name: name
5585     @@@@Type: DOMString
5586     @@@@enDesc: The name of the method.
5587     @@@Param:
5588     @@@@Name: p
5589     @@@@Type: DISPerl|HASH
5590     @@@@enDesc: The set of the parameters to the method.
5591     @@@Param:
5592     @@@@Name: o
5593     @@@@Type: DISPerl|HASH
5594     @@@@enDesc: The option value.
5595     @@@Return:
5596     @@@@PerlDef:
5597     $p->{-result} = $o->{<H::xp|error-token>}->{value}
5598     if defined $o->{<H::xp|error-token>}->{value};
5599    
5600     @RuleDef:
5601     @@Name: xp-error-lines
5602     @@enDesc:
5603     A copy of fragment of the source text that contains the line
5604     where the error occurred, if available.
5605    
5606     @@Method:
5607     @@@Name: after
5608     @@@Param:
5609     @@@@Name: name
5610     @@@@Type: DOMString
5611     @@@@enDesc: The name of the method.
5612     @@@Param:
5613     @@@@Name: p
5614     @@@@Type: DISPerl|HASH
5615     @@@@enDesc: The set of the parameters to the method.
5616     @@@Param:
5617     @@@@Name: o
5618     @@@@Type: DISPerl|HASH
5619     @@@@enDesc: The option value.
5620     @@@Return:
5621     @@@@PerlDef:
5622     my $pos = $o-><AG::DOMCore|DOMError.location>
5623     -><AG::DOMCore|DOMLocator.utf32Offset>;
5624     if ($pos > -1) {
5625 wakaba 1.6 my $src = $o->{<H::ecore|object>}->{entity}->[-1]->{reptxt};
5626 wakaba 1.1 my $start = $pos;
5627     $start = rindex ($$src, "\x0A", $start - 1) for 0..2;
5628     $start++;
5629     my $end = $pos;
5630     $end = index ($$src, "\x0A", $end + 1) for 0..2;
5631     $end = length $$src if $end < 0;
5632     $p->{-result} = substr $$src, $start, $end - $start;
5633     }
5634 wakaba 1.3
5635     @RuleDef:
5636     @@Name: character-code-point
5637     @@enDesc:
5638     The character code position, in <CODE::U+<VAR::HHHH>> notation.
5639    
5640     @@Method:
5641     @@@Name: after
5642     @@@Param:
5643     @@@@Name: name
5644     @@@@Type: DOMString
5645     @@@@enDesc: The name of the method.
5646     @@@Param:
5647     @@@@Name: p
5648     @@@@Type: DISPerl|HASH
5649     @@@@enDesc: The set of the parameters to the method.
5650     @@@Param:
5651     @@@@Name: o
5652     @@@@Type: DISPerl|HASH
5653     @@@@enDesc: The option value.
5654     @@@RuleParam:
5655     @@@@Name: v
5656     @@@@Type: DISPerl|Number
5657     @@@@enDesc:
5658     The name of the error parameter that contains the character code.
5659     @@@Return:
5660     @@@@PerlDef:
5661     $p->{-result} = sprintf 'U+%04X', $o->{$p->{v}};
5662 wakaba 1.1 ##XMLParserExceptionFormatter

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24