181b81b4a4
Former-commit-id: cf92446697332992ec36726e78eb8703e1f259d7
1316 lines
28 KiB
Plaintext
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;
|
|
}
|
|
;
|
|
|
|
%%
|
|
}
|