/[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.11 - (hide annotations) (download)
Mon Jan 30 15:17:58 2006 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.10: +833 -144 lines
++ manakai/lib/Message/Util/DIS/ChangeLog	30 Jan 2006 15:17:54 -0000
	* DPG.dis (plCodeFragment): Code generated from |dpg:matchElseBlock|
	was included to every |token-error|-converted code.

2006-01-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/DOM/ChangeLog	30 Jan 2006 15:15:09 -0000
2006-01-30  Wakaba  <wakaba@suika.fam.cx>

	* XDoctype.dis (d:Feature): New canonical feature
	name |fe:XDoctype| is added.

	* XMLParser.dis: Predefined general entity references
	are implemented.  Creates |Entity| nodes from general entities
	declared in internal subset.  |Entity| nodes created from internal
	general parsed entities now have replacement tree.
	Sets |cfg:entity-reference-read-only| flag off during
	the tree generation.  Some parsing rules use |$self->{doc}|
	rather than |$doc| parameter.  Similarly, |$self->{docx}| (document
	node with |fe:XDoctype| feature) and |$self->{dtdef}| are
	introduced.  General entity references in attribute value literal
	are supported.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24