2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng.Rnc / RncParser.jay
1 %{
2 //
3 // RELAX NG Compact Syntax parser
4 //
5 // Author:
6 //      Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 //
8 // (C)2003 Atsushi Enomoto
9 //
10 // Copyright (c) 2004 Novell Inc.
11 // All rights reserved
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Collections;
37 using System.Collections.Specialized;
38 using System.IO;
39 using System.Xml;
40 using Commons.Xml.Relaxng;
41
42 namespace Commons.Xml.Relaxng.Rnc
43 {
44
45         public class RncParser
46         {
47                 public static RelaxngPattern ParseRnc (TextReader reader)
48                 {
49                         return ParseRnc (reader, new NameTable ());
50                 }
51
52                 public static RelaxngPattern ParseRnc (TextReader reader, XmlNameTable nameTable)
53                 {
54                         return new RncParser (nameTable).Parse (reader);
55                 }
56
57                 XmlNamespaceManager nsmgr;
58                 XmlNamespaceManager dtnsmgr;
59                 string defaultNamespace = String.Empty;
60                 static int yacc_verbose_flag;
61
62                 RncTokenizer tokenizer;
63
64                 public RncParser (XmlNameTable nameTable)
65                 {
66                         nsmgr = new XmlNamespaceManager (nameTable);
67                         dtnsmgr = new XmlNamespaceManager (nameTable);
68                         ErrorOutput = System.IO.TextWriter.Null;
69                 }
70
71                 public int Line {
72                         get { return tokenizer.Line; }
73                 }
74
75                 public int Column {
76                         get { return tokenizer.Column; }
77                 }
78
79                 // note that this is different notion than that of xmlns.
80                 public string DefaultNamespace {
81                         get { return defaultNamespace; }
82                 }
83
84                 public RelaxngPattern Parse (TextReader source)
85                 {
86                         try {
87 //                              debug = new yydebug.yyDebugSimple ();
88                                 tokenizer = new RncTokenizer (source);
89                                 return (RelaxngPattern) yyparse (tokenizer);
90                         } catch (Exception ex) {\r
91                                 throw new RelaxngException (String.Format ("Tokenizer error at line {0}, column {1}: {2}", Line, Column, ex.Message), ex);\r
92                         }\r
93                 }
94
95
96                 private void FillGrammarContent (IList source, IList starts, IList defines, IList divs, IList includes)
97                 {
98                         foreach (RelaxngElementBase elem in source) {
99                                 if (elem is RelaxngStart)
100                                         starts.Add (elem);
101                                 else if (elem is RelaxngDefine)
102                                         defines.Add (elem);
103                                 else if (elem is RelaxngDiv)
104                                         divs.Add (elem);
105                                 else if (elem is RelaxngInclude)
106                                         includes.Add (elem);
107                                 else
108                                         throw new InvalidOperationException ();
109                         }
110                 }
111
112                 private XmlQualifiedName SplitQName (XmlNamespaceManager nsmgr, string name)
113                 {
114                         int colon = name.IndexOf (':');
115                         if (colon < 0)
116                                 return new XmlQualifiedName (name, String.Empty);
117                         string local = name.Substring (colon + 1);
118                         string prefix = name.Substring (0, colon);
119                         return new XmlQualifiedName (local, nsmgr.LookupNamespace (nsmgr.NameTable.Get (prefix)));
120                 }
121
122                 private void FillElementDefaultNS (RelaxngNameClass nc)
123                 {
124                         RelaxngName name = nc as RelaxngName;
125                         if (name != null) {
126                                 if (name.Namespace == null)
127                                         name.Namespace = this.DefaultNamespace;
128                                 return;
129                         }
130                         RelaxngNameChoice choice = nc as RelaxngNameChoice;
131                         if (choice != null) {
132                                 foreach (RelaxngNameClass c in choice.Children)
133                                         FillElementDefaultNS (c);
134                         }
135                 }
136
137                 private void FillAttributeDefaultNS (RelaxngNameClass nc)
138                 {
139                         RelaxngName name = nc as RelaxngName;
140                         if (name != null) {
141                                 if (name.Namespace == null)
142                                         name.Namespace = String.Empty;
143                                 return;
144                         }
145                         RelaxngNameChoice choice = nc as RelaxngNameChoice;
146                         if (choice != null) {
147                                 foreach (RelaxngNameClass c in choice.Children)
148                                         FillAttributeDefaultNS (c);
149                         }
150                 }
151
152 %}
153
154 %token ERROR
155 %token EOF
156
157 %token KeywordAttribute "attribute"
158 %token KeywordDefault //"default"
159 %token KeywordDatatypes "datatypes"
160 %token KeywordDiv "div"
161 %token KeywordElement "element"
162 %token KeywordEmpty "empty"
163 %token KeywordExternal "external"
164 %token KeywordGrammar "grammar"
165 %token KeywordInclude "include"
166 %token KeywordInherit "inherit"
167 %token KeywordList "list"
168 %token KeywordMixed "mixed"
169 %token KeywordNamespace //"namespace"
170 %token KeywordNotAllowed "notAllowed"
171 %token KeywordParent "parent"
172 %token KeywordStart "start"
173 %token KeywordString //"string"
174 %token KeywordText "text"
175 %token KeywordToken "left"
176
177 %token Equal "="
178 %token Comma ","
179 %token Tilde "~"
180 %token OpenCurly "{"
181 %token CloseCurly "}"
182 %token OpenParen "("
183 %token CloseParen ")"
184 %token OpenBracket "["
185 %token CloseBracket "]"
186 %token Amp "&"
187 %token Bar "|"
188 %token Question "?"
189 %token Asterisk "*"
190 %token BackSlash "\\"
191 %token Plus "+"
192 %token Minus "-"
193 %token OrEquals "|="
194 %token AndEquals "&="
195 %token TwoGreaters ">>"
196
197 %token LiteralSegment
198 %token NCNameButKeyword
199
200 %token Documentation
201
202 /* These tokens are parsed by RncTokenizer, since whitespaces between 
203    the particles are not allowed. */
204 %token NCName
205 %token CName
206 %token NsName
207
208 %start TopLevel
209
210 %%
211
212
213 TopLevel /* returns RelaxngPattern */
214         /* TODO: here Annotations is not specified in the spec!! */
215         : Annotations TopLevelAfterAnnotations 
216         {
217                 $$ = (RelaxngPattern) $2;
218         }
219         ;
220
221 TopLevelAfterAnnotations /* returns RelaxngPattern */
222         /* TODO: here Annotations is not specified in the spec!! */
223         : Preamble TopLevelBody
224         {
225                 $$ = (RelaxngPattern) $2;
226         }
227         ;
228
229 Preamble /* returns null */
230         : /* empty */
231         {
232                 $$ = null;
233         }
234         | Decl Preamble
235         {
236                 $$ = null;
237         }
238         ;
239
240 Decl /* returns null */
241         : KeywordNamespace NamespacePrefix Equal NamespaceURILiteral
242         {
243                 // TODO: constraints
244                 string prefix = (string) $2;
245                 string ns = (string) $4;
246                 if (prefix == "local")
247                         nsmgr.AddNamespace (String.Empty, ns);
248                 else
249                         nsmgr.AddNamespace (prefix, ns);
250                 $$ = null;
251         }
252         | KeywordDefault KeywordNamespace Equal NamespaceURILiteral
253         {
254                 // TODO: constraints
255                 string ns = (string) $4;
256                 defaultNamespace = ns;
257                 $$ = null;
258         }
259         | KeywordDefault KeywordNamespace NamespacePrefix Equal NamespaceURILiteral
260         {
261                 // TODO: constraints
262                 string prefix = (string) $3;
263                 string ns = (string) $5;
264                 defaultNamespace = ns;
265                 nsmgr.AddNamespace (prefix, ns);
266                 $$ = null;
267         }
268         | KeywordDatatypes DatatypePrefix Equal Literal
269         {
270                 // TODO: constraints
271                 string prefix = (string) $2;
272                 string ns = (string) $4;
273                 dtnsmgr.AddNamespace (prefix, ns);
274                 $$ = null;
275         }
276         ;
277
278 NamespacePrefix /* returns string */
279         : IdentifierOrKeyword
280         {
281                 $$ = (string) $1;
282         }
283         ;
284
285 DatatypePrefix /* returns string */
286         : IdentifierOrKeyword
287         {
288                 $$ = (string) $1;
289         }
290         ;
291
292 NamespaceURILiteral /* returns string */
293         : Literal
294         {
295                 $$ = (string) $1;
296         }
297         | KeywordInherit
298         {
299                 $$ = (string) $1;
300         }
301         ;
302
303 TopLevelBody /* returns RelaxngPattern */
304         : Pattern
305         {
306                 // TODO: Constraint: single element
307 //              IList pl = (IList) $1;
308 //              if (pl.Count != 1)
309 //                      throw new RelaxngException ("The number of the top level pattern must be exactly one.");
310 //              $$ = pl [0];
311                 $$ = (RelaxngPattern) $1;
312         }
313         | Grammar
314         {
315                 RelaxngGrammar g = new RelaxngGrammar ();
316                 RelaxngGrammarContentList list = (RelaxngGrammarContentList) $1;
317                 FillGrammarContent (list, g.Starts, g.Defines, g.Divs, g.Includes);
318                 $$ = g;
319         }
320         ;
321
322 Grammar /* returns RelaxngGrammarContentList */
323         : /* empty */
324         {
325                 $$ = new RelaxngGrammarContentList ();
326         }
327         | Member Grammar
328         {
329                 RelaxngGrammarContentList al = (RelaxngGrammarContentList) $2;
330                 if ($1 != null)
331                         al.Insert (0, (IGrammarContent) $1);
332                 $$ = al;
333         }
334         ;
335
336 Member /* returns nullable IGrammarContent (RelaxngDiv, RelaxngInclude, RelaxngStart, RelaxngDiv) */
337         : AnnotatedComponent
338         {
339                 $$ = (IGrammarContent) $1;
340         }
341         | AnnotationElementNotKeyword
342         {
343                 $$ = null;
344         }
345         ;
346
347 AnnotatedComponent /* returns IGrammarContent */
348         : Annotations Component
349         {
350 //              $$ = ApplyAnnotations ((string) $1, (RelaxngElementBase) $2);
351                 $$ = (IGrammarContent) $2;
352         }
353         ;
354
355 Component /* returns IGrammarContent */
356         : Start
357         {
358                 $$ = (RelaxngStart) $1;
359         }
360         | Define
361         {
362                 $$ = (RelaxngDefine) $1;
363         }
364         | Include
365         {
366                 $$ = (RelaxngInclude) $1;
367         }
368         | Div
369         {
370                 $$ = (RelaxngDiv) $1;
371         }
372         ;
373
374 Start /* returns RelaxngStart */
375         : KeywordStart AssignOp Pattern
376         {
377                 RelaxngStart start = new RelaxngStart ();
378                 start.Combine = (string) $2;
379                 start.Pattern = (RelaxngPattern) $3;
380                 $$ = start;
381         }
382         ;
383
384 Define /* returns RelaxngDefine */
385         : Identifier AssignOp Pattern
386         {
387                 RelaxngDefine def = new RelaxngDefine ();
388                 def.Name = (string) $1;
389                 def.Combine = (string) $2;
390                 def.Patterns.Add ((RelaxngPattern) $3);
391                 $$ = def;
392         }
393         ;
394
395 AssignOp /* returns string */
396         : Equal
397         {
398                 $$ = null;
399         }
400         | OrEquals
401         {
402                 $$ = "choice";
403         }
404         | AndEquals
405         {
406                 $$ = "interleave";
407         }
408         ;
409
410 Include /* returns RelaxngInclude */
411         : KeywordInclude AnyURILiteral OptInherit OptIncludeBody
412         {
413                 // FIXME: OptInherit is not handled properly.
414                 RelaxngInclude include = new RelaxngInclude ();
415                 include.Href = (string) $2;
416                 include.NSContext = (string) $3;
417                 FillGrammarContent ((IList) $4, include.Starts, include.Defines, include.Divs, null);
418                 $$ = include;
419         }
420         ;
421
422 AnyURILiteral /* returns string */
423         : Literal
424         {
425                 // Constraints: any URI
426                 $$ = (string) $1;
427         }
428         ;
429
430 OptInherit /* returns string */
431         /* FIXME: It is not handled properly. */
432         : /* empty */
433         {
434                 // MakeNsAttribute (LookupDefault (environment));
435                 $$ = nsmgr.DefaultNamespace;
436         }
437         | KeywordInherit Equal IdentifierOrKeyword
438         {
439                 // MakeNsAttribute (LookupPrefix (environment, $3));
440                 $$ = nsmgr.LookupPrefix ((string) $3);
441         }
442         ;
443
444 OptIncludeBody /* returns IList */
445         : /* empty */
446         {
447                 $$ = new ArrayList ();
448         }
449         | OpenCurly IncludeBody CloseCurly
450         {
451                 $$ = (IList) $2;
452         }
453         ;
454
455 IncludeBody /* returns IList */
456         : /* empty */
457         {
458                 $$ = new ArrayList ();
459         }
460         | IncludeMember IncludeBody
461         {
462                 ArrayList al = (ArrayList) $2;
463                 al.Insert (0, $1);
464                 $$ = al;
465         }
466         ;
467
468 IncludeMember /* returns RelaxngElementBase */
469         : AnnotatedIncludeComponent
470         {
471                 $$ = (RelaxngElementBase) $1;
472         }
473         | AnnotationElementNotKeyword
474         {
475                 $$ = (RelaxngElementBase) $1;
476         }
477         ;
478
479 AnnotatedIncludeComponent /* returns IGrammarContent */
480         : Annotations IncludeComponent
481         {
482 //              $$ = ApplyAnnotations ((string) $1, (RelaxngElementBase) $2);
483                 $$ = (IGrammarContent) $2;
484         }
485         ;
486
487 IncludeComponent /* returns IGrammarContent */
488         : Start
489         {
490                 $$ = (RelaxngStart) $1;
491         }
492         | Define
493         {
494                 $$ = (RelaxngDefine) $1;
495         }
496         | IncludeDiv
497         {
498                 $$ = (RelaxngDiv) $1;
499         }
500         ;
501
502 Div /* returns RelaxngDiv */
503         : KeywordDiv OpenCurly Grammar CloseCurly
504         {
505                 RelaxngDiv div = new RelaxngDiv ();
506                 FillGrammarContent ((IList) $3, div.Starts, div.Defines, div.Divs, div.Includes);
507                 $$ = div;
508         }
509         ;
510
511 IncludeDiv /* returns RelaxngDiv */
512         : KeywordDiv OpenCurly IncludeBody CloseCurly
513         {
514                 RelaxngDiv div = new RelaxngDiv ();
515                 FillGrammarContent ((IList) $3, div.Starts, div.Defines, div.Divs, div.Includes);
516                 $$ = div;
517         }
518         ;
519
520 Pattern /* returns RelaxngPattern */
521         : InnerPattern
522         ;
523
524 InnerPattern /* returns RelaxngPattern */
525         /* TODO: applyAnnotations() are omitted */
526         : InnerParticle
527         {
528                 $$ = (RelaxngPattern) $1;
529         }
530         | ParticleChoice
531         {
532                 RelaxngPatternList list = (RelaxngPatternList) $1;
533                 RelaxngChoice choice = new RelaxngChoice ();
534                 for (int i = 0; i < list.Count; i++)
535                         choice.Patterns.Add (list [i]);
536                 // This is said as to return Elements, while ApplyAnnotations() is said to return Element
537                 $$ = choice;
538         }
539         | ParticleGroup
540         {
541                 RelaxngPatternList list = (RelaxngPatternList) $1;
542                 RelaxngGroup group = new RelaxngGroup ();
543                 for (int i = 0; i < list.Count; i++)
544                         group.Patterns.Add (list [i]);
545                 // This is said as to return Elements, while ApplyAnnotations() is said to return Element
546                 $$ = group;
547         }
548         | ParticleInterleave
549         {
550                 RelaxngPatternList list = (RelaxngPatternList) $1;
551                 RelaxngInterleave interleave = new RelaxngInterleave ();
552                 for (int i = 0; i < list.Count; i++)
553                         interleave.Patterns.Add (list [i]);
554                 // This is said as to return Elements, while ApplyAnnotations() is said to return Element
555                 $$ = interleave;
556         }
557         | AnnotatedDataExcept
558         {
559                 $$ = (RelaxngData) $1;
560         }
561         ;
562
563 ParticleChoice /* returns RelaxngPatternList */
564         : Particle Bar Particle
565         {
566                 RelaxngPatternList list = new RelaxngPatternList ();
567                 list.Add ((RelaxngPattern) $1);
568                 list.Add ((RelaxngPattern) $3);
569                 $$ = list;
570         }
571         | Particle Bar ParticleChoice
572         {
573                 RelaxngPatternList list = (RelaxngPatternList) $3;
574                 list.Insert (0, (RelaxngPattern) $1);
575                 $$ = list;
576         }
577         ;
578
579 ParticleGroup /* returns RelaxngPatternList */
580         : Particle Comma Particle
581         {
582                 RelaxngPatternList list = new RelaxngPatternList ();
583                 list.Add ((RelaxngPattern) $1);
584                 list.Add ((RelaxngPattern) $3);
585                 $$ = list;
586         }
587         | Particle Comma ParticleGroup
588         {
589                 RelaxngPatternList list = (RelaxngPatternList) $3;
590                 list.Insert (0, (RelaxngPattern) $1);
591                 $$ = list;
592         }
593         ;
594
595 ParticleInterleave /* returns RelaxngPatternList */
596         : Particle Amp Particle
597         {
598                 RelaxngPatternList list = new RelaxngPatternList ();
599                 list.Add ((RelaxngPattern) $1);
600                 list.Add ((RelaxngPattern) $3);
601                 $$ = list;
602         }
603         | Particle Amp ParticleInterleave
604         {
605                 RelaxngPatternList list = (RelaxngPatternList) $3;
606                 list.Insert (0, (RelaxngPattern) $1);
607                 $$ = list;
608         }
609         ;
610
611 Particle /* returns RelaxngPattern */
612         : InnerParticle
613         ;
614
615 InnerParticle /* returns RelaxngPattern */
616         : AnnotatedPrimary
617         {
618 //              $$ = ApplyAnnotationsGroup (null, (RelaxngPatternList) $1);
619                 $$ = $1;
620         }
621         | RepeatedPrimary FollowAnnotations
622         {
623                 // FIXME: annotations are not handled
624                 RelaxngPattern p = (RelaxngPattern) $1;
625 //              RelaxngPatternList l = new RelaxngPatternList ();
626 //              l.Add (p);
627 //              $$ = l;
628                 $$ = p;
629         }
630         ;
631
632 RepeatedPrimary /* returns RelaxngPattern */
633         : AnnotatedPrimary Asterisk
634         {
635                 RelaxngZeroOrMore zom = new RelaxngZeroOrMore ();
636 //              foreach (RelaxngPattern p in (ICollection) $1)
637 //                      zom.Patterns.Add (p);
638                 zom.Patterns.Add ((RelaxngPattern) $1);
639                 $$ = zom;
640         }
641         | AnnotatedPrimary Plus
642         {
643                 RelaxngOneOrMore oom = new RelaxngOneOrMore ();
644 //              foreach (RelaxngPattern p in (ICollection) $1)
645 //                      oom.Patterns.Add (p);
646                 oom.Patterns.Add ((RelaxngPattern) $1);
647                 $$ = oom;
648         }
649         | AnnotatedPrimary Question
650         {
651                 RelaxngOptional opt = new RelaxngOptional ();
652 //              foreach (RelaxngPattern p in (ICollection) $1)
653 //                      opt.Patterns.Add (p);
654                 opt.Patterns.Add ((RelaxngPattern) $1);
655                 $$ = opt;
656         }
657         ;
658
659 AnnotatedPrimary /* returns RelaxngPattern */
660         : LeadAnnotatedPrimary FollowAnnotations
661         {
662                 // FIXME: handle followAnnotations
663                 $$ = $1;
664         }
665         ;
666
667 AnnotatedDataExcept /* returns RelaxngPatternList */
668         : LeadAnnotatedDataExcept FollowAnnotations
669         {
670                 // FIXME: handle followAnnotations
671                 RelaxngData p = (RelaxngData) $1;
672                 RelaxngPatternList l = new RelaxngPatternList ();
673                 l.Add (p);
674                 $$ = l;
675         }
676         ;
677
678 LeadAnnotatedDataExcept /* returns RelaxngData */
679         : Annotations DataExcept
680         {
681                 $$ = $2;
682         }
683         ;
684
685 LeadAnnotatedPrimary /* returns RelaxngPattern */
686         : Annotations Primary
687         {
688                 // LAMESPEC: This should return Elements, while ApplyAnnotations() returns Element
689 //              RelaxngPatternList list = new RelaxngPatternList ();
690 //              list.Add ((RelaxngPattern) ApplyAnnotations ((string) $1, (RelaxngPattern) $2));
691 //              $$ = list;
692                 $$ = (RelaxngPattern) $2;
693         }
694         | Annotations OpenParen InnerPattern CloseParen
695         {
696 //              $$ = (RelaxngPatternList) $3;
697                 $$ = (RelaxngPattern) $3;
698         }
699         ;
700
701 Primary /* returns RelaxngPattern */
702         : KeywordElement NameClass OpenCurly Pattern CloseCurly
703         {
704                 RelaxngNameClass nc = (RelaxngNameClass) $2;
705                 RelaxngElement el = new RelaxngElement ();
706                 el.NameClass = nc;
707                 FillElementDefaultNS (el.NameClass);
708
709 //              foreach (RelaxngPattern p in (RelaxngPatternList) $4)
710 //                      el.Patterns.Add (p);
711                 el.Patterns.Add ((RelaxngPattern) $4);
712                 $$ = el;
713         }
714         | KeywordAttribute NameClass OpenCurly Pattern CloseCurly
715         {
716                 RelaxngNameClass nc = (RelaxngNameClass) $2;
717
718                 RelaxngAttribute attr = new RelaxngAttribute ();
719                 attr.NameClass = nc;
720                 FillAttributeDefaultNS (attr.NameClass);
721                 attr.Pattern = (RelaxngPattern) $4;
722                 $$ = attr;
723         }
724         | KeywordMixed OpenCurly Pattern CloseCurly
725         {
726                 RelaxngMixed mixed = new RelaxngMixed ();
727                 foreach (RelaxngPattern p in (RelaxngPatternList) $3)
728                         mixed.Patterns.Add (p);
729                 $$ = mixed;
730         }
731         | KeywordList OpenCurly Pattern CloseCurly
732         {
733                 RelaxngList list = new RelaxngList ();
734                 foreach (RelaxngPattern p in (RelaxngPatternList) $3)
735                         list.Patterns.Add (p);
736                 $$ = list;
737         }
738         | DatatypeName OptParams
739         {
740                 RelaxngData data = new RelaxngData ();
741                 XmlQualifiedName dtName = (XmlQualifiedName) $1;
742                 data.DatatypeLibrary = dtName.Namespace;
743                 data.Type = dtName.Name;
744                 foreach (RelaxngParam p in (ICollection) $2)
745                         data.ParamList.Add (p);
746
747                 $$ = data;
748         }
749         | DatatypeName DatatypeValue
750         {
751                 RelaxngValue value = new RelaxngValue ();
752                 XmlQualifiedName dtName = (XmlQualifiedName) $1;
753                 if (dtName.Namespace != RelaxngGrammar.NamespaceURI)
754                         value.DatatypeLibrary = dtName.Namespace;
755                 value.Type = dtName.Name;
756                 value.Value = (string) $2;
757
758                 $$ = value;
759         }
760         | DatatypeValue
761         {
762                 RelaxngValue value = new RelaxngValue ();
763                 value.Value = (string) $1;
764
765                 // RELAX NG default type
766                 value.Type = "string";
767                 value.DatatypeLibrary = String.Empty;
768
769                 $$ = value;
770         }
771         | KeywordEmpty
772         {
773                 $$ = new RelaxngEmpty ();
774         }
775         | KeywordNotAllowed
776         {
777                 $$ = new RelaxngNotAllowed ();
778         }
779         | KeywordText
780         {
781                 $$ = new RelaxngText ();
782         }
783         | Ref
784         {
785                 RelaxngRef r = new RelaxngRef ();
786                 r.Name = (string) $1;
787                 $$ = r;
788         }
789         | KeywordParent Ref
790         {
791                 RelaxngParentRef pref = new RelaxngParentRef ();
792                 pref.Name = (string) $2;
793                 $$ = pref;
794         }
795         | KeywordGrammar OpenCurly Grammar CloseCurly
796         {
797                 RelaxngGrammar g = new RelaxngGrammar ();
798                 FillGrammarContent ((IList) $3, g.Starts, g.Defines, g.Divs, g.Includes);
799                 $$ = g;
800         }
801         | KeywordExternal AnyURILiteral OptInherit
802         {
803                 RelaxngExternalRef extref = new RelaxngExternalRef ();
804                 extref.Href = (string) $2;
805                 extref.NSContext = (string) $3;
806                 $$ = extref;
807         }
808         ;
809
810 DataExcept /* returns RelaxngData */
811         : DatatypeName OptParams Minus LeadAnnotatedPrimary
812         {
813                 RelaxngData data = new RelaxngData ();
814                 foreach (RelaxngParam p in (IList) $2)
815                         data.ParamList.Add (p);
816                 data.Except = new RelaxngExcept ();
817                 foreach (RelaxngPattern p in (RelaxngPatternList) $4)
818                         data.Except.Patterns.Add (p);
819                 $$ = data;
820         }
821         ;
822
823 Ref /* returns string */
824         : Identifier
825         ;
826
827 DatatypeName
828         : CName
829         {
830                 string cname = (string) $1;
831         /*
832                 int colonAt = cname.IndexOf (':');
833                 string local = cname.Substring (colonAt + 1);
834                 string prefix = cname.Substring (0, colonAt);
835                 string ns = dtnsmgr.LookupNamespace (prefix);
836                 $$ = new XmlQualifiedName (local, ns);
837         */
838                 $$ = SplitQName (dtnsmgr, cname);
839         }
840         | KeywordString
841         {
842                 $$ = new XmlQualifiedName ("string", String.Empty);
843         }
844         | KeywordToken
845         {
846                 $$ = new XmlQualifiedName ("token", String.Empty);
847         }
848         ;
849
850 DatatypeValue
851         : Literal
852         ;
853
854 OptParams
855         : /* empty */
856         {
857                 $$ = new RelaxngParamList ();
858         }
859         | OpenCurly Params CloseCurly
860         {
861                 $$ = $2;
862         }
863         ;
864
865 Params
866         : /* empty */
867         {
868                 $$ = new RelaxngParamList ();
869         }
870         | Param Params
871         {
872                 RelaxngParamList al = (RelaxngParamList) $2;
873                 al.Insert (0, (RelaxngParam) $1);
874                 $$ = al;
875         }
876         ;
877
878 Param /* returns RelaxngParam */
879         : Annotations IdentifierOrKeyword Equal Literal
880         {
881                 RelaxngParam prm = new RelaxngParam ();
882                 prm.Name = (string) $2;
883                 prm.Value = (string) $4;
884
885 //              $$ = ApplyAnnotations ((string) $1, prm);
886                 $$ = prm;
887         }
888         ;
889
890 NameClass /* returns RelaxngNameClass */
891         : InnerNameClass
892         {
893                 $$ = $1;
894         }
895         ;
896
897 InnerNameClass /* returns RelaxngNameClass */
898         : AnnotatedSimpleNameClass
899         {
900                 $$ = (RelaxngNameClass) $1;
901         }
902         | NameClassChoice
903         {
904                 RelaxngNameChoice cho = new RelaxngNameChoice ();
905                 RelaxngNameClassList list = (RelaxngNameClassList) $1;
906                 for (int i = 0; i < list.Count; i++)
907                         cho.Children.Add ((RelaxngNameClass) list [i]);
908                 $$ = cho;
909         }
910         | AnnotatedExceptNameClass
911         {
912                 $$ = (RelaxngNameClass) $1;
913         }
914         ;
915
916 NameClassChoice /* returns RelaxngNameClassList */
917         : AnnotatedSimpleNameClass Bar AnnotatedSimpleNameClass
918         {
919                 RelaxngNameClassList list = new RelaxngNameClassList ();
920                 list.Add ((RelaxngNameClass) $1);
921                 list.Add ((RelaxngNameClass) $3);
922                 $$ = list;
923         }
924         | AnnotatedSimpleNameClass Bar NameClassChoice
925         {
926                 RelaxngNameClassList list = (RelaxngNameClassList) $3;
927                 list.Insert (0, (RelaxngNameClass) $1);
928                 $$ = list;
929         }
930         ;
931
932 AnnotatedExceptNameClass /* returns RelaxngNameClass */
933         : LeadAnnotatedExceptNameClass FollowAnnotations
934         {
935                 $$ = (RelaxngNameClass) $1;
936         }
937         ;
938
939 LeadAnnotatedExceptNameClass /* returns RelaxngNameClass */
940         : Annotations ExceptNameClass
941         {
942                 $$ = (RelaxngNameClass) $2;
943         }
944         ;
945
946 AnnotatedSimpleNameClass /* returns RelaxngNameClass */
947         : LeadAnnotatedSimpleNameClass FollowAnnotations
948         {
949                 // FIXME: annotations
950                 $$ = $1;
951         }
952         ;
953
954 LeadAnnotatedSimpleNameClass /* returns RelaxngNameClass */
955         : Annotations SimpleNameClass
956         {
957                 // FIXME: applyAnnotations
958                 $$ = (RelaxngNameClass) $2;
959         }
960         | Annotations OpenParen InnerNameClass CloseParen
961         {
962                 $$ = $3;
963         }
964         ;
965
966 ExceptNameClass
967         : NsName Minus LeadAnnotatedSimpleNameClass
968         {
969                 RelaxngNsName nsName = new RelaxngNsName ();
970                 nsName.Namespace = nsmgr.LookupNamespace ((string) $1);
971                 nsName.Except = new RelaxngExceptNameClass ();
972                 nsName.Except.Names.Add ((RelaxngNameClass) $3);
973                 $$ = nsName;
974         }
975         | Asterisk Minus LeadAnnotatedSimpleNameClass
976         {
977                 RelaxngAnyName anyName = new RelaxngAnyName ();
978                 anyName.Except = new RelaxngExceptNameClass ();
979                 anyName.Except.Names.Add ((RelaxngNameClass) $3);
980                 $$ = anyName;
981         }
982         ;
983
984 SimpleNameClass /* returns RelaxngNameClass */
985         : IdentifierOrKeyword
986         {
987                 RelaxngName name = new RelaxngName ();
988                 name.LocalName = (string) $1;
989                 name.Namespace = null;
990                 $$ = name;
991         }
992         | CName
993         {
994                 string cname = (string) $1;
995 //              int colonAt = cname.IndexOf (':');
996 //              XmlQualifiedName qname = new XmlQualifiedName (cname.Substring (colonAt + 1), nsmgr.LookupNamespace (cname.Substring (0, colonAt - 1)));
997                 XmlQualifiedName qname = SplitQName (nsmgr, cname);
998                 RelaxngName name = new RelaxngName ();
999                 name.LocalName = qname.Name;
1000                 name.Namespace = qname.Namespace;
1001                 $$ = name;
1002         }
1003         | NsName
1004         {
1005                 RelaxngNsName nsName = new RelaxngNsName ();
1006                 nsName.Namespace = nsmgr.LookupNamespace ((string) $1);
1007                 $$ = nsName;
1008         }
1009         | Asterisk
1010         {
1011                 $$ = new RelaxngAnyName ();
1012         }
1013         ;
1014
1015 FollowAnnotations
1016         : /* empty */
1017         {
1018                 $$ = null;
1019         }
1020         | TwoGreaters AnnotationElement FollowAnnotations
1021         {
1022                 // FIXME: handle them
1023                 $$ = null;
1024         }
1025         ;
1026
1027 Annotations /* returns null */
1028         /* FIXME: needed to handle them? */
1029         : Documentations
1030         {
1031                 $$ = null;
1032         }
1033         | Documentations OpenCurly AnnotationAttributes AnnotationElements CloseCurly
1034         {
1035                 $$ = null;
1036         }
1037         ;
1038
1039 AnnotationAttributes /* returns null */
1040         : /* empty */
1041         {
1042                 $$ = null;
1043         }
1044         | ForeignAttributeName Equal Literal AnnotationAttributes
1045         {
1046                 // Constraint: duplicate attributes
1047
1048                 // FIXME: do something
1049                 $$ = null;
1050         }
1051         ;
1052
1053 ForeignAttributeName /* returns XmlQualifiedName */
1054         : PrefixedName
1055         {
1056                 // Constraint: xmlns namespace URI
1057                 // Constraint: unqualified name
1058                 // Constraint: RELAX NG namespace URI
1059
1060                 // do nothing
1061 //              $$ = $1;
1062         }
1063         ;
1064
1065 AnnotationElements
1066         : /* empty */
1067         | AnnotationElement AnnotationElements
1068         ;
1069
1070 AnnotationElement
1071         : ForeignElementName AnnotationAttributesContent
1072         {
1073                 // do nothing
1074 //              $$ = Element ($1, $2);
1075                 $$ = null;
1076         }
1077         ;
1078
1079 ForeignElementName
1080         : /*IdentifierOrKeyword
1081         {
1082                 $$ = new XmlQualifiedName ((string) $1, String.Empty);
1083         }
1084         |*/ PrefixedName
1085         {
1086                 // Constraint: RELAX NG namespace URI
1087                 $$ = $1;
1088         }
1089         ;
1090
1091 AnnotationElementNotKeyword /* returns null */
1092         : ForeignElementNameNotKeyword AnnotationAttributesContent
1093         {
1094                 // do nothing
1095 //              $$ = Element ($1, $2);
1096         }
1097         ;
1098
1099 ForeignElementNameNotKeyword  /* returns XmlQualifiedName */
1100 /* LAMESPEC: unprefixed Identifier causes conflict */
1101         : /*Identifier
1102         {
1103                 $$ = new XmlQualifiedName ((string) $1, String.Empty);
1104         }
1105         |*/ PrefixedName
1106         {
1107                 // Constraint: RELAX NG namespace URI
1108                 $$ = (XmlQualifiedName) $1;
1109         }
1110         ;
1111
1112 AnnotationAttributesContent /* returns null */
1113         : OpenBracket NestedAnnotationAttributes AnnotationContent CloseBracket
1114         {
1115                 $$ = null;
1116         }
1117         ;
1118
1119 NestedAnnotationAttributes /* returns null */
1120         : /* empty */
1121         {
1122                 $$ = null;
1123         }
1124         | AnyAttributeName Equal Literal NestedAnnotationAttributes
1125         {
1126                 // Constraint: duplicate attributes
1127
1128                 // do nothing
1129 //              $$ = Attribute ($1, $2);
1130                 $$ = null;
1131         }
1132
1133 AnyAttributeName /* returns XmlQualifiedName */
1134         : IdentifierOrKeyword
1135         {
1136                 $$ = new XmlQualifiedName ((string) $1);
1137         }
1138         | PrefixedName
1139         {
1140                 // Constraint: xmlns namespace URI
1141                 $$ = (XmlQualifiedName) $1;
1142         }
1143         ;
1144
1145 AnnotationContent /* returns null */
1146         : /* empty */
1147         {
1148                 $$ = null;
1149         }
1150         | NestedAnnotationElement AnnotationContent
1151         {
1152                 $$ = null;
1153         }
1154         | Literal AnnotationContent
1155         {
1156                 $$ = null;
1157         }
1158         ;
1159
1160 NestedAnnotationElement /* returns null */
1161         : AnyElementName AnnotationAttributesContent
1162         {
1163                 // do nothing
1164 //              $$ = Element ($1, $2);
1165                 $$ = null;
1166         }
1167         ;
1168
1169 AnyElementName /* returns XmlQualifiedName */
1170         : IdentifierOrKeyword
1171         {
1172                 $$ = new XmlQualifiedName ((string) $1, String.Empty);
1173         }
1174         | PrefixedName
1175         {
1176                 $$ = (XmlQualifiedName) $1;
1177         }
1178         ;
1179
1180 PrefixedName /* returns XmlQualifiedName */
1181         : CName
1182         {
1183                 // Constraint: annotation inherit
1184                 $$ = SplitQName (nsmgr, (string) $1);
1185         }
1186         ;
1187
1188 Documentations /* returns null */
1189         : /* empty */
1190         {
1191                 $$ = null;
1192         }
1193         | Documentation Documentations
1194         {
1195                 // do nothing
1196 //              $$ = Element (DocumentationElementName (), Text ((string) $1), $2);
1197                 $$ = null;
1198         }
1199         ;
1200
1201 IdentifierOrKeyword /* returns string */
1202         : Identifier
1203         {
1204                 $$ = (string) $1;
1205         }
1206         | Keyword
1207         {
1208                 $$ = (string) $1;
1209         }
1210         ;
1211
1212 Keyword /* returns string */
1213         : KeywordAttribute
1214         | KeywordDefault
1215         | KeywordDatatypes
1216         | KeywordDiv
1217         | KeywordElement
1218         | KeywordEmpty
1219         | KeywordExternal
1220         | KeywordGrammar
1221         | KeywordInclude
1222         | KeywordInherit
1223         | KeywordList
1224         | KeywordMixed
1225         | KeywordNamespace
1226         | KeywordNotAllowed
1227         | KeywordParent
1228         | KeywordStart
1229         | KeywordString
1230         | KeywordText
1231         | KeywordToken
1232         ;
1233
1234 Literal /* returns string */
1235         : LiteralSegment
1236         {
1237                 $$ = (string) $1;
1238         }
1239         | LiteralSegment Tilde Literal
1240         {
1241                 $$ = (string) $1 + (string) $3;
1242         }
1243         ;
1244
1245 Identifier /* returns string */
1246         : NCNameButKeyword
1247         {
1248                 $$ = (string) $1;
1249         }
1250         | BackSlash NCNameButKeyword
1251         {
1252                 $$ = (string) $2;
1253         }
1254         /* extended */
1255         | BackSlash Keyword
1256         {
1257                 $$ = (string) $2;
1258         }
1259         ;
1260
1261 %%
1262 }