Jo Shields 181b81b4a4 Imported Upstream version 3.12.0
Former-commit-id: cf92446697332992ec36726e78eb8703e1f259d7
2015-01-13 10:44:36 +00:00

1316 lines
28 KiB
Plaintext

%{
//
// RELAX NG Compact Syntax parser
//
// Author:
// Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
//
// (C)2003 Atsushi Enomoto
//
// Copyright (c) 2004 Novell Inc.
// All rights reserved
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Xml;
using Commons.Xml.Relaxng;
namespace Commons.Xml.Relaxng.Rnc
{
public class RncParser
{
public static RelaxngPattern ParseRnc (TextReader reader)
{
return ParseRnc (reader, new NameTable ());
}
public static RelaxngPattern ParseRnc (TextReader reader, XmlNameTable nameTable)
{
return ParseRnc (reader, nameTable, null);
}
public static RelaxngPattern ParseRnc (TextReader reader, XmlNameTable nameTable, string baseUri)
{
return ParseRnc (reader, nameTable, baseUri, null);
}
public static RelaxngPattern ParseRnc (TextReader reader, XmlNameTable nameTable, string baseUri, string defaultNamespace)
{
return new RncParser (nameTable).Parse (reader, baseUri, defaultNamespace);
}
XmlNamespaceManager nsmgr;
XmlNamespaceManager dtnsmgr;
string defaultNamespace;
static int yacc_verbose_flag;
RncTokenizer tokenizer;
public RncParser (XmlNameTable nameTable)
{
if (nameTable == null)
nameTable = new NameTable ();
nsmgr = new XmlNamespaceManager (nameTable);
dtnsmgr = new XmlNamespaceManager (nameTable);
dtnsmgr.AddNamespace ("xsd", "http://www.w3.org/2001/XMLSchema-datatypes");
ErrorOutput = System.IO.TextWriter.Null;
}
public int Line {
get { return tokenizer.Line; }
}
public int Column {
get { return tokenizer.Column; }
}
public string BaseUri {
get { return tokenizer.BaseUri; }
}
// note that this is different notion than that of xmlns.
public RelaxngPattern Parse (TextReader source)
{
return Parse (source, null);
}
public RelaxngPattern Parse (TextReader source, string baseUri)
{
return Parse (source, baseUri, null);
}
public RelaxngPattern Parse (TextReader source, string baseUri, string defaultNamespace)
{
this.defaultNamespace = defaultNamespace ?? string.Empty;
if (defaultNamespace != null && defaultNamespace.Length != 0)
nsmgr.AddNamespace (String.Empty, defaultNamespace);
try {
if (Environment.GetEnvironmentVariable ("MONO_RELAXNG_COMPACT_DEBUG") == "yes")
debug = new yydebug.yyDebugSimple ();
tokenizer = new RncTokenizer (source, baseUri);
RelaxngPattern p = (RelaxngPattern) yyparse (tokenizer);
if (p is RelaxngGrammar)
((RelaxngGrammar) p).IsSourceCompactSyntax = true;
return p;
} catch (Exception ex) {
throw new RelaxngException (String.Format ("Tokenizer error at line {0}, column {1}: {2}", Line, Column, ex.Message), ex);
}
}
private void FillLocation (RelaxngElementBase el)
{
el.BaseUri = BaseUri;
el.LineNumber = Line;
el.LinePosition = Column;
}
private void FillGrammarContent (IList source, IList starts, IList defines, IList divs, IList includes)
{
foreach (RelaxngElementBase elem in source) {
if (elem is RelaxngStart)
starts.Add (elem);
else if (elem is RelaxngDefine)
defines.Add (elem);
else if (elem is RelaxngDiv)
divs.Add (elem);
else if (elem is RelaxngInclude)
includes.Add (elem);
else
throw new InvalidOperationException ();
}
}
private XmlQualifiedName SplitQName (XmlNamespaceManager nsmgr, string name)
{
int colon = name.IndexOf (':');
if (colon < 0)
return new XmlQualifiedName (name, String.Empty);
string local = name.Substring (colon + 1);
string prefix = name.Substring (0, colon);
return new XmlQualifiedName (local, nsmgr.LookupNamespace (nsmgr.NameTable.Get (prefix)));
}
private void FillElementDefaultNS (RelaxngNameClass nc)
{
RelaxngName name = nc as RelaxngName;
if (name != null) {
if (name.Namespace == null)
name.Namespace = defaultNamespace;
return;
}
RelaxngNameChoice choice = nc as RelaxngNameChoice;
if (choice != null) {
foreach (RelaxngNameClass c in choice.Children)
FillElementDefaultNS (c);
}
}
private void FillAttributeDefaultNS (RelaxngNameClass nc)
{
RelaxngName name = nc as RelaxngName;
if (name != null) {
if (name.Namespace == null)
name.Namespace = String.Empty;
return;
}
RelaxngNameChoice choice = nc as RelaxngNameChoice;
if (choice != null) {
foreach (RelaxngNameClass c in choice.Children)
FillAttributeDefaultNS (c);
}
}
%}
%token ERROR
%token EOF
%token KeywordAttribute "attribute"
%token KeywordDefault //"default"
%token KeywordDatatypes "datatypes"
%token KeywordDiv "div"
%token KeywordElement "element"
%token KeywordEmpty "empty"
%token KeywordExternal "external"
%token KeywordGrammar "grammar"
%token KeywordInclude "include"
%token KeywordInherit "inherit"
%token KeywordList "list"
%token KeywordMixed "mixed"
%token KeywordNamespace //"namespace"
%token KeywordNotAllowed "notAllowed"
%token KeywordParent "parent"
%token KeywordStart "start"
%token KeywordString //"string"
%token KeywordText "text"
%token KeywordToken "left"
%token Equal "="
%token Comma ","
%token Tilde "~"
%token OpenCurly "{"
%token CloseCurly "}"
%token OpenParen "("
%token CloseParen ")"
%token OpenBracket "["
%token CloseBracket "]"
%token Amp "&"
%token Bar "|"
%token Question "?"
%token Asterisk "*"
%token Plus "+"
%token Minus "-"
%token OrEquals "|="
%token AndEquals "&="
%token TwoGreaters ">>"
%token LiteralSegment
%token NCName
%token QuotedIdentifier
%token Documentation
/* These tokens are parsed by RncTokenizer, since whitespaces between
the particles are not allowed. */
%token NCName
%token CName
%token NsName
%start TopLevel
%%
TopLevel /* returns RelaxngPattern */
: Preamble TopLevelBody
{
$$ = (RelaxngPattern) $2;
}
;
Preamble /* returns null */
: /* empty */
{
$$ = null;
}
| Decl Preamble
{
$$ = null;
}
;
Decl /* returns null */
: KeywordNamespace NamespacePrefix Equal NamespaceURILiteral
{
// TODO: constraints
string prefix = (string) $2;
string ns = (string) $4;
if (prefix == "local")
nsmgr.AddNamespace (String.Empty, ns);
else
nsmgr.AddNamespace (prefix, ns);
$$ = null;
}
| KeywordDefault KeywordNamespace Equal NamespaceURILiteral
{
// TODO: constraints
string ns = (string) $4;
defaultNamespace = ns;
nsmgr.AddNamespace (String.Empty, ns);
$$ = null;
}
| KeywordDefault KeywordNamespace NamespacePrefix Equal NamespaceURILiteral
{
// TODO: constraints
string prefix = (string) $3;
string ns = (string) $5;
defaultNamespace = ns;
nsmgr.AddNamespace (String.Empty, ns);
nsmgr.AddNamespace (prefix, ns);
$$ = null;
}
| KeywordDatatypes DatatypePrefix Equal Literal
{
// TODO: constraints
string prefix = (string) $2;
string ns = (string) $4;
dtnsmgr.AddNamespace (prefix, ns);
$$ = null;
}
;
NamespacePrefix /* returns string */
: IdentifierOrKeyword
{
$$ = (string) $1;
}
;
DatatypePrefix /* returns string */
: IdentifierOrKeyword
{
$$ = (string) $1;
}
;
NamespaceURILiteral /* returns string */
: Literal
{
$$ = (string) $1;
}
| KeywordInherit
{
$$ = defaultNamespace;
}
;
TopLevelBody /* returns RelaxngPattern */
: Pattern
{
// TODO: Constraint: single element
// IList pl = (IList) $1;
// if (pl.Count != 1)
// throw new RelaxngException ("The number of the top level pattern must be exactly one.");
// $$ = pl [0];
$$ = (RelaxngPattern) $1;
}
| Grammar
{
RelaxngGrammar g = new RelaxngGrammar ();
FillLocation (g);
if (defaultNamespace != null)
g.DefaultNamespace = defaultNamespace;
RelaxngGrammarContentList list = (RelaxngGrammarContentList) $1;
FillGrammarContent (list, g.Starts, g.Defines, g.Divs, g.Includes);
$$ = g;
}
;
Grammar /* returns RelaxngGrammarContentList */
: /* empty */
{
$$ = new RelaxngGrammarContentList ();
}
| Member Grammar
{
RelaxngGrammarContentList al = (RelaxngGrammarContentList) $2;
if ($1 != null)
al.Insert (0, (IGrammarContent) $1);
$$ = al;
}
;
Member /* returns nullable IGrammarContent (RelaxngDiv, RelaxngInclude, RelaxngStart, RelaxngDefine) */
: AnnotatedComponent
{
$$ = (IGrammarContent) $1;
}
| AnnotationElementNotKeyword
{
$$ = null;
}
;
AnnotatedComponent /* returns IGrammarContent */
: Annotations Component
{
// $$ = ApplyAnnotations ((string) $1, (RelaxngElementBase) $2);
$$ = (IGrammarContent) $2;
}
;
Component /* returns IGrammarContent */
: Start
{
$$ = (RelaxngStart) $1;
}
| Define
{
$$ = (RelaxngDefine) $1;
}
| Include
{
$$ = (RelaxngInclude) $1;
}
| Div
{
$$ = (RelaxngDiv) $1;
}
;
Start /* returns RelaxngStart */
: KeywordStart AssignOp Pattern
{
RelaxngStart start = new RelaxngStart ();
FillLocation (start);
start.Combine = (string) $2;
start.Pattern = (RelaxngPattern) $3;
$$ = start;
}
;
Define /* returns RelaxngDefine */
: Identifier AssignOp Pattern
{
RelaxngDefine def = new RelaxngDefine ();
FillLocation (def);
def.Name = (string) $1;
def.Combine = (string) $2;
def.Patterns.Add ((RelaxngPattern) $3);
$$ = def;
}
;
AssignOp /* returns string */
: Equal
{
$$ = null;
}
| OrEquals
{
$$ = "choice";
}
| AndEquals
{
$$ = "interleave";
}
;
Include /* returns RelaxngInclude */
: KeywordInclude AnyURILiteral OptInherit OptIncludeBody
{
// FIXME: OptInherit is not handled properly.
RelaxngInclude include = new RelaxngInclude ();
FillLocation (include);
include.Href = (string) $2;
include.NSContext = (string) $3;
FillGrammarContent ((IList) $4, include.Starts, include.Defines, include.Divs, null);
$$ = include;
}
;
AnyURILiteral /* returns string */
: Literal
{
// Constraints: any URI
$$ = (string) $1;
}
;
OptInherit /* returns string */
/* The empty value will be handled at Compile() time. */
: /* empty */
{
// MakeNsAttribute (LookupDefault (environment));
$$ = defaultNamespace;
}
| KeywordInherit Equal IdentifierOrKeyword
{
// MakeNsAttribute (LookupPrefix (environment, $3));
$$ = nsmgr.LookupPrefix ((string) $3);
}
;
OptIncludeBody /* returns IList */
: /* empty */
{
$$ = new ArrayList ();
}
| OpenCurly IncludeBody CloseCurly
{
$$ = (IList) $2;
}
;
IncludeBody /* returns IList */
: /* empty */
{
$$ = new ArrayList ();
}
| IncludeMember IncludeBody
{
ArrayList al = (ArrayList) $2;
al.Insert (0, $1);
$$ = al;
}
;
IncludeMember /* returns RelaxngElementBase */
: AnnotatedIncludeComponent
{
$$ = (RelaxngElementBase) $1;
}
| AnnotationElementNotKeyword
{
$$ = (RelaxngElementBase) $1;
}
;
AnnotatedIncludeComponent /* returns IGrammarContent */
: Annotations IncludeComponent
{
// $$ = ApplyAnnotations ((string) $1, (RelaxngElementBase) $2);
$$ = (IGrammarContent) $2;
}
;
IncludeComponent /* returns IGrammarContent */
: Start
{
$$ = (RelaxngStart) $1;
}
| Define
{
$$ = (RelaxngDefine) $1;
}
| IncludeDiv
{
$$ = (RelaxngDiv) $1;
}
;
Div /* returns RelaxngDiv */
: KeywordDiv OpenCurly Grammar CloseCurly
{
RelaxngDiv div = new RelaxngDiv ();
FillLocation (div);
FillGrammarContent ((IList) $3, div.Starts, div.Defines, div.Divs, div.Includes);
$$ = div;
}
;
IncludeDiv /* returns RelaxngDiv */
: KeywordDiv OpenCurly IncludeBody CloseCurly
{
RelaxngDiv div = new RelaxngDiv ();
FillLocation (div);
FillGrammarContent ((IList) $3, div.Starts, div.Defines, div.Divs, div.Includes);
$$ = div;
}
;
Pattern /* returns RelaxngPattern */
: InnerPattern
;
InnerPattern /* returns RelaxngPattern */
/* TODO: applyAnnotations() are omitted */
: InnerParticle
{
$$ = (RelaxngPattern) $1;
}
| ParticleChoice
{
RelaxngPatternList list = (RelaxngPatternList) $1;
RelaxngChoice choice = new RelaxngChoice ();
FillLocation (choice);
for (int i = 0; i < list.Count; i++)
choice.Patterns.Add (list [i]);
// This is said as to return Elements, while ApplyAnnotations() is said to return Element
$$ = choice;
}
| ParticleGroup
{
RelaxngPatternList list = (RelaxngPatternList) $1;
RelaxngGroup group = new RelaxngGroup ();
FillLocation (group);
for (int i = 0; i < list.Count; i++)
group.Patterns.Add (list [i]);
// This is said as to return Elements, while ApplyAnnotations() is said to return Element
$$ = group;
}
| ParticleInterleave
{
RelaxngPatternList list = (RelaxngPatternList) $1;
RelaxngInterleave interleave = new RelaxngInterleave ();
FillLocation (interleave);
for (int i = 0; i < list.Count; i++)
interleave.Patterns.Add (list [i]);
// This is said as to return Elements, while ApplyAnnotations() is said to return Element
$$ = interleave;
}
| AnnotatedDataExcept
{
$$ = (RelaxngData) $1;
}
;
ParticleChoice /* returns RelaxngPatternList */
: Particle Bar Particle
{
RelaxngPatternList list = new RelaxngPatternList ();
list.Add ((RelaxngPattern) $1);
list.Add ((RelaxngPattern) $3);
$$ = list;
}
| Particle Bar ParticleChoice
{
RelaxngPatternList list = (RelaxngPatternList) $3;
list.Insert (0, (RelaxngPattern) $1);
$$ = list;
}
;
ParticleGroup /* returns RelaxngPatternList */
: Particle Comma Particle
{
RelaxngPatternList list = new RelaxngPatternList ();
list.Add ((RelaxngPattern) $1);
list.Add ((RelaxngPattern) $3);
$$ = list;
}
| Particle Comma ParticleGroup
{
RelaxngPatternList list = (RelaxngPatternList) $3;
list.Insert (0, (RelaxngPattern) $1);
$$ = list;
}
;
ParticleInterleave /* returns RelaxngPatternList */
: Particle Amp Particle
{
RelaxngPatternList list = new RelaxngPatternList ();
list.Add ((RelaxngPattern) $1);
list.Add ((RelaxngPattern) $3);
$$ = list;
}
| Particle Amp ParticleInterleave
{
RelaxngPatternList list = (RelaxngPatternList) $3;
list.Insert (0, (RelaxngPattern) $1);
$$ = list;
}
;
Particle /* returns RelaxngPattern */
: InnerParticle
;
InnerParticle /* returns RelaxngPattern */
: AnnotatedPrimary
{
// $$ = ApplyAnnotationsGroup (null, (RelaxngPatternList) $1);
$$ = $1;
}
| RepeatedPrimary FollowAnnotations
{
// FIXME: annotations are not handled
RelaxngPattern p = (RelaxngPattern) $1;
// RelaxngPatternList l = new RelaxngPatternList ();
// l.Add (p);
// $$ = l;
$$ = p;
}
;
RepeatedPrimary /* returns RelaxngPattern */
: AnnotatedPrimary Asterisk
{
RelaxngZeroOrMore zom = new RelaxngZeroOrMore ();
FillLocation (zom);
zom.Patterns.Add ((RelaxngPattern) $1);
$$ = zom;
}
| AnnotatedPrimary Plus
{
RelaxngOneOrMore oom = new RelaxngOneOrMore ();
FillLocation (oom);
oom.Patterns.Add ((RelaxngPattern) $1);
$$ = oom;
}
| AnnotatedPrimary Question
{
RelaxngOptional opt = new RelaxngOptional ();
FillLocation (opt);
opt.Patterns.Add ((RelaxngPattern) $1);
$$ = opt;
}
;
AnnotatedPrimary /* returns RelaxngPattern */
: LeadAnnotatedPrimary FollowAnnotations
{
// FIXME: handle followAnnotations
$$ = $1;
}
;
AnnotatedDataExcept /* returns RelaxngPattern */
: LeadAnnotatedDataExcept FollowAnnotations
{
// FIXME: handle followAnnotations
$$ = $1;
}
;
LeadAnnotatedDataExcept /* returns RelaxngData */
: Annotations DataExcept
{
$$ = $2;
}
;
LeadAnnotatedPrimary /* returns RelaxngPattern */
: Annotations Primary
{
// LAMESPEC: This should return Elements, while ApplyAnnotations() returns Element
// RelaxngPatternList list = new RelaxngPatternList ();
// list.Add ((RelaxngPattern) ApplyAnnotations ((string) $1, (RelaxngPattern) $2));
// $$ = list;
$$ = (RelaxngPattern) $2;
}
| Annotations OpenParen InnerPattern CloseParen
{
// $$ = (RelaxngPatternList) $3;
$$ = (RelaxngPattern) $3;
}
;
Primary /* returns RelaxngPattern */
: KeywordElement NameClass OpenCurly Pattern CloseCurly
{
RelaxngNameClass nc = (RelaxngNameClass) $2;
RelaxngElement el = new RelaxngElement ();
FillLocation (el);
el.NameClass = nc;
FillElementDefaultNS (el.NameClass);
el.Patterns.Add ((RelaxngPattern) $4);
$$ = el;
}
| KeywordAttribute NameClass OpenCurly Pattern CloseCurly
{
RelaxngNameClass nc = (RelaxngNameClass) $2;
RelaxngAttribute attr = new RelaxngAttribute ();
FillLocation (attr);
attr.NameClass = nc;
FillAttributeDefaultNS (attr.NameClass);
attr.Pattern = (RelaxngPattern) $4;
$$ = attr;
}
| KeywordMixed OpenCurly Pattern CloseCurly
{
RelaxngMixed mixed = new RelaxngMixed ();
FillLocation (mixed);
mixed.Patterns.Add ((RelaxngPattern) $3);
$$ = mixed;
}
| KeywordList OpenCurly Pattern CloseCurly
{
RelaxngList list = new RelaxngList ();
FillLocation (list);
list.Patterns.Add ((RelaxngPattern) $3);
$$ = list;
}
| DatatypeName OptParams
{
RelaxngData data = new RelaxngData ();
FillLocation (data);
XmlQualifiedName dtName = (XmlQualifiedName) $1;
data.DatatypeLibrary = dtName.Namespace;
data.Type = dtName.Name;
foreach (RelaxngParam p in (ICollection) $2)
data.ParamList.Add (p);
$$ = data;
}
| DatatypeName DatatypeValue
{
RelaxngValue value = new RelaxngValue ();
FillLocation (value);
XmlQualifiedName dtName = (XmlQualifiedName) $1;
if (dtName.Namespace != RelaxngGrammar.NamespaceURI)
value.DatatypeLibrary = dtName.Namespace;
value.Type = dtName.Name;
value.Value = (string) $2;
$$ = value;
}
| DatatypeValue
{
RelaxngValue value = new RelaxngValue ();
FillLocation (value);
value.Value = (string) $1;
// RELAX NG default type
value.Type = "string";
value.DatatypeLibrary = String.Empty;
$$ = value;
}
| KeywordEmpty
{
RelaxngEmpty empty = new RelaxngEmpty ();
FillLocation (empty);
$$ = empty;
}
| KeywordNotAllowed
{
RelaxngNotAllowed na = new RelaxngNotAllowed ();
FillLocation (na);
$$ = na;
}
| KeywordText
{
RelaxngText text = new RelaxngText ();
FillLocation (text);
$$ = text;
}
| Ref
{
RelaxngRef r = new RelaxngRef ();
FillLocation (r);
r.Name = (string) $1;
$$ = r;
}
| KeywordParent Ref
{
RelaxngParentRef pref = new RelaxngParentRef ();
FillLocation (pref);
pref.Name = (string) $2;
$$ = pref;
}
| KeywordGrammar OpenCurly Grammar CloseCurly
{
RelaxngGrammar g = new RelaxngGrammar ();
FillLocation (g);
FillGrammarContent ((IList) $3, g.Starts, g.Defines, g.Divs, g.Includes);
$$ = g;
}
| KeywordExternal AnyURILiteral OptInherit
{
RelaxngExternalRef extref = new RelaxngExternalRef ();
FillLocation (extref);
extref.Href = (string) $2;
extref.NSContext = (string) $3;
$$ = extref;
}
;
DataExcept /* returns RelaxngData */
: DatatypeName OptParams Minus LeadAnnotatedPrimary
{
XmlQualifiedName type = (XmlQualifiedName) $1;
RelaxngData data = new RelaxngData ();
FillLocation (data);
data.Type = type.Name;
data.DatatypeLibrary = type.Namespace;
foreach (RelaxngParam p in (RelaxngParamList) $2)
data.ParamList.Add (p);
data.Except = new RelaxngExcept ();
FillLocation (data.Except);
data.Except.Patterns.Add ((RelaxngPattern) $4);
$$ = data;
}
;
Ref /* returns string */
: Identifier
;
DatatypeName
: CName
{
string cname = (string) $1;
$$ = SplitQName (dtnsmgr, cname);
}
| KeywordString
{
$$ = new XmlQualifiedName ("string", String.Empty);
}
| KeywordToken
{
$$ = new XmlQualifiedName ("token", String.Empty);
}
;
DatatypeValue
: Literal
;
OptParams
: /* empty */
{
$$ = new RelaxngParamList ();
}
| OpenCurly Params CloseCurly
{
$$ = $2;
}
;
Params
: /* empty */
{
$$ = new RelaxngParamList ();
}
| Param Params
{
RelaxngParamList al = (RelaxngParamList) $2;
al.Insert (0, (RelaxngParam) $1);
$$ = al;
}
;
Param /* returns RelaxngParam */
: Annotations IdentifierOrKeyword Equal Literal
{
RelaxngParam prm = new RelaxngParam ();
FillLocation (prm);
prm.Name = (string) $2;
prm.Value = (string) $4;
// $$ = ApplyAnnotations ((string) $1, prm);
$$ = prm;
}
;
NameClass /* returns RelaxngNameClass */
: InnerNameClass
{
$$ = $1;
}
;
InnerNameClass /* returns RelaxngNameClass */
: AnnotatedSimpleNameClass
{
$$ = (RelaxngNameClass) $1;
}
| NameClassChoice
{
RelaxngNameChoice cho = new RelaxngNameChoice ();
FillLocation (cho);
RelaxngNameClassList list = (RelaxngNameClassList) $1;
for (int i = 0; i < list.Count; i++)
cho.Children.Add ((RelaxngNameClass) list [i]);
$$ = cho;
}
| AnnotatedExceptNameClass
{
$$ = (RelaxngNameClass) $1;
}
;
NameClassChoice /* returns RelaxngNameClassList */
: AnnotatedSimpleNameClass Bar AnnotatedSimpleNameClass
{
RelaxngNameClassList list = new RelaxngNameClassList ();
list.Add ((RelaxngNameClass) $1);
list.Add ((RelaxngNameClass) $3);
$$ = list;
}
| AnnotatedSimpleNameClass Bar NameClassChoice
{
RelaxngNameClassList list = (RelaxngNameClassList) $3;
list.Insert (0, (RelaxngNameClass) $1);
$$ = list;
}
;
AnnotatedExceptNameClass /* returns RelaxngNameClass */
: LeadAnnotatedExceptNameClass FollowAnnotations
{
$$ = (RelaxngNameClass) $1;
}
;
LeadAnnotatedExceptNameClass /* returns RelaxngNameClass */
: Annotations ExceptNameClass
{
$$ = (RelaxngNameClass) $2;
}
;
AnnotatedSimpleNameClass /* returns RelaxngNameClass */
: LeadAnnotatedSimpleNameClass FollowAnnotations
{
// FIXME: annotations
$$ = $1;
}
;
LeadAnnotatedSimpleNameClass /* returns RelaxngNameClass */
: Annotations SimpleNameClass
{
// FIXME: applyAnnotations
$$ = (RelaxngNameClass) $2;
}
| Annotations OpenParen InnerNameClass CloseParen
{
$$ = $3;
}
;
ExceptNameClass
: NsName Minus LeadAnnotatedSimpleNameClass
{
RelaxngNsName nsName = new RelaxngNsName ();
FillLocation (nsName);
nsName.Namespace = nsmgr.LookupNamespace ((string) $1);
nsName.Except = new RelaxngExceptNameClass ();
FillLocation (nsName.Except);
nsName.Except.Names.Add ((RelaxngNameClass) $3);
$$ = nsName;
}
| Asterisk Minus LeadAnnotatedSimpleNameClass
{
RelaxngAnyName anyName = new RelaxngAnyName ();
FillLocation (anyName);
anyName.Except = new RelaxngExceptNameClass ();
FillLocation (anyName.Except);
anyName.Except.Names.Add ((RelaxngNameClass) $3);
$$ = anyName;
}
;
SimpleNameClass /* returns RelaxngNameClass */
: IdentifierOrKeyword
{
RelaxngName name = new RelaxngName ();
FillLocation (name);
name.LocalName = (string) $1;
name.Namespace = null;
$$ = name;
}
| CName
{
string cname = (string) $1;
XmlQualifiedName qname = SplitQName (nsmgr, cname);
RelaxngName name = new RelaxngName ();
FillLocation (name);
name.LocalName = qname.Name;
name.Namespace = qname.Namespace;
$$ = name;
}
| NsName
{
RelaxngNsName nsName = new RelaxngNsName ();
FillLocation (nsName);
nsName.Namespace = nsmgr.LookupNamespace ((string) $1);
$$ = nsName;
}
| Asterisk
{
RelaxngAnyName anyName= new RelaxngAnyName ();
FillLocation (anyName);
$$ = anyName;
}
;
FollowAnnotations
: /* empty */
{
$$ = null;
}
| TwoGreaters AnnotationElement FollowAnnotations
{
// FIXME: handle them
$$ = null;
}
;
Annotations /* returns null */
/* FIXME: needed to handle them? */
: Documentations
{
$$ = null;
}
| Documentations OpenBracket AnnotationContentInAnnotations CloseBracket
{
$$ = null;
}
;
// This one is extra to the original syntax rule. Also it and following
// annotation related rules are modified to work fine without ambiguity.
// FIXME: it should reject attributes after elements...
AnnotationContentInAnnotations
: // empty
| PrefixedName Equal Literal AnnotationContentInAnnotations
| PrefixedName AnnotationAttributesContent AnnotationContentInAnnotations
| IdentifierOrKeyword AnnotationAttributesContent AnnotationContentInAnnotations
;
// ... but something like this one should be used instead.
AttributableAnnotations
: // empty
| AttributableAnnotations PrefixedName Equal Literal NonAttributableAnnotations
;
NonAttributableAnnotations
: // empty
| PrefixedName AnnotationAttributesContent
| NonAttributableAnnotations IdentifierOrKeyword AnnotationAttributesContent
;
AnnotationElement
: ForeignElementName AnnotationAttributesContent
{
// do nothing
// $$ = Element ($1, $2);
$$ = null;
}
;
ForeignElementName
: IdentifierOrKeyword
{
$$ = new XmlQualifiedName ((string) $1, String.Empty);
}
| PrefixedName
// Constraint: RELAX NG namespace URI
;
// FIXME: due to syntax ambiguity it cannot be included in the creation rules.
AnnotationElementNotKeyword /* null */
: ERROR
;
/*
AnnotationElementNotKeyword // null
: ForeignElementNameNotKeyword AnnotationAttributeContent
{
// do nothing
$$ = $1;
}
;
ForeignElementNameNotKeyword // QName
: Identifier
{
$$ = new XmlQualifiedName ((string) $1, String.Empty);
}
| PrefixedName
{
// Constraint: RELAX NG namespace URI
$$ = (XmlQualifiedName) $1;
}
;
*/
AnnotationAttributesContent /* returns null */
: OpenBracket NestedAnnotationContents CloseBracket
{
$$ = null;
}
;
// ditto (see also AnnotationContentInAnnotations)
NestedAnnotationContents
: /* empty */
| PrefixedName Equal Literal NestedAnnotationContents
| IdentifierOrKeyword Equal Literal NestedAnnotationContents
| PrefixedName AnnotationAttributesContent NestedAnnotationContents
| IdentifierOrKeyword AnnotationAttributesContent NestedAnnotationContents
| Literal
| Literal NestedAnnotationContents
;
NestedAnnotationAttributes /* returns null */
: /* empty */
{
$$ = null;
}
| AnyAttributeName Equal Literal NestedAnnotationAttributes
{
// Constraint: duplicate attributes
// do nothing
// $$ = Attribute ($1, $2);
$$ = null;
}
AnyAttributeName /* returns XmlQualifiedName */
: IdentifierOrKeyword
{
$$ = new XmlQualifiedName ((string) $1);
}
| PrefixedName
{
// Constraint: xmlns namespace URI
$$ = (XmlQualifiedName) $1;
}
;
AnnotationContent /* returns null */
: /* empty */
{
$$ = null;
}
| NestedAnnotationElement AnnotationContent
{
$$ = null;
}
| Literal AnnotationContent
{
$$ = null;
}
;
NestedAnnotationElement /* returns null */
: AnyElementName AnnotationAttributesContent
{
// do nothing
// $$ = Element ($1, $2);
$$ = null;
}
;
AnyElementName /* returns XmlQualifiedName */
: IdentifierOrKeyword
{
$$ = new XmlQualifiedName ((string) $1, String.Empty);
}
| PrefixedName
{
$$ = (XmlQualifiedName) $1;
}
;
PrefixedName /* returns XmlQualifiedName */
: CName
{
// Constraint: annotation inherit
$$ = SplitQName (nsmgr, (string) $1);
}
;
Documentations /* returns null */
: /* empty */
{
$$ = null;
}
| Documentation Documentations
{
// do nothing
// $$ = Element (DocumentationElementName (), Text ((string) $1), $2);
$$ = null;
}
;
IdentifierOrKeyword /* returns string */
: Identifier
{
$$ = (string) $1;
}
| Keyword
{
$$ = (string) $1;
}
;
Keyword /* returns string */
: KeywordAttribute
| KeywordDefault
| KeywordDatatypes
| KeywordDiv
| KeywordElement
| KeywordEmpty
| KeywordExternal
| KeywordGrammar
| KeywordInclude
| KeywordInherit
| KeywordList
| KeywordMixed
| KeywordNamespace
| KeywordNotAllowed
| KeywordParent
| KeywordStart
| KeywordString
| KeywordText
| KeywordToken
;
Literal /* returns string */
: LiteralSegment
{
$$ = (string) $1;
}
| LiteralSegment Tilde Literal
{
$$ = (string) $1 + (string) $3;
}
;
Identifier /* returns string */
: NCName
{
$$ = (string) $1;
}
| QuotedIdentifier
{
$$ = (string) $1;
}
;
%%
}