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