/[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.12 - (hide annotations) (download)
Wed Feb 8 08:18:29 2006 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.11: +79 -8 lines
++ manakai/bin/ChangeLog	8 Feb 2006 07:59:04 -0000
2006-02-08  Wakaba  <wakaba@suika.fam.cx>

	* dac2test.pl (|test:ParserTest| converter): |c:erred| is supported.

++ manakai/lib/Message/Util/ChangeLog	8 Feb 2006 08:07:42 -0000
2006-02-08  Wakaba  <wakaba@suika.fam.cx>

	* PerlCode.dis (getNameListAttrR): Non-|pc:|-namespace elements
	and their descendants were ignored.
	(getNameListAttrRM): New variant derived from |getNameListAttrR|,
	for |getUsePerlModuleNameList| and |getUseCharClassNameList|.
	(getUsePerlModuleNameList, getUseCharClassNameList): Don't
	include |pc:package| and their descendants to the target.
	(PerlFile.stringify): Outputs |use| statements
	for Perl modules and character classes not part of any package,
	if any.

	* DIS.dis: |lang:tdterr|'s |DVNSValue| convertion is supported.

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

	* DIS.dis (loadModule): Loads a "daem" submodule file
	if exists.

++ manakai/lib/Message/Util/Error/ChangeLog	8 Feb 2006 08:17:54 -0000
2006-02-06  Wakaba  <wakaba@suika.fam.cx>

	* DOMException.dis (ManakaiDOM:WarningClass): Removed.
	(ManakaiDOM:alwaysWarns): Removed.
	(disPerl:WARNING): Removed.
	(ManakaiDOM:ManakaiDOMExceptionOrWarning): Removed.
	(ManakaiDOM:ManakaiDOMWarning): Removed.

++ manakai/lib/Message/Util/DIS/ChangeLog	8 Feb 2006 08:16:38 -0000
2006-02-08  Wakaba  <wakaba@suika.fam.cx>

	* Value.dis: |lang:tdterr| type support is added.

	* Test.dis (failureComment): New method.
	(TFQNames): New token type.
	(rule node): It now accepts empty declaration.

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

	* Test.dis (assertTypedValueEquals): New code fragment
	extracted from |assertDOMTreeEquals| method.
	(assertErrorEquals): New method.

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

	* Test.dis (Require): Requires |Util:DIS| module.
	(parseTDTErrorString): New method.
	(URI, QName): New token types.
	(rule tdterr): New parser rule.
	(dtest:undeclared-namespace-prefix-error): New error.
	(dtest:bad-error-resource-error): New error.

++ manakai/lib/Message/DOM/ChangeLog	8 Feb 2006 08:01:24 -0000
2006-02-08  Wakaba  <wakaba@suika.fam.cx>

	* XMLParser.dis (XMLTests): Tests for |c:erred| is supported.

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

	* DOMCore.dis (c:erred): New property.
	(c:DOMErrorType): It should have been a subset
	of |ecore:AnyErrorCode|.

	* XMLParser.dis (XMLTests): Empty input tests added.

++ manakai/lib/manakai/ChangeLog	8 Feb 2006 08:18:20 -0000
2006-02-06  Wakaba  <wakaba@suika.fam.cx>

	* Test.dis (lang:tdterr): New type.

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.12 $Date: 2006/01/30 15:17:58 $
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.12 @@@QName: xp.syntax.empty.test
3859     @@@DEnt:
3860     @@@@test:value: \
3861     @@@c:erred:
3862     <[[xp:wf-syntax-error]]> { (1, 1); }
3863     @@XMLTest:
3864     @@@QName: xp.syntax.space.test
3865     @@@DEnt:
3866     @@@@test:value: \
3867     @@@c:erred:
3868     <[[xp:wf-syntax-error]]> { (1, 4); }
3869     @@XMLTest:
3870     @@@QName: xp.syntax.newlines.test
3871     @@@DEnt:
3872     @@@@test:value:
3873     \
3874     \
3875     \
3876     @@@c:erred:
3877     <[[xp:wf-syntax-error]]> { (3, 1); }
3878    
3879     @@XMLTest:
3880 wakaba 1.6 @@@QName: xp.only.docel.test
3881 wakaba 1.5 @@@DEnt:
3882     @@@@test:value:
3883     <p></p>
3884     @@@test:domTree:
3885     document {
3886     xml-version: '1.0';
3887 wakaba 1.6 xml-encoding: null;
3888     xml-standalone: false;
3889     element {
3890     namespace-uri: null;
3891     prefix: null;
3892     local-name: 'p';
3893     text-content: '';
3894     }
3895     }
3896     @@XMLTest:
3897     @@@QName: xp.only.docel.emptyelemtag.test
3898     @@@DEnt:
3899     @@@@test:value:
3900     <p/>
3901     @@@test:domTree:
3902     document {
3903     xml-version: '1.0';
3904     xml-encoding: null;
3905     xml-standalone: false;
3906 wakaba 1.5 element {
3907     namespace-uri: null;
3908     prefix: null;
3909     local-name: 'p';
3910     text-content: '';
3911     }
3912     }
3913 wakaba 1.6
3914     @@XMLTest:
3915     @@@QName: xp.doctype.empty.test
3916     @@@DEnt:
3917     @@@@test:value:
3918     <!DOCTYPE a>
3919     <a></a>
3920     @@@test:domTree:
3921     document {
3922     xml-version: '1.0';
3923     xml-encoding: null;
3924     xml-standalone: false;
3925     document-type {
3926     node-name: 'a';
3927     }
3928     element {
3929     namespace-uri: null;
3930     prefix: null;
3931     local-name: 'a';
3932     text-content: '';
3933     }
3934     }
3935    
3936     @@XMLTest:
3937     @@@QName: xp.doctype.intsubset.empty.test
3938     @@@DEnt:
3939     @@@@test:value:
3940     <!DOCTYPE a [
3941    
3942     ]>
3943     <a></a>
3944     @@@test:domTree:
3945     document {
3946     xml-version: '1.0';
3947     xml-encoding: null;
3948     xml-standalone: false;
3949     document-type {
3950     node-name: 'a';
3951     }
3952     element {
3953     namespace-uri: null;
3954     prefix: null;
3955     local-name: 'a';
3956     text-content: '';
3957     }
3958     }
3959    
3960     @@XMLTest:
3961     @@@QName: xp.doctype.intsubset.pi.test
3962     @@@DEnt:
3963     @@@@test:value:
3964     <!DOCTYPE a [
3965     <?pi data ?>
3966     ]>
3967     <a></a>
3968     @@@test:domTree:
3969     document {
3970     xml-version: '1.0';
3971     xml-encoding: null;
3972     xml-standalone: false;
3973     document-type {
3974     node-name: 'a';
3975     pi {
3976     target: 'pi';
3977     data: 'data ';
3978     }
3979     }
3980     element {
3981     namespace-uri: null;
3982     prefix: null;
3983     local-name: 'a';
3984     text-content: '';
3985     }
3986     }
3987     @@@enImplNote:
3988     A DOM PI node in doctype node is a manakai extension.
3989    
3990    
3991     @@XMLTest:
3992     @@@QName: xp.doctype.intsubset.entity.general.internal.test
3993     @@@DEnt:
3994     @@@@test:value:
3995     <!DOCTYPE a [
3996     <!ENTITY entity "entity value">
3997     ]>
3998     <a></a>
3999     @@@test:domTree:
4000     document {
4001     xml-version: '1.0';
4002     xml-encoding: null;
4003     xml-standalone: false;
4004     document-type {
4005     node-name: 'a';
4006 wakaba 1.11 general-entity {
4007     node-name: 'entity';
4008     text-content: 'entity value';
4009     has-replacement-tree: true;
4010     }
4011 wakaba 1.6 }
4012     element {
4013     namespace-uri: null;
4014     prefix: null;
4015     local-name: 'a';
4016     text-content: '';
4017     }
4018     }
4019     @@XMLTest:
4020     @@@QName: xp.doctype.intsubset.entity.parameter.internal.test
4021     @@@DEnt:
4022     @@@@test:value:
4023     <!DOCTYPE a [
4024     <!ENTITY % entity "entity value">
4025     ]>
4026     <a></a>
4027     @@@test:domTree:
4028     document {
4029     xml-version: '1.0';
4030     xml-encoding: null;
4031     xml-standalone: false;
4032     document-type {
4033     node-name: 'a';
4034     }
4035     element {
4036     namespace-uri: null;
4037     prefix: null;
4038     local-name: 'a';
4039     text-content: '';
4040     }
4041     }
4042    
4043     @@XMLTest:
4044     @@@QName: xp.doctype.internal.entity.root.element.text.only.test
4045     @@@DEnt:
4046     @@@@test:value:
4047     <!DOCTYPE a [
4048     <!ENTITY entity "entity value">
4049     ]>
4050     <a>&entity;</a>
4051     @@@test:domTree:
4052     document {
4053     xml-version: '1.0';
4054     xml-encoding: null;
4055     xml-standalone: false;
4056     document-type {
4057     node-name: 'a';
4058 wakaba 1.11 general-entity {
4059     node-name: 'entity';
4060     text-content: 'entity value';
4061     has-replacement-tree: true;
4062     }
4063 wakaba 1.6 }
4064     element {
4065     namespace-uri: null;
4066     prefix: null;
4067     local-name: 'a';
4068     general-entity-reference {
4069     node-name: 'entity';
4070     text {
4071     data: 'entity value';
4072     }
4073     }
4074     }
4075     }
4076     @@XMLTest:
4077     @@@QName: xp.doctype.internal.entity.root.element.text.mult.test
4078     @@@DEnt:
4079     @@@@test:value:
4080     <!DOCTYPE a [
4081     <!ENTITY entity "entity value">
4082     ]>
4083     <a>&entity; and &entity;</a>
4084     @@@test:domTree:
4085     document {
4086     xml-version: '1.0';
4087     xml-encoding: null;
4088     xml-standalone: false;
4089     document-type {
4090     node-name: 'a';
4091 wakaba 1.11 general-entity {
4092     node-name: 'entity';
4093     text-content: 'entity value';
4094     has-replacement-tree: true;
4095     }
4096 wakaba 1.6 }
4097     element {
4098     namespace-uri: null;
4099     prefix: null;
4100     local-name: 'a';
4101     general-entity-reference {
4102     node-name: 'entity';
4103     text {
4104     data: 'entity value';
4105     }
4106     }
4107     text { data: ' and '; }
4108     general-entity-reference {
4109     node-name: 'entity';
4110     text {
4111     data: 'entity value';
4112     }
4113     }
4114     }
4115     }
4116     @@XMLTest:
4117     @@@QName: xp.doctype.internal.entity.root.element.text.element.test
4118     @@@DEnt:
4119     @@@@test:value:
4120     <!DOCTYPE a [
4121     <!ENTITY entity "entity <p>value</p> with <e>element</e> ">
4122     ]>
4123     <a>&entity;</a>
4124     @@@test:domTree:
4125     document {
4126     xml-version: '1.0';
4127     xml-encoding: null;
4128     xml-standalone: false;
4129     document-type {
4130     node-name: 'a';
4131 wakaba 1.11 general-entity {
4132     node-name: 'entity';
4133     has-replacement-tree: true;
4134     text { data: 'entity '; }
4135     element {
4136     node-name: 'p';
4137     text-content: 'value';
4138     }
4139     text { data: ' with '; }
4140     element {
4141     node-name: 'e';
4142     text-content: 'element';
4143     }
4144     }
4145 wakaba 1.6 }
4146     element {
4147     namespace-uri: null;
4148     prefix: null;
4149     local-name: 'a';
4150     general-entity-reference {
4151     node-name: 'entity';
4152     text {
4153     data: 'entity ';
4154     }
4155     element {
4156     namespace-uri: null;
4157     prefix: null;
4158     local-name: 'p';
4159     text {
4160     data: 'value';
4161     }
4162     }
4163     text {
4164     data: ' with ';
4165     }
4166     element {
4167     namespace-uri: null;
4168     prefix: null;
4169     local-name: 'e';
4170     text {
4171     data: 'element';
4172     }
4173     }
4174     text {
4175     data: ' ';
4176     }
4177     }
4178     }
4179     }
4180     @@XMLTest:
4181     @@@QName: xp.doctype.internal.entity.root.element.text.in.ent.test
4182     @@@DEnt:
4183     @@@@test:value:
4184     <!DOCTYPE a [
4185     <!ENTITY entity1 "entity value">
4186     <!ENTITY entity2 "e&entity1;n">
4187     ]>
4188     <a>&entity2;</a>
4189     @@@test:domTree:
4190     document {
4191     xml-version: '1.0';
4192     xml-encoding: null;
4193     xml-standalone: false;
4194     document-type {
4195     node-name: 'a';
4196 wakaba 1.11 general-entity {
4197     node-name: 'entity1';
4198     text-content: 'entity value';
4199     }
4200     general-entity {
4201     node-name: 'entity2';
4202     text { data: 'e'; }
4203     general-entity-reference {
4204     node-name: 'entity1';
4205     text-content: 'entity value';
4206     is-expanded: true;
4207     }
4208     text { data: 'n'; }
4209     }
4210 wakaba 1.6 }
4211     element {
4212     namespace-uri: null;
4213     prefix: null;
4214     local-name: 'a';
4215     general-entity-reference {
4216     node-name: 'entity2';
4217     text { data: 'e'; }
4218     general-entity-reference {
4219     node-name: 'entity1';
4220     text {
4221     data: 'entity value';
4222     }
4223     }
4224     text { data: 'n'; }
4225     }
4226 wakaba 1.8 }
4227     }
4228 wakaba 1.11
4229     @@XMLTest:
4230     @@@QName: xp.doctype.entity.value.charref.test
4231     @@@DEnt:
4232     @@@@test:value:
4233     <!DOCTYPE a [
4234     <!ENTITY entity1 "entity &#x21;value&#35;">
4235     <!ENTITY entity2 '&#x21;value&#35;'>
4236     ]>
4237     <a></a>
4238     @@@test:domTree:
4239     document {
4240     document-type {
4241     general-entity {
4242     node-name: 'entity1';
4243     text-content: 'entity !value#';
4244     has-replacement-tree: true;
4245     }
4246     general-entity {
4247     node-name: 'entity2';
4248     text-content: '!value#';
4249     has-replacement-tree: true;
4250     }
4251     }
4252     element { }
4253     }
4254    
4255     @@XMLTest:
4256     @@@QName: xp.predefined.in.content.test
4257     @@@DEnt:
4258     @@@@test:value:
4259     <a>_&lt;_&gt;_&quot;_&apos;_&amp;_</a>
4260     @@@test:domTree:
4261     document {
4262     element {
4263     text-content: '_<_>_"_' U+0027 '_&_';
4264     }
4265     }
4266     @@XMLTest:
4267     @@@QName: xp.predefined.in.attr.test
4268     @@@DEnt:
4269     @@@@test:value:
4270     <a at="_&lt;_&gt;_&quot;_&apos;_&amp;_"></a>
4271     @@@test:domTree:
4272     document {
4273     element {
4274     attribute {
4275     node-name: 'at';
4276     text-content: '_<_>_"_' U+0027 '_&_';
4277     }
4278     }
4279     }
4280     @@XMLTest:
4281     @@@QName: xp.predefined.in.content.in.entity.test
4282     @@@DEnt:
4283     @@@@test:value:
4284     <!DOCTYPE a [
4285     <!ENTITY ent "_&lt;_&gt;_&quot;_&apos;_&amp;_">
4286     ]>
4287     <a>&ent;</a>
4288     @@@test:domTree:
4289     document {
4290     document-type {
4291     general-entity {
4292     node-name: 'ent';
4293     text-content: '_<_>_"_' U+0027 '_&_';
4294     }
4295     }
4296     element {
4297     text-content: '_<_>_"_' U+0027 '_&_';
4298     }
4299     }
4300     @@XMLTest:
4301     @@@QName: xp.predefined.decl.ignore.test
4302     @@@DEnt:
4303     @@@@test:value:
4304     <!DOCTYPE a [
4305     <!ENTITY lt "&#x26;#x3C;">
4306     <!ENTITY gt "&#x3E;">
4307     <!ENTITY amp "&#x26;#x26;">
4308     <!ENTITY quot "&#x22;">
4309     <!ENTITY apos "&#x27;">
4310     <!ENTITY other "other">
4311     ]>
4312     <a>_&lt;_&gt;_&quot;_&apos;_&amp;_&other;_</a>
4313     @@@test:domTree:
4314     document {
4315     document-type {
4316     general-entity {
4317     node-name: 'other';
4318     text-content: 'other';
4319     }
4320     }
4321     element {
4322     text-content: '_<_>_"_' U+0027 '_&_other_';
4323     }
4324     }
4325    
4326 wakaba 1.8 @@XMLTest:
4327     @@@QName: xp.doctype.internal.attr.empty.test
4328     @@@DEnt:
4329     @@@@test:value:
4330     <!DOCTYPE a [
4331     <!ATTLIST a>
4332     ]>
4333     <a></a>
4334     @@@test:domTree:
4335     document {
4336     xml-version: '1.0';
4337     xml-encoding: null;
4338     xml-standalone: false;
4339     document-type {
4340     node-name: 'a';
4341     element-type-definition {
4342     node-name: 'a';
4343     }
4344     }
4345     element {
4346     namespace-uri: null;
4347     local-name: 'a';
4348     }
4349     }
4350     @@XMLTest:
4351     @@@QName: xp.doctype.internal.attr.cdata.implied.test
4352     @@@DEnt:
4353     @@@@test:value:
4354     <!DOCTYPE a [
4355     <!ATTLIST a
4356     at CDATA #IMPLIED
4357     >
4358     ]>
4359     <a></a>
4360     @@@test:domTree:
4361     document {
4362     xml-version: '1.0';
4363     xml-encoding: null;
4364     xml-standalone: false;
4365     document-type {
4366     node-name: 'a';
4367     element-type-definition {
4368     node-name: 'a';
4369     attribute-definition {
4370     node-name: 'at';
4371     declared-type: const (CDATA_ATTR);
4372     allowed-tokens: DOMStringList ();
4373     default-type: const (IMPLIED_DEFAULT);
4374     text-content: '';
4375     }
4376     }
4377     }
4378     element {
4379     namespace-uri: null;
4380     local-name: 'a';
4381     }
4382     }
4383     @@XMLTest:
4384     @@@QName: xp.doctype.internal.attr.types.implied.test
4385     @@@DEnt:
4386     @@@@test:value:
4387     <!DOCTYPE a [
4388     <!ATTLIST a
4389     at1 ID #IMPLIED
4390     at2 IDREF #IMPLIED
4391     at3 IDREFS #IMPLIED
4392     at4 ENTITY #IMPLIED
4393     at5 ENTITIES #IMPLIED
4394     at6 NMTOKEN #IMPLIED
4395     at7 NMTOKENS #IMPLIED
4396     at8 NOTATION (n1 | n2|n3) #IMPLIED
4397     at9 (e1| e2| e3 ) #IMPLIED
4398     >
4399     ]>
4400     <a></a>
4401     @@@test:domTree:
4402     document {
4403     xml-version: '1.0';
4404     xml-encoding: null;
4405     xml-standalone: false;
4406     document-type {
4407     node-name: 'a';
4408     element-type-definition {
4409     node-name: 'a';
4410     attribute-definition {
4411     node-name: 'at1';
4412     declared-type: const (ID_ATTR);
4413     allowed-tokens: DOMStringList ();
4414     default-type: const (IMPLIED_DEFAULT);
4415     text-content: '';
4416     }
4417     attribute-definition {
4418     node-name: 'at2';
4419     declared-type: const (IDREF_ATTR);
4420     allowed-tokens: DOMStringList ();
4421     default-type: const (IMPLIED_DEFAULT);
4422     text-content: '';
4423     }
4424     attribute-definition {
4425     node-name: 'at3';
4426     declared-type: const (IDREFS_ATTR);
4427     allowed-tokens: DOMStringList ();
4428     default-type: const (IMPLIED_DEFAULT);
4429     text-content: '';
4430     }
4431     attribute-definition {
4432     node-name: 'at4';
4433     declared-type: const (ENTITY_ATTR);
4434     allowed-tokens: DOMStringList ();
4435     default-type: const (IMPLIED_DEFAULT);
4436     text-content: '';
4437     }
4438     attribute-definition {
4439     node-name: 'at5';
4440     declared-type: const (ENTITIES_ATTR);
4441     allowed-tokens: DOMStringList ();
4442     default-type: const (IMPLIED_DEFAULT);
4443     text-content: '';
4444     }
4445     attribute-definition {
4446     node-name: 'at6';
4447     declared-type: const (NMTOKEN_ATTR);
4448     allowed-tokens: DOMStringList ();
4449     default-type: const (IMPLIED_DEFAULT);
4450     text-content: '';
4451     }
4452     attribute-definition {
4453     node-name: 'at7';
4454     declared-type: const (NMTOKENS_ATTR);
4455     allowed-tokens: DOMStringList ();
4456     default-type: const (IMPLIED_DEFAULT);
4457     text-content: '';
4458     }
4459     attribute-definition {
4460     node-name: 'at8';
4461     declared-type: const (NOTATION_ATTR);
4462     allowed-tokens: DOMStringList ('n1', 'n2', 'n3');
4463     default-type: const (IMPLIED_DEFAULT);
4464     text-content: '';
4465     }
4466     attribute-definition {
4467     node-name: 'at9';
4468     declared-type: const (ENUMERATION_ATTR);
4469     allowed-tokens: DOMStringList ('e1', 'e2', 'e3');
4470     default-type: const (IMPLIED_DEFAULT);
4471     text-content: '';
4472     }
4473     }
4474     }
4475     element {
4476     namespace-uri: null;
4477     local-name: 'a';
4478     }
4479     }
4480     @@XMLTest:
4481     @@@QName: xp.doctype.internal.attr.cdata.defaults.test
4482     @@@DEnt:
4483     @@@@test:value:
4484     <!DOCTYPE a [
4485     <!ATTLIST a
4486     at1 CDATA #IMPLIED
4487     at2 CDATA #REQUIRED
4488     at3 CDATA #FIXED "value3"
4489     at4 CDATA "value4"
4490     at5 CDATA #FIXED 'value5'
4491     at6 CDATA 'value6'
4492     >
4493     ]>
4494     <a></a>
4495     @@@test:domTree:
4496     document {
4497     xml-version: '1.0';
4498     xml-encoding: null;
4499     xml-standalone: false;
4500     document-type {
4501     node-name: 'a';
4502     element-type-definition {
4503     node-name: 'a';
4504     attribute-definition {
4505     node-name: 'at1';
4506     declared-type: const (CDATA_ATTR);
4507     allowed-tokens: DOMStringList ();
4508     default-type: const (IMPLIED_DEFAULT);
4509     text-content: '';
4510     }
4511     attribute-definition {
4512     node-name: 'at2';
4513     declared-type: const (CDATA_ATTR);
4514     allowed-tokens: DOMStringList ();
4515     default-type: const (REQUIRED_DEFAULT);
4516     text-content: '';
4517     }
4518     attribute-definition {
4519     node-name: 'at3';
4520     declared-type: const (CDATA_ATTR);
4521     allowed-tokens: DOMStringList ();
4522     default-type: const (FIXED_DEFAULT);
4523     text-content: 'value3';
4524     }
4525     attribute-definition {
4526     node-name: 'at4';
4527     declared-type: const (CDATA_ATTR);
4528     allowed-tokens: DOMStringList ();
4529     default-type: const (EXPLICIT_DEFAULT);
4530     text-content: 'value4';
4531     }
4532     attribute-definition {
4533     node-name: 'at5';
4534     declared-type: const (CDATA_ATTR);
4535     allowed-tokens: DOMStringList ();
4536     default-type: const (FIXED_DEFAULT);
4537     text-content: 'value5';
4538     }
4539     attribute-definition {
4540     node-name: 'at6';
4541     declared-type: const (CDATA_ATTR);
4542     allowed-tokens: DOMStringList ();
4543     default-type: const (EXPLICIT_DEFAULT);
4544     text-content: 'value6';
4545     }
4546     }
4547     }
4548     element {
4549     namespace-uri: null;
4550     local-name: 'a';
4551 wakaba 1.10 attribute {
4552     node-name: 'at3';
4553     text-content: 'value3';
4554     specified: false;
4555     }
4556     attribute {
4557     node-name: 'at4';
4558     text-content: 'value4';
4559     specified: false;
4560     }
4561     attribute {
4562     node-name: 'at5';
4563     text-content: 'value5';
4564     specified: false;
4565     }
4566     attribute {
4567     node-name: 'at6';
4568     text-content: 'value6';
4569     specified: false;
4570     }
4571 wakaba 1.9 }
4572     }
4573    
4574     @@XMLTest:
4575     @@@QName: xp.doctype.internal.attr.cdata.default.normalize.test
4576     @@@DEnt:
4577     @@@@test:value:
4578     <!DOCTYPE a [
4579     <!ATTLIST a
4580     at CDATA " default &#x0A;value "
4581     >
4582     ]>
4583     <a></a>
4584     @@@test:domTree:
4585     document {
4586     xml-version: '1.0';
4587     xml-encoding: null;
4588     xml-standalone: false;
4589     document-type {
4590     node-name: 'a';
4591     element-type-definition {
4592     node-name: 'a';
4593     attribute-definition {
4594     node-name: 'at';
4595     declared-type: const (CDATA_ATTR);
4596     allowed-tokens: DOMStringList ();
4597     default-type: const (EXPLICIT_DEFAULT);
4598     text-content: ' default ' U+000A 'value ';
4599     }
4600     }
4601     }
4602     element {
4603     namespace-uri: null;
4604     local-name: 'a';
4605 wakaba 1.10 attribute {
4606     node-name: 'at';
4607     text-content: ' default ' U+000A 'value ';
4608     specified: false;
4609     }
4610 wakaba 1.9 }
4611     }
4612     @@XMLTest:
4613     @@@QName: xp.doctype.internal.attr.nmtoken.default.normalize.test
4614     @@@DEnt:
4615     @@@@test:value:
4616     <!DOCTYPE a [
4617     <!ATTLIST a
4618     at NMTOKEN " default &#x0A;value "
4619     >
4620     ]>
4621     <a></a>
4622     @@@test:domTree:
4623     document {
4624     xml-version: '1.0';
4625     xml-encoding: null;
4626     xml-standalone: false;
4627     document-type {
4628     node-name: 'a';
4629     element-type-definition {
4630     node-name: 'a';
4631     attribute-definition {
4632     node-name: 'at';
4633     declared-type: const (NMTOKEN_ATTR);
4634     allowed-tokens: DOMStringList ();
4635     default-type: const (EXPLICIT_DEFAULT);
4636     text-content: ' default ' U+000A 'value ';
4637     }
4638     }
4639     }
4640     element {
4641     namespace-uri: null;
4642     local-name: 'a';
4643 wakaba 1.10 attribute {
4644     node-name: 'at';
4645     text-content: ' default ' U+000A 'value ';
4646     specified: false;
4647     }
4648 wakaba 1.9 }
4649     }
4650    
4651     @@XMLTest:
4652     @@@QName: xp.doctype.attrtype.no-value.test
4653     @@@DEnt:
4654     @@@@test:value:
4655     <!DOCTYPE a>
4656     <a at=" at value "></a>
4657     @@@test:domTree:
4658     document {
4659     xml-version: '1.0';
4660     xml-encoding: null;
4661     xml-standalone: false;
4662     document-type { }
4663     element {
4664     namespace-uri: null;
4665     local-name: 'a';
4666     attribute {
4667     namespace-uri: null;
4668     local-name: 'at';
4669     value: ' at value ';
4670     text {
4671     data: ' at value ';
4672     }
4673     schema-type-info: TypeInfo (null, null);
4674 wakaba 1.10 specified: true;
4675 wakaba 1.9 }
4676     }
4677     }
4678     @@XMLTest:
4679     @@@QName: xp.doctype.attrtype.cdata.test
4680     @@@DEnt:
4681     @@@@test:value:
4682     <!DOCTYPE a [
4683     <!ATTLIST a
4684     at CDATA #IMPLIED
4685     >
4686     ]>
4687     <a at=" at value "></a>
4688     @@@test:domTree:
4689     document {
4690     xml-version: '1.0';
4691     xml-encoding: null;
4692     xml-standalone: false;
4693     document-type { }
4694     element {
4695     namespace-uri: null;
4696     local-name: 'a';
4697     attribute {
4698     namespace-uri: null;
4699     local-name: 'at';
4700     value: ' at value ';
4701     text {
4702     data: ' at value ';
4703     }
4704     schema-type-info:
4705     TypeInfo ('http://www.w3.org/TR/REC-xml', 'CDATA');
4706 wakaba 1.10 specified: true;
4707 wakaba 1.9 }
4708     }
4709     }
4710     @@XMLTest:
4711     @@@QName: xp.doctype.attrtype.nmtoken.test
4712     @@@DEnt:
4713     @@@@test:value:
4714     <!DOCTYPE a [
4715     <!ATTLIST a
4716     at NMTOKEN #IMPLIED
4717     >
4718     ]>
4719     <a at=" at value "></a>
4720     @@@test:domTree:
4721     document {
4722     xml-version: '1.0';
4723     xml-encoding: null;
4724     xml-standalone: false;
4725     document-type { }
4726     element {
4727     namespace-uri: null;
4728     local-name: 'a';
4729     attribute {
4730     namespace-uri: null;
4731     local-name: 'at';
4732     value: 'at value';
4733     text {
4734     data: ' at value ';
4735     }
4736     schema-type-info:
4737     TypeInfo ('http://www.w3.org/TR/REC-xml', 'NMTOKEN');
4738 wakaba 1.10 specified: true;
4739 wakaba 1.9 }
4740     }
4741     }
4742    
4743     @@XMLTest:
4744     @@@QName: xp.doctype.attr.normalization.1.test
4745     @@@DEnt:
4746     @@@@test:value:
4747     <a at=" at &#xA;value "></a>
4748     @@@test:domTree:
4749     document {
4750     element {
4751     attribute {
4752 wakaba 1.10 node-name: 'at';
4753 wakaba 1.9 value: ' at ' U+000A 'value ';
4754     schema-type-info: TypeInfo (null, null);
4755 wakaba 1.10 specified: true;
4756 wakaba 1.9 }
4757     }
4758     }
4759     @@XMLTest:
4760     @@@QName: xp.doctype.attr.normalization.2.test
4761     @@@DEnt:
4762     @@@@test:value:
4763     <a at=" at &#xD;value "></a>
4764     @@@test:domTree:
4765     document {
4766     element {
4767     attribute {
4768     value: ' at ' U+000D 'value ';
4769     schema-type-info: TypeInfo (null, null);
4770 wakaba 1.10 specified: true;
4771 wakaba 1.9 }
4772     }
4773     }
4774     @@XMLTest:
4775     @@@QName: xp.doctype.attr.normalization.3.test
4776     @@@DEnt:
4777     @@@@test:value:
4778     <a at=" at &#x9;value "></a>
4779     @@@test:domTree:
4780     document {
4781     element {
4782     attribute {
4783 wakaba 1.10 node-name: 'at';
4784 wakaba 1.9 value: ' at ' U+0009 'value ';
4785     schema-type-info: TypeInfo (null, null);
4786 wakaba 1.10 specified: true;
4787     }
4788     }
4789     }
4790    
4791     @@XMLTest:
4792     @@@QName: xp.doctype.attr.specified.1.test
4793     @@@DEnt:
4794     @@@@test:value:
4795     <!DOCTYPE a [
4796     <!ATTLIST a
4797     at CDATA "default"
4798     >
4799     ]>
4800     <a></a>
4801     @@@test:domTree:
4802     document {
4803     document-type { }
4804     element {
4805     attribute {
4806     node-name: 'at';
4807     value: 'default';
4808     specified: false;
4809     }
4810     }
4811     }
4812     @@XMLTest:
4813     @@@QName: xp.doctype.attr.specified.2.test
4814     @@@DEnt:
4815     @@@@test:value:
4816     <!DOCTYPE a [
4817     <!ATTLIST a
4818     at CDATA "default"
4819     >
4820     ]>
4821     <a at2="specified"></a>
4822     @@@test:domTree:
4823     document {
4824     document-type { }
4825     element {
4826     attribute {
4827     node-name: 'at';
4828     value: 'default';
4829     specified: false;
4830     }
4831     attribute {
4832     node-name: 'at2';
4833     value: 'specified';
4834     specified: true;
4835     }
4836     }
4837     }
4838     @@XMLTest:
4839     @@@QName: xp.doctype.attr.specified.3.test
4840     @@@DEnt:
4841     @@@@test:value:
4842     <!DOCTYPE a [
4843     <!ATTLIST a
4844     at CDATA "default"
4845     >
4846     ]>
4847     <a at="specified"></a>
4848     @@@test:domTree:
4849     document {
4850     document-type { }
4851     element {
4852     attribute {
4853     node-name: 'at';
4854     value: 'specified';
4855     specified: true;
4856 wakaba 1.11 }
4857     }
4858     }
4859    
4860     @@XMLTest:
4861     @@@QName: xp.attr.literal.charref.test
4862     @@@DEnt:
4863     @@@@test:value:
4864     <a at1 = "value&#33;_&#x25;value"
4865     at2 = 'value&#x25;_&#33;value'></a>
4866     @@@test:domTree:
4867     document {
4868     element {
4869     attribute {
4870     node-name: 'at1';
4871     text-content: 'value!_%value';
4872     }
4873     attribute {
4874     node-name: 'at2';
4875     text-content: 'value%_!value';
4876     }
4877     }
4878     }
4879     @@XMLTest:
4880     @@@QName: xp.attr.literal.entref.test
4881     @@@DEnt:
4882     @@@@test:value:
4883     <!DOCTYPE a [
4884     <!ENTITY ent "entity&#x26;#33;_&#x26;#x29;value">
4885     ]>
4886     <a at1 = "value&ent;value"
4887     at2 = 'value&ent;value'></a>
4888     @@@test:domTree:
4889     document {
4890     document-type {
4891     general-entity {
4892     node-name: 'ent';
4893     text-content: 'entity!_)value';
4894     }
4895     }
4896     element {
4897     attribute {
4898     node-name: 'at1';
4899     text-content: 'valueentity!_)valuevalue';
4900     }
4901     attribute {
4902     node-name: 'at2';
4903     text-content: 'valueentity!_)valuevalue';
4904     }
4905     }
4906     }
4907     @@XMLTest:
4908     @@@QName: xp.attr.literal.entref.nest.test
4909     @@@DEnt:
4910     @@@@test:value:
4911     <!DOCTYPE a [
4912     <!ENTITY ent1 "entity&#x26;#33;_&#x26;#x29;value">
4913     <!ENTITY ent2 "@&ent1;@">
4914     ]>
4915     <a at1 = "value&ent2;value"
4916     at2 = 'value&ent2;value'></a>
4917     @@@test:domTree:
4918     document {
4919     document-type {
4920     general-entity {
4921     node-name: 'ent1';
4922     text-content: 'entity!_)value';
4923     }
4924     general-entity {
4925     node-name: 'ent2';
4926     text-content: '@entity!_)value@';
4927     }
4928     }
4929     element {
4930     attribute {
4931     node-name: 'at1';
4932     text-content: 'value@entity!_)value@value';
4933     }
4934     attribute {
4935     node-name: 'at2';
4936     text-content: 'value@entity!_)value@value';
4937 wakaba 1.9 }
4938 wakaba 1.6 }
4939     }
4940    
4941 wakaba 1.5 @@PerlDef:
4942     my $impl = $Message::DOM::ImplementationRegistry->get_implementation ({
4943     'Core' => '3.0',
4944     'XML' => '3.0',
4945     'XMLVersion' => ['1.0', '1.1'],
4946     });
4947     my $parser = <Class::ManakaiXMLParser>->new ($impl);
4948    
4949     for my $test_data (@$TestData) {
4950     $test->start_new_test ($test_data->{uri});
4951     my $doc_ent = $test_data->{entity}->{$test_data->{root_uri}};
4952 wakaba 1.12
4953     $parser->dom_config->set_parameter ('error-handler' => sub ($$) {
4954     my (undef, $err) = @_;
4955     my $err_type = $err->type;
4956     if ($test_data->{dom_error}->{$err_type}) {
4957     $test->assert_error_equals
4958     (actual_value => $err,
4959     expected_hash => pop @{$test_data->{dom_error}
4960     ->{$err_type}});
4961     } else { # Uncatched error
4962     warn $err;
4963     }
4964     return true; # continue as far as possible
4965     });
4966    
4967     if ($test_data->{dom_tree}) { # Successful test
4968     try {
4969     my $doc = $parser->parse_string ($doc_ent->{<H::test:value>});
4970     $test->assert_dom_tree_equals
4971     (actual_value => $doc,
4972     expected_hash => $test_data->{dom_tree});
4973     my $has_error;
4974     for (values %{$test_data->{dom_error}||{}}) {
4975     if (@$_) {
4976     $test->failure_comment
4977     (@$_.' |DOMError|s of type |'.
4978     $_->[0]->{type}.'| are not reported');
4979     $has_error = true;
4980     }
4981     }
4982     $has_error ? $test->not_ok : $test->ok;
4983     } catch Message::Util::IF::DTException with {
4984     #
4985     } catch Message::DOM::IF::LSException with {
4986     $test->assert_never;
4987     };
4988     } else {
4989     try {
4990     my $doc = $parser->parse_string ($doc_ent->{<H::test:value>});
4991     $test->assert_never;
4992     } catch Message::Util::IF::DTException with {
4993     #
4994     } catch Message::DOM::IF::LSException with {
4995     #
4996     };
4997     my $has_error;
4998     for (values %{$test_data->{dom_error}||{}}) {
4999     if (@$_) {
5000     $test->failure_comment
5001     (@$_.' |DOMError|s of type |'.
5002     $_->[0]->{type}.'| are not reported');
5003     $has_error = true;
5004     }
5005     }
5006     $has_error ? $test->not_ok : $test->ok;
5007     }
5008 wakaba 1.5 }
5009 wakaba 1.6
5010     @ResourceDef:
5011     @@QName: getCopyOfEntityState
5012     @@rdf:type: DISPerl|InlineCode
5013     @@ForCheck: ManakaiDOM|ForClass
5014     @@PerlDef:
5015     {%{$self->{$entity_type}->{$entity_name}},
5016     line => 1, column => 1, pos => 0}
5017 wakaba 1.1 ##ManakaiXMLParser
5018 wakaba 1.5
5019     ElementTypeBinding:
5020     @Name: XMLTests
5021     @ElementType:
5022     dis:ResourceDef
5023     @ShadowContent:
5024     @@ForCheck: ManakaiDOM|ForClass
5025     @@rdf:type: test|ParserTestSet
5026    
5027     ElementTypeBinding:
5028     @Name: XMLTest
5029     @ElementType:
5030     dis:ResourceDef
5031     @ShadowContent:
5032     @@ForCheck: ManakaiDOM|ForClass
5033     @@rdf:type: test|ParserTest
5034    
5035     ElementTypeBinding:
5036     @Name: DEnt
5037     @ElementType:
5038     dis:ResourceDef
5039     @ShadowContent:
5040     @@rdf:type: test|RootEntity
5041    
5042     ElementTypeBinding:
5043     @Name: Ent
5044     @ElementType:
5045     dis:ResourceDef
5046     @ShadowContent:
5047     @@rdf:type: test|Entity
5048 wakaba 1.1
5049 wakaba 1.3 ResourceDef:
5050     @QName: xp|get-location-from-token
5051     @rdf:type: DISPerl|BlockCode
5052     @enDesc:
5053     Creates a <IF::DOMCore:DOMLocator> object from a token.
5054     @PerlDef:
5055     $result = {
5056 wakaba 1.6 utf32_offset => $self->{entity}->[-1]->{pos},
5057 wakaba 1.3 };
5058     @For: ManakaiDOM|ManakaiDOM3
5059 wakaba 1.1
5060     ElementTypeBinding:
5061     @Name: RuleDef
5062     @ElementType:
5063     dis:ResourceDef
5064     @ShadowContent:
5065     @@ForCheck: ManakaiDOM|ForClass
5066     @@rdf:type: Muf2003|RuleDefClass
5067    
5068     ElementTypeBinding:
5069     @Name: RuleParam
5070     @ElementType:
5071     dis:ResourceDef
5072     @ShadowContent:
5073     @@rdf:type: Muf2003|RuleParameter
5074    
5075     ElementTypeBinding:
5076     @Name: enImplNote
5077     @ElementType:
5078     dis:ImplNote
5079     @ShadowContent:
5080     @@lang:en
5081    
5082     ElementTypeBinding:
5083     @Name: ErrDef
5084     @ElementType:
5085     dis:ResourceDef
5086     @ShadowContent:
5087     @@rdf:type: DOMCore|DOMErrorType
5088     @@For: ManakaiDOM|DOM3
5089     @@ecore:textFormatter: ManakaiXMLParserExceptionFormatter
5090    
5091 wakaba 1.3 ElementTypeBinding:
5092     @Name: WFErrDef
5093     @ElementType:
5094     dis:ResourceDef
5095     @ShadowContent:
5096     @@rdf:type: DOMCore|DOMErrorType
5097     @@For: ManakaiDOM|DOM3
5098     @@ecore:textFormatter: ManakaiXMLParserExceptionFormatter
5099    
5100     WFErrDef:
5101     @QName: xp|wf-syntax-error
5102     @enDesc:
5103     The entity does not match to the production rule; it is not
5104     well-formed.
5105     @DOMCore:severity: DOMCore|SEVERITY_FATAL_ERROR
5106     @enMufDef:
5107     |%xp-error-token-type;|%xp-error-token-value
5108     (prefix => { (|}, suffix => {|)}); is not
5109     allowed%xp-error-lines (prefix => { (|}, suffix => {|)});
5110     @ecore:hasParameter:
5111     @@@: xp|error-token
5112     @@enDesc:
5113     The token that is not allowed.
5114    
5115     WFErrDef:
5116     @QName: xp|wf-pi-target-is-xml
5117     @enDesc:
5118     A processing instruction has its <CODE::PITarget> of
5119     <XML::xml> (in any case) which is not allowed.
5120     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5121     @enMufDef:
5122     Processing instruction target name cannot be |%p
5123     (name => {<Q::xp|name>});|
5124     @ecore:hasParameter:
5125     @@@: xp|error-token
5126     @@enDesc:
5127     The token that contains the name.
5128     @ecore:hasParameter:
5129     @@@: xp|name
5130     @@enDesc:
5131     A string that is specified as target name of the
5132     processing instruction.
5133     @ecore:hasParameter: xp|parent
5134    
5135     WFErrDef:
5136     @QName: xp|wf-no-end-tag
5137     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5138     @enDesc:
5139     An end-tag is not found.
5140     @enMufDef:
5141     End-tag |</%p (name => {<Q::xp|expected-element-type>});>| is required
5142     @ecore:hasParameter: xp|error-token
5143     @ecore:hasParameter:
5144     @@@: xp|node
5145     @@enDesc:
5146     The element node that is not closed.
5147     @ecore:hasParameter:
5148     @@@: xp|expected-element-type
5149     @@enDesc:
5150     The element type name of the element that is not closed.
5151    
5152     WFErrDef:
5153     @QName: xp|wf-unsupported-xml-version
5154     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5155     @enDesc:
5156     The XML version specified in the version declaration is not supported.
5157     @enMufDef:
5158     XML version |%p (name => {<Q::infoset|version>});| is not supported
5159     @ecore:hasParameter: xp|bad-token
5160     @ecore:hasParameter:
5161     @@@: xp|parent
5162     @@enDesc:
5163     The document node.
5164     @ecore:hasParameter:
5165     @@@: infoset|version
5166     @@enDesc:
5167     The specified XML version.
5168    
5169     WFErrDef:
5170     @QName: xp|wf-malformed-enc-name
5171     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5172     @enDesc:
5173     An <XA::encoding> pseudo-attribute value does not match
5174     to the procduction rule <CODE::EncName>.
5175     @enMufDef:
5176     Encoding name |%p (name => {<Q::xp|name>});| is not allowed
5177     @ecore:hasParameter: xp|error-token
5178     @ecore:hasParameter:
5179     @@@: xp|parent
5180     @@enDesc: The document node.
5181     @ecore:hasParameter:
5182     @@@: xp|name
5183     @@enDesc:
5184     The <XA::encoding> value.
5185    
5186     WFErrDef:
5187     @QName: xp|wf-malformed-xml-standalone
5188     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5189     @enDesc:
5190     An <XA::standalone> pseudo-attribute value is neither <XML::yes>
5191     or <XML::no>.
5192     @enMufDef:
5193     |standalone| pseudo-attribute value |%p (name => {<Q::xp|name>});|
5194     is not allowed
5195     @ecore:hasParameter: xp|error-token
5196     @ecore:hasParameter:
5197     @@@: xp|parent
5198     @@enDesc: The document node.
5199     @ecore:hasParameter:
5200     @@@: xp|name
5201     @@enDesc:
5202     The <XA::standalone> value.
5203    
5204     WFErrDef:
5205     @QName: xp|wf-legal-literal-character
5206     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5207     @enDesc:
5208     Each character in XML entity must match to the production
5209     rule <CODE::Char - RestrictedChar>.
5210     @enMufDef:
5211     Character %character-code-point
5212     (v => {<Q::xp|character-number>}); is not allowed
5213     @ecore:hasParameter:
5214     @@@: xp|character-number
5215     @@enDesc:
5216     The code position of the character being referred.
5217    
5218     WFErrDef:
5219     @QName: xp|wf-element-type-match
5220     @DOMCore:severity: DOMCore|SEVERITY_FATAL_ERROR
5221 wakaba 1.1 @enDesc:
5222 wakaba 1.3 The <CODE::Name> in an element's end-tag must match the element type
5223     in the start-tag.
5224     @enMufDef:
5225     End-tag |</%p (name => {<Q::xp|actual-element-type>});>| does
5226     not match to start-tag |<%p (name => {<Q::xp|expected-element-type>});>|
5227     @ecore:hasParameter: xp|error-token
5228     @ecore:hasParameter:
5229     @@@: xp|node
5230     @@enDesc:
5231     The current opening element node.
5232     @ecore:hasParameter:
5233     @@@: xp|expected-element-type
5234     @@enDesc:
5235     The element type name of the current element.
5236     @ecore:hasParameter:
5237     @@@: xp|actual-element-type
5238     @@enDesc:
5239     The <CODE::Name> occurs in the end-tag.
5240    
5241     WFErrDef:
5242     @QName: xp|wf-unique-att-spec
5243 wakaba 1.1 @DOMCore:severity: DOMCore|SEVERITY_ERROR
5244 wakaba 1.3 @enDesc:
5245     An attribute name <kwd:MUST-NOT> appear more than once in
5246     the same start-tag or empty-element tag.
5247 wakaba 1.1 @enMufDef:
5248 wakaba 1.3 Attribute |%p (name => {<Q::xp|name>});| is specified more
5249     than once in the same tag
5250     @ecore:hasParameter: xp|error-token
5251     @ecore:hasParameter:
5252     @@@: xp|name
5253     @@enDesc:
5254     The name of the attribute.
5255    
5256     WFErrDef:
5257     @QName: xp|wf-legal-character
5258     @DOMCore:severity: DOMCore|SEVERITY_ERROR
5259     @enDesc:
5260     Characters referred to using character references <kwd:MUST>
5261     match the production for <CODE::Char>.
5262     @enMufDef:
5263     Reference to character %character-code-point
5264     (v => {<Q::xp|character-number>}); is not allowed
5265     @ecore:hasParameter: xp|error-token
5266     @ecore:hasParameter:
5267     @@@: xp|character-number
5268     @@enDesc:
5269     The code position of the character being referred.
5270     @ecore:hasParameter:
5271     @@@: xp|parent
5272     @@enDesc:
5273     The parent node in which the character reference has
5274     occurred, if available.
5275 wakaba 1.1
5276 wakaba 1.3 XWParam:
5277 wakaba 1.1 @QName: xp|error-token
5278     @enDesc:
5279     The token where the parser found an error.
5280    
5281 wakaba 1.3 XWParam:
5282     @QName: xp|name
5283     @enDesc:
5284     A name.
5285    
5286     XWParam:
5287     @QName: xp|parent
5288     @enDesc:
5289     The parent node in which the error occurs.
5290    
5291     XWParam:
5292     @QName: xp|node
5293     @enDesc:
5294     The current node.
5295    
5296     XWParam:
5297     @QName: xp|actual-element-type
5298     @enDesc:
5299     The actual element type name occured in the source.
5300    
5301     XWParam:
5302     @QName: xp|expected-element-type
5303 wakaba 1.1 @enDesc:
5304 wakaba 1.3 The element type name expected.
5305    
5306     XWParam:
5307     @QName: xp|character-number
5308     @enDesc:
5309     The character code position.
5310    
5311     ElementTypeBinding:
5312     @Name: XWParam
5313     @ElementType:
5314     dis:ResourceDef
5315     @ShadowContent:
5316     @@For: =ManakaiDOM|all
5317     @@rdf:type: ecore|Parameter
5318 wakaba 1.1
5319     ElementTypeBinding:
5320     @Name:enMufDef
5321     @ElementType:
5322     ecore:defaultMessage
5323     @ShadowContent:
5324     @@lang:en
5325     @@ContentType:
5326     lang:muf
5327    
5328     ResourceDef:
5329     @QName: DOMImpl
5330     @AliasFor: DOMCore|DOMImplementation
5331     @For: ManakaiDOM|DOM
5332    
5333     ElementTypeBinding:
5334     @Name: Attr
5335     @ElementType:
5336     dis:ResourceDef
5337     @ShadowContent:
5338     @@rdf:type: DISLang|Attribute
5339     @@ForCheck: !=ManakaiDOM|ManakaiDOM
5340    
5341     ElementTypeBinding:
5342     @Name: Get
5343     @ElementType:
5344     dis:ResourceDef
5345     @ShadowContent:
5346     @@rdf:type: DISLang|AttributeGet
5347    
5348     ElementTypeBinding:
5349     @Name: Set
5350     @ElementType:
5351     dis:ResourceDef
5352     @ShadowContent:
5353     @@rdf:type: DISLang|AttributeSet
5354    
5355     ElementTypeBinding:
5356     @Name: enDesc
5357     @ElementType:
5358     dis:Description
5359     @ShadowContent:
5360     @@lang:en
5361    
5362     ElementTypeBinding:
5363     @Name: Method
5364     @ElementType:
5365     dis:ResourceDef
5366     @ShadowContent:
5367     @@rdf:type: DISLang|Method
5368     @@For: !=ManakaiDOM|ManakaiDOM
5369    
5370     ElementTypeBinding:
5371     @Name: Return
5372     @ElementType:
5373     dis:ResourceDef
5374     @ShadowContent:
5375     @@rdf:type: DISLang|MethodReturn
5376    
5377     ElementTypeBinding:
5378     @Name: Param
5379     @ElementType:
5380     dis:ResourceDef
5381     @ShadowContent:
5382     @@rdf:type: DISLang|MethodParameter
5383    
5384     ElementTypeBinding:
5385     @Name: PerlDef
5386     @ElementType:
5387     dis:Def
5388     @ShadowContent:
5389     @@ContentType: lang|Perl
5390    
5391     ElementTypeBinding:
5392     @Name: PropDef
5393     @ElementType:
5394     dis:ResourceDef
5395     @ShadowContent:
5396     @@rdf:type: rdf|Property
5397    
5398     ClsDef:
5399     @ClsQName: ManakaiXMLParserExceptionFormatter
5400    
5401     @ClsISA: ecore|MUErrorFormatter||ManakaiDOM|Perl
5402    
5403     @RuleDef:
5404     @@Name: xp-error-token-type
5405     @@enDesc:
5406     The type of the token the parser is encountered.
5407    
5408     @@Method:
5409     @@@Name: after
5410     @@@Param:
5411     @@@@Name: name
5412     @@@@Type: DOMString
5413     @@@@enDesc: The name of the method.
5414     @@@Param:
5415     @@@@Name: p
5416     @@@@Type: DISPerl|HASH
5417     @@@@enDesc: The set of the parameters to the method.
5418     @@@Param:
5419     @@@@Name: o
5420     @@@@Type: DISPerl|HASH
5421     @@@@enDesc: The option value.
5422     @@@Return:
5423     @@@@PerlDef:
5424     $p->{-result} = $o->{<H::xp|error-token>}->{type}
5425     if defined $o->{<H::xp|error-token>}->{type};
5426    
5427     @RuleDef:
5428     @@Name: xp-error-token-value
5429     @@enDesc:
5430     The value of the token the parser is encountered, if any.
5431    
5432     @@Method:
5433     @@@Name: after
5434     @@@Param:
5435     @@@@Name: name
5436     @@@@Type: DOMString
5437     @@@@enDesc: The name of the method.
5438     @@@Param:
5439     @@@@Name: p
5440     @@@@Type: DISPerl|HASH
5441     @@@@enDesc: The set of the parameters to the method.
5442     @@@Param:
5443     @@@@Name: o
5444     @@@@Type: DISPerl|HASH
5445     @@@@enDesc: The option value.
5446     @@@Return:
5447     @@@@PerlDef:
5448     $p->{-result} = $o->{<H::xp|error-token>}->{value}
5449     if defined $o->{<H::xp|error-token>}->{value};
5450    
5451     @RuleDef:
5452     @@Name: xp-error-lines
5453     @@enDesc:
5454     A copy of fragment of the source text that contains the line
5455     where the error occurred, if available.
5456    
5457     @@Method:
5458     @@@Name: after
5459     @@@Param:
5460     @@@@Name: name
5461     @@@@Type: DOMString
5462     @@@@enDesc: The name of the method.
5463     @@@Param:
5464     @@@@Name: p
5465     @@@@Type: DISPerl|HASH
5466     @@@@enDesc: The set of the parameters to the method.
5467     @@@Param:
5468     @@@@Name: o
5469     @@@@Type: DISPerl|HASH
5470     @@@@enDesc: The option value.
5471     @@@Return:
5472     @@@@PerlDef:
5473     my $pos = $o-><AG::DOMCore|DOMError.location>
5474     -><AG::DOMCore|DOMLocator.utf32Offset>;
5475     if ($pos > -1) {
5476 wakaba 1.6 my $src = $o->{<H::ecore|object>}->{entity}->[-1]->{reptxt};
5477 wakaba 1.1 my $start = $pos;
5478     $start = rindex ($$src, "\x0A", $start - 1) for 0..2;
5479     $start++;
5480     my $end = $pos;
5481     $end = index ($$src, "\x0A", $end + 1) for 0..2;
5482     $end = length $$src if $end < 0;
5483     $p->{-result} = substr $$src, $start, $end - $start;
5484     }
5485 wakaba 1.3
5486     @RuleDef:
5487     @@Name: character-code-point
5488     @@enDesc:
5489     The character code position, in <CODE::U+<VAR::HHHH>> notation.
5490    
5491     @@Method:
5492     @@@Name: after
5493     @@@Param:
5494     @@@@Name: name
5495     @@@@Type: DOMString
5496     @@@@enDesc: The name of the method.
5497     @@@Param:
5498     @@@@Name: p
5499     @@@@Type: DISPerl|HASH
5500     @@@@enDesc: The set of the parameters to the method.
5501     @@@Param:
5502     @@@@Name: o
5503     @@@@Type: DISPerl|HASH
5504     @@@@enDesc: The option value.
5505     @@@RuleParam:
5506     @@@@Name: v
5507     @@@@Type: DISPerl|Number
5508     @@@@enDesc:
5509     The name of the error parameter that contains the character code.
5510     @@@Return:
5511     @@@@PerlDef:
5512     $p->{-result} = sprintf 'U+%04X', $o->{$p->{v}};
5513 wakaba 1.1 ##XMLParserExceptionFormatter

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24