#if NET_2_0
using System;
using System.Collections;
+using System.Globalization;
using System.Xml;
+using System.Xml.Query;
using System.Xml.Schema;
using System.Xml.XPath;
+using Mono.Xml.XQuery;
namespace Mono.Xml.XPath2
{
- public class ExprSequence
+ public class ExprSequence : CollectionBase
{
- ArrayList list = new ArrayList ();
-
public ExprSequence ()
{
}
public void Add (ExprSingle expr)
{
- list.Add (expr);
+ List.Add (expr);
+ }
+
+ public void AddRange (ICollection items)
+ {
+ if (items != null)
+ foreach (ExprSingle e in items)
+ List.Add (e);
}
public void Insert (int pos, ExprSingle expr)
{
- list.Insert (pos, expr);
+ List.Insert (pos, expr);
}
- public void Reverse ()
+ public ExprSingle this [int i] {
+ get { return List [i] as ExprSingle; }
+ set { List [i] = value; }
+ }
+
+ internal void CheckReference (XQueryASTCompiler compiler)
{
- list.Reverse ();
+ foreach (ExprSingle expr in List)
+ expr.CheckReference (compiler);
}
}
public abstract class ExprSingle
{
+ internal abstract void CheckReference (XQueryASTCompiler compiler);
+
+#region CompileAndEvaluate
+ internal static readonly XPathAtomicValue AtomicTrue = new XPathAtomicValue (true, XmlSchemaSimpleType.XsBoolean);
+ internal static readonly XPathAtomicValue AtomicFalse = new XPathAtomicValue (false, XmlSchemaSimpleType.XsBoolean);
+
+ XQueryStaticContext ctx;
+
+ internal ExprSingle Compile (XQueryASTCompiler compiler)
+ {
+ this.ctx = ctx;
+ return CompileCore (compiler);
+ }
+
+ // If internal&&protected is available in C#, it is the best signature.
+ internal abstract ExprSingle CompileCore (XQueryASTCompiler compiler);
+
+ internal XQueryStaticContext Context {
+ get { return ctx; }
+ }
+
+ public abstract SequenceType StaticType { get; }
+
+ /** <summary>
+ This is the core part of ExprSingle. It is
+ generally used to evaluate expression and returns
+ XPathItem sequence (iterator). The result is unordered
+ */
+ public abstract XPathSequence Evaluate (XPathSequence iter);
+
+ public virtual XPathSequence EvaluateOrdered (XPathSequence iter)
+ {
+ if (RequireSorting) {
+ ArrayList al = new ArrayList ();
+ foreach (XPathItem item in Evaluate (iter))
+ al.Add (item);
+ return new ListIterator (iter, al);
+ }
+ else
+ return Evaluate (iter);
+ }
+
+ public virtual void Serialize (XPathSequence iter)
+ {
+ XmlWriter w = iter.Context.Writer;
+ XPathSequence result = Evaluate (iter);
+ foreach (XPathItem item in result)
+ WriteXPathItem (item, w);
+ }
+
+ private void WriteXPathItem (XPathItem item, XmlWriter w)
+ {
+ if (item.IsNode) {
+ XPathNavigator nav = item as XPathNavigator;
+ nav.WriteSubtree (w);
+ } else
+ w.WriteValue (item.Value);
+ }
+
+ // get EBV
+ public virtual bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ XPathAtomicValue v = Atomize (Evaluate (iter));
+ return v != null ? v.ValueAsBoolean : false;
+ }
+
+ public virtual int EvaluateAsInt (XPathSequence iter)
+ {
+ XPathAtomicValue v = Atomize (Evaluate (iter));
+ return v != null ? v.ValueAsInt32 : 0;
+ }
+
+ public virtual string EvaluateAsString (XPathSequence iter)
+ {
+ XPathAtomicValue v = Atomize (Evaluate (iter));
+ return v != null ? v.Value : String.Empty;
+ }
+
+ // FIXME: What if iter contains list value?
+ public static XPathAtomicValue Atomize (XPathSequence iter)
+ {
+ if (!iter.MoveNext ())
+ return null;
+ XPathNavigator nav = iter.Current as XPathNavigator;
+ if (nav != null)
+ return new XPathAtomicValue (nav.TypedValue, nav.SchemaInfo.SchemaType);
+ else
+ return (XPathAtomicValue) iter.Current;
+ }
+
+ public virtual XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
+ {
+ return Atomize (Evaluate (iter));
+ }
+
+ public virtual bool RequireSorting {
+ get { return false; }
+ }
+#endregion
}
// FLWORExpr
- public class FLWORExpr : ExprSingle
+ internal class FLWORExpr : ExprSingle
{
public FLWORExpr (ForLetClauseCollection forlet, ExprSequence whereClause, OrderSpecList orderBy, ExprSingle ret)
{
public ExprSingle ReturnExpr {
get { return ret; }
+ set { ret = value; }
+ }
+
+ // ExprSingle Overrides
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ foreach (ForLetClause flc in fl)
+ foreach (ForLetSingleBody single in flc)
+ single.CheckReference (compiler);
+ whereClause.CheckReference (compiler);
+ foreach (OrderSpec os in orderBy)
+ os.Expression.CheckReference (compiler);
+ ret.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ foreach (ForLetClause flc in ForLetClauses) {
+ foreach (ForLetSingleBody flsb in flc) {
+ flsb.Expression = flsb.Expression.Compile (compiler);
+ compiler.CheckType (flsb.Expression, flsb.ReturnType);
+ }
+ }
+ for (int i = 0; i < WhereClause.Count; i++)
+ WhereClause [i] = WhereClause [i].Compile (compiler);
+ foreach (OrderSpec os in OrderBy)
+ os.Expression = os.Expression.Compile (compiler);
+ ReturnExpr = ReturnExpr.Compile (compiler);
+
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return ReturnExpr.StaticType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new FLWORIterator (iter, this);
}
+#endregion
}
- public class ForLetClauseCollection
+ internal class ForLetClauseCollection : CollectionBase
{
- ArrayList list = new ArrayList ();
-
public void Add (ForLetClause clause)
{
- list.Add (clause);
+ List.Add (clause);
}
- public void Reverse ()
+ public void Insert (int pos, ForLetClause clause)
{
- list.Reverse ();
+ List.Insert (pos, clause);
+ }
+
+ public ForLetClause this [int i] {
+ get { return (ForLetClause) List [i]; }
}
}
- public class OrderSpecList
+ internal class OrderSpecList : CollectionBase
{
bool isStable;
- ArrayList list = new ArrayList ();
public OrderSpecList ()
{
set { isStable = value; }
}
- public void Add (OrderSpec spec)
+ public void Insert (int pos, OrderSpec os)
{
- list.Add (spec);
+ List.Insert (pos, os);
}
- public void Reverse ()
+ public void Add (OrderSpec spec)
{
- list.Reverse ();
+ List.Add (spec);
+ }
+
+ public OrderSpec this [int i] {
+ get { return (OrderSpec) List [i]; }
}
}
- public class OrderSpec
+ internal class OrderSpec
{
public OrderSpec (ExprSingle expr, OrderModifier modifier)
{
}
}
- public class OrderModifier
+ internal class OrderModifier
{
public OrderModifier (XmlSortOrder order, XmlSortOrder emptyOrder, string collation)
{
this.sortOrder = sortOrder;
this.emptyOrder = emptyOrder;
- this.coll = collation;
+ this.coll = new CultureInfo (collation);
}
XmlSortOrder sortOrder;
XmlSortOrder emptyOrder;
- string coll;
+ CultureInfo coll;
- public XmlSortOrder SortOrder{
+ public XmlSortOrder SortOrder {
get { return sortOrder; }
}
get { return emptyOrder; }
}
- public string Collation {
+ public CultureInfo Collation {
get { return coll; }
}
}
- public class ForLetClause
+ internal class ForLetClause : CollectionBase
{
- ArrayList list = new ArrayList ();
-
- protected ArrayList List {
- get { return list; }
- }
-
- public void Reverse ()
- {
- list.Reverse ();
+ public ForLetSingleBody this [int i] {
+ get { return (ForLetSingleBody) List [i]; }
}
}
- public class ForClause : ForLetClause
+ internal class ForClause : ForLetClause
{
public ForClause ()
{
}
+ public void Insert (int pos, ForSingleBody body)
+ {
+ List.Insert (pos, body);
+ }
+
public void Add (ForSingleBody body)
{
List.Add (body);
}
}
- public class LetClause : ForLetClause
+ internal class LetClause : ForLetClause
{
public LetClause ()
{
}
+ public void Insert (int pos, LetSingleBody body)
+ {
+ List.Insert (pos, body);
+ }
+
public void Add (LetSingleBody body)
{
List.Add (body);
}
}
- public class ForSingleBody
+ internal abstract class ForLetSingleBody
{
- public ForSingleBody (XmlQualifiedName varName, SequenceType type, XmlQualifiedName positionalVar, ExprSingle expr)
+ XmlQualifiedName varName;
+ SequenceType type;
+ ExprSingle expr;
+
+ public ForLetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
{
this.varName = varName;
this.type = type;
- this.positionalVar = positionalVar;
this.expr = expr;
}
- XmlQualifiedName varName;
- XmlQualifiedName positionalVar;
- SequenceType type;
- ExprSingle expr;
-
public XmlQualifiedName VarName {
get { return varName; }
}
get { return type; }
}
- public XmlQualifiedName PositionalVar {
- get { return positionalVar; }
- }
-
public ExprSingle Expression {
get { return expr; }
+ set { expr = value; }
+ }
+
+ internal void CheckReference (XQueryASTCompiler compiler)
+ {
+ compiler.CheckSchemaType (type);
+ expr.CheckReference (compiler);
}
}
- public class LetSingleBody
+ internal class ForSingleBody : ForLetSingleBody
{
- public LetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
+ public ForSingleBody (XmlQualifiedName varName, SequenceType type, XmlQualifiedName positionalVar, ExprSingle expr)
+ : base (varName, type, expr)
{
- this.varName = varName;
- this.type = type;
- this.expr = expr;
+ this.positionalVar = positionalVar;
}
- XmlQualifiedName varName;
- SequenceType type;
- ExprSingle expr;
-
- public XmlQualifiedName VarName {
- get { return varName; }
- set { varName = value; }
- }
+ XmlQualifiedName positionalVar;
- public SequenceType ReturnType {
- get { return type; }
- set { type =value; }
+ public XmlQualifiedName PositionalVar {
+ get { return positionalVar; }
}
+ }
- public ExprSingle Expression {
- get { return expr; }
- set { expr = value; }
+ internal class LetSingleBody : ForLetSingleBody
+ {
+ public LetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
+ : base (varName, type, expr)
+ {
}
}
// QuantifiedExpr
- public class QuantifiedExpr : ExprSingle
+ internal class QuantifiedExpr : ExprSingle
{
+ QuantifiedExprBodyList body;
+ ExprSingle satisfies;
+ bool every;
+
public QuantifiedExpr (bool every, QuantifiedExprBodyList body, ExprSingle satisfies)
{
+ this.every = every;
+ this.body = body;
+ this.satisfies = satisfies;
+ }
+
+ public bool Every {
+ get { return every; }
+ }
+
+ public QuantifiedExprBodyList BodyList {
+ get { return body; }
+ }
+
+ public ExprSingle Satisfies {
+ get { return satisfies; }
+ set { satisfies = value; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ foreach (QuantifiedExprBody one in body) {
+ compiler.CheckSchemaType (one.Type);
+ one.Expression.CheckReference (compiler);
+ }
+ Satisfies.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Satisfies = Satisfies.Compile (compiler);
+ for (int i = 0; i < BodyList.Count; i++) {
+ BodyList [i].Expression = BodyList [i].Expression.Compile (compiler);
+ compiler.CheckType (BodyList [i].Expression, BodyList [i].Type);
+ }
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ foreach (QuantifiedExprBody qb in BodyList) {
+ XPathSequence seq = qb.Expression.Evaluate (iter);
+ // FIXME: consider qb.Type
+// if (!qb.Type.IsValid (seq))
+// throw new XmlQueryException ("Quantified expression resulted in type promotion error.");
+ iter.Context.PushVariable (qb.VarName, seq);
+ }
+
+ bool result = every;
+
+ foreach (XPathItem item in iter) {
+ if (satisfies.EvaluateAsBoolean (new SingleItemIterator (item, iter))) {
+ if (!every) {
+ result = true;
+ break;
+ }
+ }
+ else if (every) {
+ result = false;
+ break;
+ }
+ }
+
+ for (int i = 0; i < BodyList.Count; i++)
+ iter.Context.PopVariable ();
+
+ return result;
}
+#endregion
}
- public class QuantifiedExprBodyList
+ internal class QuantifiedExprBodyList : CollectionBase
{
- ArrayList list = new ArrayList ();
-
public QuantifiedExprBodyList ()
{
}
public void Add (QuantifiedExprBody body)
{
- list.Add (body);
+ List.Add (body);
}
- public void Reverse ()
+ public void Insert (int pos, QuantifiedExprBody body)
{
- list.Reverse ();
+ List.Insert (pos, body);
+ }
+
+ public QuantifiedExprBody this [int i] {
+ get { return (QuantifiedExprBody) List [i]; }
}
}
- public class QuantifiedExprBody
+ internal class QuantifiedExprBody
{
private XmlQualifiedName varName;
- private SequenceType typeDeclaration;
+ private SequenceType type;
private ExprSingle expr;
public QuantifiedExprBody (XmlQualifiedName varName,
- SequenceType typeDeclaration,
- ExprSingle expr)
+ SequenceType type, ExprSingle expr)
{
this.varName = varName;
- this.typeDeclaration = typeDeclaration;
+ this.type = type ;
this.expr = expr;
}
get { return varName; }
}
- public SequenceType TypeDeclaration {
- get { return typeDeclaration; }
+ public SequenceType Type {
+ get { return type; }
}
public ExprSingle Expression {
get { return expr; }
+ set { expr = value; }
}
}
// TypeswitchExpr
- public class TypeswitchExpr : ExprSingle
+ internal class TypeswitchExpr : ExprSingle
{
- public TypeswitchExpr (ExprSequence switchExpr, CaseClauseList caseList, XmlQualifiedName variableSpecName, ExprSingle defaultReturn)
+ ExprSequence switchExpr;
+ CaseClauseList caseList;
+ XmlQualifiedName defaultVarName;
+ ExprSingle defaultReturn;
+
+ public TypeswitchExpr (ExprSequence switchExpr, CaseClauseList caseList, XmlQualifiedName defaultVarName, ExprSingle defaultReturn)
+ {
+ }
+
+ public ExprSequence SwitchExpr {
+ get { return switchExpr; }
+ }
+
+ public CaseClauseList Cases {
+ get { return caseList; }
+ }
+
+ public XmlQualifiedName DefaultVarName {
+ get { return defaultVarName; }
+ }
+
+ public ExprSingle DefaultReturn {
+ get { return defaultReturn; }
+ set { defaultReturn = value; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ switchExpr.CheckReference (compiler);
+ foreach (CaseClause cc in caseList) {
+ compiler.CheckSchemaType (cc.Type);
+ cc.Expr.CheckReference (compiler);
+ }
+ defaultReturn.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ for (int i = 0; i < SwitchExpr.Count; i++)
+ SwitchExpr [i] = SwitchExpr [i].Compile (compiler);
+ foreach (CaseClause cc in Cases)
+ cc.Expr = cc.Expr.Compile (compiler);
+ DefaultReturn = DefaultReturn.Compile (compiler);
+ return this;
+ }
+
+ // FIXME: it can be optimized by checking all case clauses.
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
{
+ // FIXME: should move to iterator?
+ XPathSequence cond = new ExprSequenceIterator (iter, SwitchExpr);
+ XPathSequence ret = null;
+
+ foreach (CaseClause ccc in Cases) {
+ if (ccc.Type.Matches (cond)) {
+ if (ccc.VarName != XmlQualifiedName.Empty)
+ iter.Context.PushVariable (ccc.VarName, cond);
+ ret = ccc.Expr.Evaluate (iter);
+ // FIXME: The design should make sure that in-scope variables are held on actual iteration.
+ if (ccc.VarName != XmlQualifiedName.Empty)
+ iter.Context.PopVariable ();
+ return ret;
+ }
+ }
+
+ if (DefaultVarName != XmlQualifiedName.Empty)
+ iter.Context.PushVariable (DefaultVarName, cond);
+ ret = DefaultReturn.Evaluate (iter);
+ if (DefaultVarName != XmlQualifiedName.Empty)
+ iter.Context.PopVariable ();
+ return ret;
}
+#endregion
}
- public class CaseClauseList : CollectionBase
+ internal class CaseClauseList : CollectionBase
{
- ArrayList list = new ArrayList ();
+ public void Insert (int pos, CaseClause cc)
+ {
+ List.Insert (pos, cc);
+ }
public void Add (CaseClause cc)
{
- list.Add (cc);
+ List.Add (cc);
}
- public void Reverse ()
- {
- list.Reverse ();
+ public CaseClause this [int i] {
+ get { return (CaseClause) List [i]; }
}
}
- public class CaseClause
+ internal class CaseClause
{
public CaseClause (SequenceType type, ExprSingle expr, XmlQualifiedName varName)
{
+ this.type = type;
+ this.expr = expr;
+ this.varName = varName;
+ }
+
+ SequenceType type;
+ ExprSingle expr;
+ XmlQualifiedName varName;
+
+ public SequenceType Type {
+ get { return type; }
+ }
+
+ public ExprSingle Expr {
+ get { return expr; }
+ set { expr = value; }
+ }
+
+ public XmlQualifiedName VarName {
+ get { return varName; }
+ set { varName = value; }
}
}
// IfExpr
- public class IfExpr : ExprSingle
+ internal class IfExpr : ExprSingle
{
public IfExpr (ExprSequence condition, ExprSingle trueExpr, ExprSingle falseExpr)
{
+ this.condition = condition;
+ this.trueExpr = trueExpr;
+ this.falseExpr = falseExpr;
+ }
+
+ ExprSequence condition;
+ ExprSingle trueExpr;
+ ExprSingle falseExpr;
+
+ public ExprSequence Condition {
+ get { return condition; }
+ set { condition = value; }
+ }
+
+ public ExprSingle TrueExpr {
+ get { return trueExpr; }
+ set { trueExpr = value; }
+ }
+
+ public ExprSingle FalseExpr {
+ get { return falseExpr; }
+ set { falseExpr = value; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ condition.CheckReference (compiler);
+ trueExpr.CheckReference (compiler);
+ falseExpr.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ SequenceType computedReturnType;
+
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ for (int i = 0; i < Condition.Count; i++)
+ Condition [i] = Condition [i].Compile (compiler);
+ // FIXME: check if condition is constant, and returns trueExpr or falseExpr
+ TrueExpr = TrueExpr.Compile (compiler);
+ FalseExpr = FalseExpr.Compile (compiler);
+ return this;
}
+
+ public override SequenceType StaticType {
+ get {
+ if (Context == null)
+ return SequenceType.AnyType;
+ if (computedReturnType == null)
+ computedReturnType = SequenceType.ComputeCommonBase (TrueExpr.StaticType, FalseExpr.StaticType);
+ return computedReturnType;
+ }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ foreach (ExprSingle expr in Condition) {
+ if (expr.EvaluateAsBoolean (iter))
+ return TrueExpr.Evaluate (iter);
+ }
+ return FalseExpr.Evaluate (iter);
+ }
+#endregion
+
}
// logical expr
- public abstract class BinaryOperationExpr : ExprSingle
+ internal abstract class BinaryOperationExpr : ExprSingle
{
protected BinaryOperationExpr (ExprSingle left, ExprSingle right)
{
public ExprSingle Left {
get { return left; }
+ set { left = value; }
}
public ExprSingle Right{
get { return right; }
+ set { right = value; }
}
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ left.CheckReference (compiler);
+ right.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Left = Left.Compile (compiler);
+ Right = Right.Compile (compiler);
+ return this;
+ }
+#endregion
+
}
- public class OrExpr : BinaryOperationExpr
+ internal class OrExpr : BinaryOperationExpr
{
public OrExpr (ExprSingle left, ExprSingle right)
: base (left, right)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ base.CompileCore (compiler);
+ // FIXME: check constant value and return true or false
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ return Left.EvaluateAsBoolean (iter) || Right.EvaluateAsBoolean (iter);
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (EvaluateAsBoolean (iter) ?AtomicTrue : AtomicFalse, iter);
+ }
+
+ /*
+ - compiler -
+ return leftExprBool (context) || rightExprBool (context);
+ */
+#endregion
}
- public class AndExpr : BinaryOperationExpr
+ internal class AndExpr : BinaryOperationExpr
{
public AndExpr (ExprSingle left, ExprSingle right)
: base (left, right)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ base.CompileCore (compiler);
+ // FIXME: check constant value and return true or false
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ return Left.EvaluateAsBoolean (iter) && Right.EvaluateAsBoolean (iter);
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
+ }
+
+ /*
+ - compiler -
+ return leftExprBool (context) && rightExprBool (context);
+ */
+#endregion
}
// TypeOperation expr
- public abstract class TypeOperationExpr : ExprSingle
+ internal abstract class TypeOperationExpr : ExprSingle
{
protected TypeOperationExpr (ExprSingle expr, SequenceType type)
{
public ExprSingle Expr {
get { return expr; }
+ set { expr = value; }
}
- public SequenceType Type {
+ public SequenceType TargetType {
get { return type; }
}
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ compiler.CheckSchemaType (type);
+ }
}
- public abstract class AtomicTypeOperationExpr : ExprSingle
+ internal abstract class AtomicTypeOperationExpr : ExprSingle
{
protected AtomicTypeOperationExpr (ExprSingle expr, XmlTypeCode type, bool optional)
{
this.expr = expr;
- this.typeCode = type;
- this.optional = optional;
+// this.typeCode = type;
+// this.optional = optional;
+ this.targetType = SequenceType.Create (type, optional ? Occurence.Optional : Occurence.One);
}
ExprSingle expr;
- XmlTypeCode typeCode;
- bool optional;
+// XmlTypeCode typeCode;
+// bool optional;
+ SequenceType targetType;
- public ExprSingle Expr {
+ internal ExprSingle Expr {
get { return expr; }
+ set { expr = value; }
}
+/*
public XmlTypeCode TypeCode {
get { return typeCode; }
}
public bool Optional {
get { return optional; }
}
+*/
+ internal SequenceType TargetType {
+ get { return targetType; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ }
}
- public class InstanceOfExpr : TypeOperationExpr
+ internal class InstanceOfExpr : TypeOperationExpr
{
public InstanceOfExpr (ExprSingle expr, SequenceType type)
: base (expr, type)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ // FIXME: check return type and if it never matches then return false
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ bool occured = false;
+ bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
+ bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
+ foreach (XPathItem item in iter) {
+ if (occured && onlyOnce)
+ return false;
+ if (!TargetType.IsInstance (item))
+ return false;
+ }
+ return occured || !required;
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
+ }
+#endregion
}
- public class TreatExpr : TypeOperationExpr
+ internal class TreatExpr : TypeOperationExpr
{
public TreatExpr (ExprSingle expr, SequenceType type)
: base (expr, type)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ // FIXME: check return type and if it never matches then return false
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ if (TargetType.CanConvert (iter))
+ return iter;
+ else
+ throw new XmlQueryException (String.Format ("Cannot treat as {1}", TargetType));
+ }
+#endregion
}
- public class CastableExpr : AtomicTypeOperationExpr
+ internal class CastableExpr : AtomicTypeOperationExpr
{
public CastableExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
: base (expr, atomicType, optional)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ // FIXME: check return type and if it never matches then return boolean
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (new XPathAtomicValue (EvaluateAsBoolean (iter), XmlSchemaSimpleType.XsBoolean), iter);
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ bool occured = false;
+ bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
+ bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
+ foreach (XPathItem item in iter) {
+ if (occured && onlyOnce)
+ return false;
+ if (!TargetType.CanConvert (item))
+ return false;
+ }
+ return occured || !required;
+ }
+#endregion
}
- public class CastExpr : AtomicTypeOperationExpr
+ internal class CastExpr : AtomicTypeOperationExpr
{
public CastExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
: base (expr, atomicType, optional)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ // FIXME: check return type and if it never matches then return boolean
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return TargetType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ if (TargetType.CanConvert (iter))
+ return new ConvertingIterator (iter, TargetType);
+ else
+ throw new XmlQueryException (String.Format ("Cannot cast as {1}", TargetType));
+ }
+#endregion
}
// ComparisonExpr
- public class ComparisonExpr : BinaryOperationExpr
+ internal class ComparisonExpr : BinaryOperationExpr
{
public ComparisonExpr (ExprSingle left, ExprSingle right, ComparisonOperator oper)
: base (left, right)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Left = Left.Compile (compiler);
+ Right = Right.Compile (compiler);
+ // FIXME: check return type and if it never matches then return boolean
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Boolean; }
+ }
+
+ public override bool EvaluateAsBoolean (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
+ }
+#endregion
}
public enum ComparisonOperator {
// Range
- public class RangeExpr : BinaryOperationExpr
+ internal class RangeExpr : BinaryOperationExpr
{
public RangeExpr (ExprSingle left, ExprSingle right)
: base (left, right)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Left = Left.Compile (compiler);
+ Right = Right.Compile (compiler);
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.IntegerList; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ int start = Left.EvaluateAsInt (iter);
+ int end = Right.EvaluateAsInt (iter);
+ return new IntegerRangeIterator (iter, start, end);
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ int start = Left.EvaluateAsInt (iter);
+ int end = Right.EvaluateAsInt (iter);
+ for (int i = start; i <= end; i++) {
+ iter.Context.Writer.WriteValue (i);
+ if (i < end)
+ iter.Context.Writer.WriteWhitespace (" ");
+ }
+ }
+#endregion
}
// arithmetic operation expr
IMod
}
- public class ArithmeticOperationExpr : BinaryOperationExpr
+ internal class ArithmeticOperationExpr : BinaryOperationExpr
{
public ArithmeticOperationExpr (ExprSingle left, ExprSingle right, ArithmeticOperator oper)
: base (left, right)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Left = Left.Compile (compiler);
+ Right = Right.Compile (compiler);
+ return this;
+ }
+
+ // FIXME: It can be optimized by comparing l/r value types.
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ XPathAtomicValue lvalue = Left.EvaluateAsAtomic (iter);
+ XPathAtomicValue rvalue = Right.EvaluateAsAtomic (iter);
+
+ throw new NotImplementedException ();
+ }
+#endregion
}
- public class MinusExpr : ExprSingle
+ internal class MinusExpr : ExprSingle
{
public MinusExpr (ExprSingle expr)
{
+ this.expr = expr;
+ }
+
+ ExprSingle expr;
+
+ public ExprSingle Expr {
+ get { return expr; }
+ set { expr = value; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return Expr.StaticType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
}
+#endregion
}
// aggregation expr
- public class UnionExpr : BinaryOperationExpr
+ public enum AggregationType {
+ Union,
+ Intersect,
+ Except
+ }
+
+ internal class GroupExpr : BinaryOperationExpr
{
- public UnionExpr (ExprSingle left, ExprSingle right)
+ public GroupExpr (ExprSingle left, ExprSingle right, AggregationType aggrType)
: base (left, right)
{
+ this.aggrType = aggrType;
}
- }
- public class IntersectExpr : BinaryOperationExpr
- {
- public IntersectExpr (ExprSingle left, ExprSingle right)
- : base (left, right)
+ AggregationType aggrType;
+
+ public AggregationType AggregationType {
+ get { return aggrType; }
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
{
+ Left = Left.Compile (compiler);
+ Right = Right.Compile (compiler);
+ return this;
}
- }
- public class ExceptExpr : BinaryOperationExpr
- {
- public ExceptExpr (ExprSingle left, ExprSingle right)
- : base (left, right)
+ // FIXME: It can be optimized by comparing l/r value types.
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ // only applicable against node-sets
+ public override XPathSequence Evaluate (XPathSequence iter)
{
+ XPathSequence lvalue = Left.EvaluateOrdered (iter);
+ XPathSequence rvalue = Right.EvaluateOrdered (iter);
+
+ /*
+ TBD (yield earlier node, skipping one of the same nodes)
+ - or -
+ TBD (yield earlier node, skipping non-intersection nodes)
+ - or -
+ TBD (yield earlier node, skipping both of the same nodes)
+ */
+ throw new NotImplementedException ();
}
+#endregion
}
// validate expr
- public class ValidateExpr : ExprSingle
+ internal class ValidateExpr : ExprSingle
{
XmlSchemaContentProcessing schemaMode;
ExprSequence expr;
this.schemaMode = schemaMode;
this.expr = expr;
}
+
+ public ExprSequence Expr {
+ get { return expr; }
+ }
+
+ public XmlSchemaContentProcessing SchemaMode {
+ get { return schemaMode; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ for (int i = 0; i < expr.Count; i++)
+ expr [i] = expr [i].Compile (compiler);
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ // TBD (see 3.13).
+ throw new NotImplementedException ();
+ }
+#endregion
}
// Path expr
- public abstract class PathExpr : ExprSingle
+ internal abstract class PathExpr : ExprSingle
{
}
// '/'
- public class PathExprRoot : PathExpr
+ internal class PathRootExpr : PathExpr
{
- public PathExprRoot ()
+ public PathRootExpr ()
+ {
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Document; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ if (iter.MoveNext ())
+ return new XPathEmptySequence (iter);
+ XPathNavigator nav = iter.Current as XPathNavigator;
+ if (nav == null)
+ return new XPathEmptySequence (iter);
+ nav = nav.Clone ();
+ nav.MoveToRoot ();
+ return new SingleItemIterator (nav, iter);
+ }
+#endregion
}
// 'foo/bar'
- public class PathExprChild : PathExpr
+ internal class PathChildExpr : PathExpr
{
ExprSingle left;
- ExprSingle child;
+ ExprSingle next;
- public PathExprChild (ExprSingle left, ExprSingle child)
+ public PathChildExpr (ExprSingle left, ExprSingle next)
{
this.left = left;
- this.child = child;
+ this.next = next;
+ }
+
+ public ExprSingle Left {
+ get { return left; }
+ set { left = value; }
}
+
+ public ExprSingle Next {
+ get { return next; }
+ set { next = value; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ left.CheckReference (compiler);
+ next.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Left = Left.Compile (compiler);
+ Next = Next.Compile (compiler);
+ return this;
+ }
+
+ // FIXME: It can be optimized by comparing l/r value types.
+ public override SequenceType StaticType {
+ get { return SequenceType.Node; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new ChildPathIterator (iter, this);
+ }
+#endregion
}
// 'foo//bar'
- public class PathExprDescendant : PathExpr
+ internal class PathDescendantExpr : PathExpr
{
ExprSingle left;
ExprSingle descendant;
- public PathExprDescendant (ExprSingle left, ExprSingle descendant)
+ public PathDescendantExpr (ExprSingle left, ExprSingle descendant)
{
this.left = left;
this.descendant = descendant;
}
- }
- public abstract class StepExpr : PathExpr
- {
- }
+ public ExprSingle Left {
+ get { return left; }
+ set { left = value; }
+ }
- public class AxisStepExpr : StepExpr
- {
- public AxisStepExpr (XPathAxis axis, NodeTestExpr test)
- {
+ public ExprSingle Descendant {
+ get { return descendant; }
+ set { descendant = value; }
}
- static AxisStepExpr parentStep;
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ left.CheckReference (compiler);
+ descendant.CheckReference (compiler);
+ }
- static AxisStepExpr ()
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
{
- parentStep = new AxisStepExpr (XPathAxis.Parent, null);
+ Left = Left.Compile (compiler);
+ Descendant = Descendant.Compile (compiler);
+ return this;
}
- public static AxisStepExpr ParentStep {
- get { return parentStep; }
+ // FIXME: It can be optimized by comparing l/r value types.
+ public override SequenceType StaticType {
+ get { return SequenceType.Node; }
}
- }
- public class FilterStepExpr : StepExpr
- {
- public FilterStepExpr (ExprSingle expr, ExprSequenceList predicates)
+ public override XPathSequence Evaluate (XPathSequence iter)
{
+ return new DescendantPathIterator (iter, this);
}
+#endregion
}
- // predicates == exprsequence list == list of list of exprsingle
- public class ExprSequenceList
+ internal class AxisStepExpr : PathExpr
{
- ArrayList list = new ArrayList ();
+ static AxisStepExpr parentStep;
- public void Add (ExprSequence expr)
+ static AxisStepExpr ()
{
- list.Add (expr);
+ parentStep = new AxisStepExpr (XPathAxis.Parent, null);
}
- public void Insert (int pos, ExprSequence expr)
- {
- list.Insert (pos, expr);
+ public static AxisStepExpr ParentStep {
+ get { return parentStep; }
}
- }
-
- public enum XPathAxisType
- {
- Child,
- Descendant,
- Attribute,
- Self,
- DescendantOrSelf,
- FollowingSibling,
- Following,
- Parent,
- Ancestor,
- PrecedingSibling,
- Preceding,
- AncestorOrSelf
- }
- public class XPathAxis
- {
- // FIXME: add more parameters to distinguish them
- private XPathAxis (XPathAxisType axisType)
- {
- this.axisType = axisType;
- switch (axisType) {
- case XPathAxisType.Parent:
- case XPathAxisType.Ancestor:
- case XPathAxisType.AncestorOrSelf:
- case XPathAxisType.Preceding:
- case XPathAxisType.PrecedingSibling:
- this.reverse = true;
- break;
+ public AxisStepExpr (XPathAxis axis, XPath2NodeTest test)
+ {
+ this.axis = axis;
+ if (test == null)
+ nameTest = XmlQualifiedName.Empty;
+ else {
+ if (test.NameTest != null)
+ this.nameTest = test.NameTest;
+ else
+ this.kindTest = test.KindTest;
}
}
- bool reverse;
- XPathAxisType axisType;
+ XPathAxis axis;
+ XmlQualifiedName nameTest;
+ KindTest kindTest;
- public bool ReverseAxis {
- get { return reverse; }
+ public XPathAxis Axis {
+ get { return axis; }
}
- public XPathAxisType AxisType {
- get { return axisType; }
+ public XmlQualifiedName NameTest {
+ get { return nameTest; }
+ set { nameTest = value; }
}
- static XPathAxis child, descendant, attribute, self,
- descendantOrSelf, followingSibling, following,
- parent, ancestor, precedingSibling, preceding,
- ancestorOrSelf;
-
- static XPathAxis ()
- {
- child = new XPathAxis (XPathAxisType.Child);
- descendant = new XPathAxis (XPathAxisType.Descendant);
- attribute = new XPathAxis (XPathAxisType.Attribute);
- self = new XPathAxis (XPathAxisType.Self);
- descendantOrSelf = new XPathAxis (XPathAxisType.DescendantOrSelf);
- followingSibling = new XPathAxis (XPathAxisType.FollowingSibling);
- following = new XPathAxis (XPathAxisType.Following);
- parent = new XPathAxis (XPathAxisType.Parent);
- ancestor = new XPathAxis (XPathAxisType.Ancestor);
- precedingSibling = new XPathAxis (XPathAxisType.PrecedingSibling);
- preceding = new XPathAxis (XPathAxisType.Preceding);
- ancestorOrSelf = new XPathAxis (XPathAxisType.AncestorOrSelf);
+ public KindTest KindTest {
+ get { return kindTest; }
+ set { kindTest = value; }
}
- public static XPathAxis Child {
- get { return child; }
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (KindTest != null)
+ KindTest.CheckReference (compiler);
}
- public static XPathAxis Descendant {
- get { return descendant; }
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (KindTest != null)
+ KindTest.Compile (compiler);
+ return this;
}
- public static XPathAxis Attribute {
- get { return attribute; }
+ public override SequenceType StaticType {
+ get {
+ switch (Axis.AxisType) {
+ case XPathAxisType.Attribute:
+ return SequenceType.Attribute;
+ case XPathAxisType.Namespace:
+ return SequenceType.Namespace;
+ }
+ // FIXME: we can more filtering by KindTest
+ return SequenceType.Node;
+ }
}
- public static XPathAxis Self {
- get { return self; }
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ // FIXME: provide more classes than just one iterator
+ return new AxisIterator (iter, this);
}
+#endregion
+ }
- public static XPathAxis DescendantOrSelf {
- get { return descendantOrSelf; }
+ internal class FilterStepExpr : PathExpr
+ {
+ public FilterStepExpr (ExprSingle expr, PredicateList predicates)
+ {
+ this.expr = expr;
+ this.predicates = predicates;
}
- public static XPathAxis FollowingSibling {
- get { return followingSibling; }
- }
+ ExprSingle expr;
+ PredicateList predicates;
- public static XPathAxis Following {
- get { return following; }
+ public ExprSingle Expr {
+ get { return expr; }
+ set { expr = value; }
}
- public static XPathAxis Parent {
- get { return parent; }
+ public PredicateList Predicates {
+ get { return predicates; }
}
- public static XPathAxis Ancestor {
- get { return ancestor; }
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ foreach (ExprSequence seq in predicates)
+ seq.CheckReference (compiler);
}
- public static XPathAxis PrecedingSibling {
- get { return precedingSibling; }
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ Expr = Expr.Compile (compiler);
+ foreach (ExprSequence seq in Predicates)
+ for (int i = 0; i < seq.Count; i++)
+ seq [i] = seq [i].Compile (compiler);
+ return this;
}
- public static XPathAxis Preceding {
- get { return preceding; }
+ public override SequenceType StaticType {
+ get { return Expr.StaticType; }
}
- public static XPathAxis AncestorOrSelf {
- get { return ancestorOrSelf; }
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new FilteredIterator (iter, this);
}
+#endregion
}
- // NodeTest
-
- public abstract class NodeTestExpr : StepExpr
- {
- }
-
- public class NodeNameTestExpr : NodeTestExpr
+ // predicates == exprsequence list == list of list of exprsingle
+ internal class PredicateList : CollectionBase
{
- XmlQualifiedName name;
+ public void Add (ExprSequence expr)
+ {
+ List.Add (expr);
+ }
- public NodeNameTestExpr (XmlQualifiedName name)
+ public void Insert (int pos, ExprSequence expr)
{
- this.name = name;
+ List.Insert (pos, expr);
}
- public XmlQualifiedName Name {
- get { return name; }
+ public ExprSequence this [int i] {
+ get { return (ExprSequence) List [i]; }
}
}
- public class NodeKindTestExpr : NodeTestExpr
+ internal class XPath2NodeTest
{
- public NodeKindTestExpr (XmlTypeCode type)
+ public XPath2NodeTest (XmlQualifiedName nameTest)
+ {
+ this.NameTest = nameTest;
+ }
+
+ public XPath2NodeTest (KindTest kindTest)
{
- // item() -> XPathNodeType.All
- this.nodeKind = type;
+ this.KindTest = kindTest;
}
- XmlTypeCode nodeKind;
+ public XmlQualifiedName NameTest;
- public XmlTypeCode NodeKind {
- get { return nodeKind; }
- }
+ public KindTest KindTest;
}
- public class DocumentTestExpr : NodeKindTestExpr
+ internal class EnclosedExpr : ExprSingle
{
- ElementTestExpr content;
+ ExprSequence expr;
- public DocumentTestExpr (ElementTestExpr content)
- : base (XmlTypeCode.Document)
+ public EnclosedExpr (ExprSequence expr)
{
- this.content = content;
+ this.expr = expr;
}
- }
- public class ElementTestExpr : NodeKindTestExpr
- {
- public ElementTestExpr (XmlQualifiedName name)
- : base (XmlTypeCode.Element)
- {
- this.name = name;
+ public ExprSequence Expr {
+ get { return expr; }
}
- public ElementTestExpr (XmlQualifiedName name, XmlQualifiedName typeName, bool nillable)
- : base (XmlTypeCode.Element)
+ internal override void CheckReference (XQueryASTCompiler compiler)
{
- this.name = name;
- this.typeName = typeName;
- this.nillable = nillable;
+ expr.CheckReference (compiler);
}
- XmlQualifiedName name;
- XmlQualifiedName typeName;
- bool nillable;
-
- public XmlQualifiedName Name {
- get { return name; }
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Expr.Count == 0)
+ return Expr [0].Compile (compiler);
+ for (int i = 0; i < Expr.Count; i++)
+ Expr [i] = Expr [i].Compile (compiler);
+ return this;
}
- public XmlQualifiedName TypeName {
- get { return typeName; }
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
}
- public bool Nillable {
- get { return nillable; }
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new ExprSequenceIterator (iter, Expr);
}
+#endregion
}
- public class AttributeTestExpr : NodeKindTestExpr
- {
- static AttributeTestExpr anyAttribute;
+ // PrimaryExpr
- static AttributeTestExpr ()
+ internal abstract class PrimaryExpr : ExprSingle
+ {
+ internal override void CheckReference (XQueryASTCompiler compiler)
{
- anyAttribute = new AttributeTestExpr (XmlQualifiedName.Empty);
}
- public static AttributeTestExpr AnyAttribute {
- get { return anyAttribute; }
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ return this;
}
- public AttributeTestExpr (XmlQualifiedName name)
- : base (XmlTypeCode.Attribute)
+ public override XPathSequence Evaluate (XPathSequence iter)
{
- this.name = name;
+ return new SingleItemIterator (EvaluateAsAtomic (iter), iter);
}
+#endregion
+ }
- public AttributeTestExpr (XmlQualifiedName name, XmlQualifiedName typeName)
- : base (XmlTypeCode.Attribute)
+ internal class StringLiteralExpr : PrimaryExpr
+ {
+ string literal;
+
+ public StringLiteralExpr (string literal)
{
- this.name = name;
- this.typeName = typeName;
+ this.literal = literal;
}
- XmlQualifiedName name;
- XmlQualifiedName typeName;
-
- public XmlQualifiedName Name {
- get { return name; }
+ public string Literal {
+ get { return literal; }
}
- public XmlQualifiedName TypeName {
- get { return typeName; }
+#region CompileAndEvaluate
+ XmlSchemaSimpleType stringType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("string", XmlSchema.Namespace));
+
+ public override SequenceType StaticType {
+ get { return SequenceType.AtomicString; }
}
- }
- public class XmlPITestExpr : NodeKindTestExpr
- {
- string name;
+ public override string EvaluateAsString (XPathSequence iter)
+ {
+ return Literal;
+ }
- public XmlPITestExpr (string nameTest)
- : base (XmlTypeCode.ProcessingInstruction)
+ public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
{
- this.name = nameTest;
+ return new XPathAtomicValue (Literal, stringType);
}
+#endregion
}
- public class EnclosedExpr : ExprSingle
+ internal class DecimalLiteralExpr : PrimaryExpr
{
- ExprSequence expr;
+ decimal value;
- public EnclosedExpr (ExprSequence expr)
+ public DecimalLiteralExpr (decimal value)
{
- this.expr = expr;
+ this.value = value;
}
- }
- // PrimaryExpr
+ public decimal Value {
+ get { return value; }
+ }
- public abstract class PrimaryExpr : ExprSingle
- {
- }
+#region CompileAndEvaluate
+ XmlSchemaSimpleType decimalType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("decimal", XmlSchema.Namespace));
- public class StringLiteralExpr : PrimaryExpr
- {
- string literal;
- public StringLiteralExpr (string literal)
+ public override SequenceType StaticType {
+ get { return SequenceType.Decimal; }
+ }
+
+ public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
{
- this.literal = literal;
+ return new XPathAtomicValue (Value, decimalType);
}
+#endregion
}
- public class NumberLiteralExpr : PrimaryExpr
+ internal class DoubleLiteralExpr : PrimaryExpr
{
- decimal value;
+ double value;
- public NumberLiteralExpr (decimal value)
+ public DoubleLiteralExpr (double value)
{
this.value = value;
}
+
+ public double Value {
+ get { return value; }
+ }
+
+#region CompileAndEvaluate
+ XmlSchemaSimpleType doubleType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("double", XmlSchema.Namespace));
+
+ public override SequenceType StaticType {
+ get { return SequenceType.Double; }
+ }
+
+ public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
+ {
+ return new XPathAtomicValue (Value, doubleType);
+ }
+#endregion
}
- public class VariableReferenceExpr : PrimaryExpr
+ internal class VariableReferenceExpr : PrimaryExpr
{
XmlQualifiedName varName;
public XmlQualifiedName VariableName {
get { return varName; }
}
+
+ // FIXME: variable name must be stacked in any area
+ // whereever variables are defined.
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ compiler.CheckVariableName (varName);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ // FIXME: try to resolve static context variable and return the actual value expression
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ XPathSequence variable = iter.Context.ResolveVariable (VariableName, iter);
+ // FIXME: if Evaluate() accepts XPathSequence, then XPathSequence must be public class (to make IXPath2Variable public).
+ return variable;
+ }
+#endregion
}
- public class ParenthesizedExpr : PrimaryExpr
+ internal class ParenthesizedExpr : PrimaryExpr
{
ExprSequence expr;
{
this.expr = expr;
}
+
+ ExprSequence Expr {
+ get { return expr; }
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Expr.Count == 1)
+ return Expr [0].Compile (compiler);
+ for (int i = 0; i < Expr.Count; i++)
+ Expr [i] = Expr [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new ExprSequenceIterator (iter, Expr);
+ }
+#endregion
}
// "."
- public class ContextItemExpr : PrimaryExpr
+ internal class ContextItemExpr : PrimaryExpr
{
public ContextItemExpr ()
{
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ return this;
+ }
+
+ public override SequenceType StaticType {
+ get { return SequenceType.AnyType; }
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ return new SingleItemIterator (iter.Context.CurrentItem, iter);
+ }
+#endregion
}
- public class FunctionCallExpr : PrimaryExpr
+ internal abstract class FunctionCallExprBase : PrimaryExpr
{
XmlQualifiedName name;
ExprSequence args;
+ public FunctionCallExprBase (XmlQualifiedName name, ExprSequence args)
+ {
+ this.name = name;
+ this.args = args;
+ }
+
+ public XmlQualifiedName Name {
+ get { return name; }
+ }
+
+ public ExprSequence Args {
+ get { return args; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ compiler.CheckFunctionName (name);
+ }
+
+#region CompileAndEvaluate
+ /*
+ internal static FunctionCallExpr Create (
+ XmlQualifiedName name,
+ ExprSingle [] args,
+ XQueryStaticContext ctx)
+ {
+ switch (name.Namespace) {
+ case XQueryFunction.Namespace:
+ switch (name.Name) {
+ case "node-name":
+ return new FnNodeNameCall (ctx, args);
+ case "nilled":
+ return new FnNilledCall (ctx, args);
+ case "string":
+ return new FnStringCall (ctx, args);
+ case "data":
+ return new FnDataCall (ctx, args);
+ case "base-uri":
+ return new FnBaseUriCall (ctx, args);
+ case "document-uri":
+ return new FnDocumentUriCall (ctx, args);
+ case "error":
+ return new FnErrorCall (ctx, args);
+ case "trace":
+ return new FnTraceCall (ctx, args);
+ case "abs":
+ return new FnAbsCall (ctx, args);
+ case "ceiling":
+ return new FnCeilingCall (ctx, args);
+ case "floor":
+ return new FnFloorCall (ctx, args);
+ case "round":
+ return new FnRoundCall (ctx, args);
+ case "round-half-to-even":
+ return new FnRoundHalfToEvenCall (ctx, args);
+ case "codepoints-to-string":
+ return new FnCodepointsToStringCall (ctx, args);
+ case "string-to-codepoints":
+ return new FnStringCallToCodepointsCall (ctx, args);
+ }
+ goto default;
+ case XmlSchema.XdtNamespace:
+ case XmlSchema.Namespace:
+ XmlSchemaType type = XmlSchemaType.GetBuiltInSimpleType (name);
+ if (type != null)
+ return new AtomicConstructorCall (ctx, SequenceType.Create (type, Occurence.One), args);
+ type = XmlSchemaType.GetBuiltInComplexType (name);
+ if (type == null)
+ goto default;
+ return null;
+ default:
+ XQueryFunction func = ctx.CompileContext.InEffectFunctions [name];
+ if (func != null)
+ return new CustomFunctionCallExpression (ctx, args, func);
+ return null;
+ }
+ }
+ */
+
+ internal void CheckArguments (XQueryASTCompiler compiler)
+ {
+ if (args.Count < MinArgs || args.Count > MaxArgs)
+ // FIXME: add more info
+ throw new XmlQueryCompileException (String.Format ("{0} is invalid for the number of {1} function argument.", args.Count, name));
+ }
+
+ public abstract int MinArgs { get; }
+ public abstract int MaxArgs { get; }
+#endregion
+ }
+
+ // This class is used only in AST
+ internal class FunctionCallExpr : FunctionCallExprBase
+ {
public FunctionCallExpr (XmlQualifiedName name, ExprSequence args)
+ : base (name, args)
+ {
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
{
+ // resolve function
+ return new CustomFunctionCallExpr (Args, compiler.ResolveFunction (Name)).Compile (compiler);
}
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new InvalidOperationException ("XQuery internal error. Should not happen.");
+ }
+
+ public SequenceType StaticType {
+ get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
+ }
+
+ public override int MinArgs {
+ get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
+ }
+
+ public override int MaxArgs {
+ get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
+ }
+
+#endregion
}
- public class SequenceType
+#region CompileAndEvaluate
+
+ // It is instantiated per function call expression.
+ // (e.g. the example below contains 3 FunctionCallExpression instances:
+ // "replace(node-name (node-before(/*)), 'foo', node-name($var))"
+ internal class CustomFunctionCallExpr : FunctionCallExprBase
{
- NodeKindTestExpr kindTest;
- Occurence occurence;
+ public CustomFunctionCallExpr (ExprSequence args, XQueryFunction function)
+ : base (function.Name, args)
+ {
+ this.function = function;
+ }
+
+ XQueryFunction function;
+
+ public XQueryFunction Function {
+ get { return function; }
+ }
+
+ public override int MinArgs {
+ get { return function.MinArgs; }
+ }
+
+ public override int MaxArgs {
+ get { return function.MaxArgs; }
+ }
+
+ public override SequenceType StaticType {
+ get { return function.ReturnType; }
+ }
+
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ CheckArguments (compiler);
+ return this;
+ }
- public SequenceType (NodeKindTestExpr test, Occurence occurence)
+ public override XPathSequence Evaluate (XPathSequence iter)
{
- this.kindTest = test;
- this.occurence = occurence;
+ return Function.Evaluate (iter);
}
+
+ // FIXME: add all overrides that delegates to XQueryFunction
}
+#endregion
- public enum Occurence
+ // Ordered / Unordered
+ internal class OrderSpecifiedExpr : ExprSingle
{
- One,
- Optional,
- ZeroOrMore,
- OneOrMore,
+ bool ordered;
+ ExprSequence expr;
+
+ public OrderSpecifiedExpr (ExprSequence expr, bool ordered)
+ {
+ this.ordered = ordered;
+ this.expr = expr;
+ }
+
+ public ExprSequence Expr {
+ get { return expr; }
+ }
+
+ public bool Ordered {
+ get { return ordered; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ expr.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ public override SequenceType StaticType {
+ // FIXME: could be optimized by checking all the expressions
+ get { return SequenceType.AnyType; }
+ }
+
+ public override bool RequireSorting {
+ get { return Ordered; }
+ }
+
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ for (int i = 0; i < Expr.Count; i++)
+ Expr [i] = Expr [i].Compile (compiler);
+ return this;
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
+ }
+#endregion
}
}
using System;
using System.Collections;
using System.Xml;
+using System.Xml.Query;
using System.Xml.Schema;
using System.Xml.XPath;
using Mono.Xml.XPath2;
namespace Mono.Xml.XQuery
{
- public class ElementConstructor : ExprSingle
+ internal abstract class XmlConstructorExpr : ExprSingle
{
- public ElementConstructor (XmlQualifiedName name, AttributeConstructorList attributes, ExprSequence content)
+ public XmlConstructorExpr (ExprSequence content)
{
+ this.content = content;
}
- }
- public class AttributeConstructorList
- {
- ArrayList list = new ArrayList ();
+ ExprSequence content;
+
+ public ExprSequence Content {
+ get { return content; }
+ }
- public AttributeConstructorList ()
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
{
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
}
- public void Add (AttributeConstructor item)
+ public void SerializeContent (XPathSequence iter)
{
- list.Add (item);
+ foreach (ExprSingle expr in Content)
+ expr.Serialize (iter);
}
- public void Insert (int pos, AttributeConstructor item)
+ internal IXmlNamespaceResolver GetNSResolver (XPathSequence iter)
{
- list.Insert (pos, item);
+ // FIXME: IXmlNamespaceResolver must be constructed
+ // considering 1)static context and 2)in-scope element
+ // construction.
+ return iter.Context;
}
+#endregion
}
- public class AttributeConstructor
+ internal class XmlAttrConstructorList : CollectionBase
{
- public AttributeConstructor (XmlQualifiedName name, ExprSequence content)
+ public XmlAttrConstructorList ()
{
}
+
+ public void Add (XmlAttrConstructor item)
+ {
+ List.Add (item);
+ }
+
+ public void Insert (int pos, XmlAttrConstructor item)
+ {
+ List.Insert (pos, item);
+ }
}
- public class XmlElemConstructor : ExprSingle
+ internal class XmlElemConstructor : XmlConstructorExpr
{
XmlQualifiedName name;
ExprSequence nameExpr;
- ExprSequence content;
public XmlElemConstructor (XmlQualifiedName name, ExprSequence content)
+ : base (content)
{
+ this.name = name;
}
public XmlElemConstructor (ExprSequence name, ExprSequence content)
+ : base (content)
+ {
+ this.name = XmlQualifiedName.Empty;
+ this.nameExpr = name;
+ }
+
+ public XmlQualifiedName Name {
+ get { return name; }
+ }
+ public ExprSequence NameExpr {
+ get { return nameExpr; }
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (nameExpr != null)
+ nameExpr.CheckReference (compiler);
+ if (Content != null)
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (NameExpr != null)
+ for (int i = 0; i < NameExpr.Count; i++)
+ NameExpr [i] = NameExpr [i].Compile (compiler);
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Element; }
+ }
+
+ public override void Serialize (XPathSequence iter)
{
+ XmlQualifiedName name = EvaluateName (iter);
+ XmlWriter w = iter.Context.Writer;
+ w.WriteStartElement (iter.Context.LookupPrefix (name.Namespace), name.Name, name.Namespace);
+ SerializeContent (iter);
+ w.WriteEndElement ();
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ XmlQualifiedName name = EvaluateName (iter);
+
+ XPathDocument doc = new XPathDocument ();
+ XmlWriter w = iter.Context.Writer;
+ try {
+ iter.Context.Writer = doc.CreateWriter ();
+ Serialize (iter);
+ iter.Context.Writer.Close ();
+ } finally {
+ iter.Context.Writer = w;
+ }
+ XPathNavigator nav = doc.CreateNavigator ();
+ nav.MoveToFirstChild ();
+ return new SingleItemIterator (nav, iter);
+ }
+
+ private XmlQualifiedName EvaluateName (XPathSequence iter)
+ {
+ XmlQualifiedName name = Name;
+ if (NameExpr != null) {
+ XPathAtomicValue value = Atomize (new ExprSequenceIterator (iter, NameExpr));
+ IXmlNamespaceResolver res = iter.Context.NSResolver;
+
+ switch (value.XmlType.TypeCode) {
+ case XmlTypeCode.QName:
+ name = (XmlQualifiedName) value.ValueAs (typeof (XmlQualifiedName), res);
+ break;
+ case XmlTypeCode.String:
+ try {
+ name = XmlQualifiedName.Parse (value.Value, res);
+ } catch (ArgumentException ex) {
+ // FIXME: add more info
+ throw new XmlQueryException (String.Format ("The evaluation result of the name expression could not be resolved as a valid QName. Evaluation result string is '{0}'.", value.Value));
+ }
+ break;
+ default:
+ // FIXME: add more info
+ throw new XmlQueryException ("A name of an element constructor must be resolved to either a QName or string.");
+ }
+ }
+ return name;
}
+#endregion
}
- public class XmlAttrConstructor : ExprSingle
+ internal class XmlAttrConstructor : XmlConstructorExpr
{
XmlQualifiedName name;
ExprSequence nameExpr;
- ExprSequence content;
public XmlAttrConstructor (XmlQualifiedName name, ExprSequence content)
+ : base (content)
{
+ this.name = name;
}
public XmlAttrConstructor (ExprSequence name, ExprSequence content)
+ : base (content)
+ {
+ this.nameExpr = name;
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (nameExpr != null)
+ nameExpr.CheckReference (compiler);
+ if (Content != null)
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (NameExpr != null)
+ for (int i = 0; i < NameExpr.Count; i++)
+ NameExpr [i] = NameExpr [i].Compile (compiler);
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ public XmlQualifiedName Name {
+ get { throw new NotImplementedException (); }
+ }
+ public ExprSequence NameExpr {
+ get { throw new NotImplementedException (); }
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Attribute; }
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ XmlQualifiedName name = EvaluateName (iter);
+ XmlWriter w = iter.Context.Writer;
+ w.WriteStartAttribute (GetNSResolver (iter).LookupPrefix (name.Namespace), name.Name, name.Namespace);
+ SerializeContent (iter);
+ w.WriteEndAttribute ();
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
{
+ XmlQualifiedName name = EvaluateName (iter);
+
+ XPathDocument doc = new XPathDocument ();
+ XmlWriter w = iter.Context.Writer;
+ try {
+ iter.Context.Writer = doc.CreateEditor ().CreateAttributes ();
+ // FIXME: maybe container element is required?
+ Serialize (iter);
+ iter.Context.Writer.Close ();
+ } finally {
+ iter.Context.Writer = w;
+ }
+ XPathNavigator nav = doc.CreateNavigator ();
+ nav.MoveToFirstAttribute ();
+ return new SingleItemIterator (nav, iter);
}
+
+ private XmlQualifiedName EvaluateName (XPathSequence iter)
+ {
+ XmlQualifiedName name = Name;
+ if (NameExpr != null) {
+ XPathAtomicValue value = Atomize (new ExprSequenceIterator (iter, NameExpr));
+ IXmlNamespaceResolver res = GetNSResolver (iter);
+
+ switch (value.XmlType.TypeCode) {
+ case XmlTypeCode.QName:
+ name = (XmlQualifiedName) value.ValueAs (typeof (XmlQualifiedName), res);
+ break;
+ case XmlTypeCode.String:
+ try {
+ // nonprefixed attribute name == element's local namespace
+ if (value.Value.IndexOf (':') < 0)
+ name = new XmlQualifiedName (value.Value);
+ else
+ name = XmlQualifiedName.Parse (value.Value, res);
+ } catch (ArgumentException ex) {
+ // FIXME: add more info
+ throw new XmlQueryException (String.Format ("The evaluation result of the name expression could not be resolved as a valid QName. Evaluation result string is '{0}'.", value.Value));
+ }
+ break;
+ default:
+ // FIXME: add more info
+ throw new XmlQueryException ("A name of an attribute constructor must be resolved to either a QName or string.");
+ }
+ }
+ return name;
+ }
+#endregion
}
- public class XmlNSConstructor : ExprSingle
+ internal class XmlNSConstructor : XmlConstructorExpr
{
public XmlNSConstructor (string prefix, ExprSequence content)
+ : base (content)
+ {
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Namespace; }
+ }
+
+ public override void Serialize (XPathSequence iter)
{
+ // TBD
+ throw new NotImplementedException ();
}
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ // TBD
+ throw new NotImplementedException ();
+ }
+#endregion
}
- public class XmlDocConstructor : ExprSingle
+ internal class XmlDocConstructor : XmlConstructorExpr
{
public XmlDocConstructor (ExprSequence content)
+ : base (content)
+ {
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Document; }
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ XmlWriter w = iter.Context.Writer;
+ w.WriteStartDocument ();
+ SerializeContent (iter);
+ w.WriteEndDocument ();
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
{
+ throw new NotImplementedException ();
}
+#endregion
}
- public class XmlTextConstructor : ExprSingle
+ internal class XmlTextConstructor : XmlConstructorExpr
{
public XmlTextConstructor (string text)
+ : base (null)
{
}
public XmlTextConstructor (ExprSequence content)
+ : base (content)
{
}
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Text; }
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ iter.Context.Writer.WriteString (Atomize (new ExprSequenceIterator (iter, Content)).Value);
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
+ }
+#endregion
}
- public class XmlCommentConstructor : ExprSingle
+ internal class XmlCommentConstructor : XmlConstructorExpr
{
string contentLiteral;
- ExprSequence contentExpr;
public XmlCommentConstructor (string content)
+ : base (null)
{
this.contentLiteral = content;
}
public XmlCommentConstructor (ExprSequence content)
+ : base (content)
+ {
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
{
- this.contentExpr = content;
+ if (Content != null)
+ Content.CheckReference (compiler);
}
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.Comment; }
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ iter.Context.Writer.WriteComment (Atomize (new ExprSequenceIterator (iter, Content)).Value);
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
+ }
+#endregion
}
- public class XmlPIConstructor : ExprSingle
+ internal class XmlPIConstructor : XmlConstructorExpr
{
string name;
ExprSequence nameExpr;
- string contentExpr;
- ExprSequence content;
+ string contentLiteral;
public XmlPIConstructor (string name, string content)
+ : base (null)
{
+ this.name = name;
+ this.contentLiteral = content;
}
public XmlPIConstructor (string name, ExprSequence content)
+ : base (content)
{
+ this.name = name;
}
public XmlPIConstructor (ExprSequence name, ExprSequence content)
+ : base (content)
+ {
+ this.nameExpr = name;
+ }
+
+ internal override void CheckReference (XQueryASTCompiler compiler)
+ {
+ if (nameExpr != null)
+ nameExpr.CheckReference (compiler);
+ if (Content != null)
+ Content.CheckReference (compiler);
+ }
+
+#region CompileAndEvaluate
+ internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
+ {
+ if (NameExpr != null)
+ for (int i = 0; i < NameExpr.Count; i++)
+ NameExpr [i] = NameExpr [i].Compile (compiler);
+ if (Content != null)
+ for (int i = 0; i < Content.Count; i++)
+ Content [i] = Content [i].Compile (compiler);
+ return this;
+ }
+
+ public string Name {
+ get { throw new NotImplementedException (); }
+ }
+ public ExprSequence NameExpr {
+ get { throw new NotImplementedException (); }
+ }
+
+ // FIXME: can be optimized by checking all items in Expr
+ public override SequenceType StaticType {
+ get { return SequenceType.XmlPI; }
+ }
+
+ public override void Serialize (XPathSequence iter)
+ {
+ iter.Context.Writer.WriteProcessingInstruction (
+ GetName (iter),
+ Atomize (new ExprSequenceIterator (iter, Content)).Value);
+ }
+
+ public override XPathSequence Evaluate (XPathSequence iter)
+ {
+ throw new NotImplementedException ();
+ }
+
+ private string GetName (XPathSequence iter)
{
+ if (Name != String.Empty)
+ return Name;
+ return Atomize (new ExprSequenceIterator (iter, NameExpr)).Value;
}
+#endregion
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+
+//
+// FIXME:
+// attribute value template
+// handle double literal
+//
+
#if NET_2_0
using System;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Security.Policy;
-using Mono.Xml.XQuery.SyntaxTree;
using Mono.Xml.XPath2;
using Mono.Xml.XQuery;
namespace Mono.Xml.XQuery.Parser
{
- public class XQueryParser
+ internal class XQueryParser
{
// FIXME: Wait for recommendation
public const string XdtNamespace = "http://www.w3.org/2003/11/xpath-datatypes";
reservedFunctionNames.Add ("typeswitch", "typeswitch");
}
+ public static XQueryModule Parse (TextReader reader)
+ {
+ return new XQueryParser ().RunParse (reader);
+ }
+
private XQueryTokenizer tokenizer;
- public XQueryParser ()
+ private XQueryParser ()
{
}
- public XQueryModule Parse (TextReader source, Evidence evidence)
+ // FIXME: we don't need Evidence here at all. It is used only
+ // to generate runnable IL (on loading resulting Assembly).
+ public XQueryModule RunParse (TextReader source)
{
tokenizer = null;
try {
// debug = new yydebug.yyDebugSimple ();
- tokenizer = new XQueryTokenizer (source, evidence);
- return (XQueryModule) yyparse (tokenizer);
+ tokenizer = new XQueryTokenizer (source);
+ XQueryModule mod = (XQueryModule) yyparse (tokenizer);
+ mod.NSResolver = tokenizer.NSResolver;
+ return mod;
} catch (yyParser.yyException ex) {
throw new XmlQueryCompileException (String.Format ("Tokenizer error at line {0}, column {1}: {2}", tokenizer.LineNumber, tokenizer.LinePosition, ex.Message), ex);
}
%token WILD_PREFIX
%token STRING_LITERAL
-%token NUMERIC_LITERAL
+%token DECIMAL_LITERAL
+%token DOUBLE_LITERAL
%token PRAGMA_CONTENTS // characters until "::)"
tokenizer.State = ParseState.Default;
}
{
+ tokenizer.DefaultFunctionNamespace = (string) $5;
$$ = new SimplePrologContent (PrologContentType.DefaultFunctionNamespace, (string) $5);
}
;
tokenizer.State = ParseState.Operator;
} OptionalTypeDeclaration VarDeclBody
{
- $$ = new VariableDeclaration ((XmlQualifiedName) $4, (SequenceType) $5, (ExprSequence) $6);
+ $$ = new XQueryVariable ((XmlQualifiedName) $4, (SequenceType) $5, (ExprSequence) $6);
}
;
SequenceType // returns SequenceType
: ItemType OptionalOccurenceIndicator
{
- $$ = new SequenceType ((NodeKindTestExpr) $1, (Occurence) $2);
+ $$ = new SequenceType ((ItemType) $1, (Occurence) $2);
}
| EMPTY OPEN_PAREN CLOSE_PAREN {
tokenizer.State = ParseState.Operator;
}
{
- $$ = new SequenceType (null, Occurence.ZeroOrMore);
+ $$ = SequenceType.Create (XmlTypeCode.None, Occurence.One);
}
;
: ExprSequence
{
ExprSequence seq = (ExprSequence) $1;
- seq.Reverse ();
$$ = seq;
}
;
| ExprSingle COMMA ExprSequence
{
ExprSequence seq = (ExprSequence) $3;
- seq.Add ((ExprSingle) $1);
+ seq.Insert (0, (ExprSingle) $1);
$$ = seq;
}
;
} ExprSingle
{
ForLetClauseCollection col = (ForLetClauseCollection) $1;
- col.Reverse ();
$$ = new FLWORExpr (col, (ExprSequence) $2, (OrderSpecList) $3, (ExprSingle) $5);
}
;
| ForLetClause RepeatedForLetClause
{
ForLetClauseCollection col = (ForLetClauseCollection) $2;
- col.Add ((ForLetClause) $1);
+ col.Insert (0, (ForLetClause) $1);
$$ = col;
}
;
: FOR ForBody
{
ForClause fc = (ForClause) $2;
- fc.Reverse ();
$$ = fc;
}
;
| ForSingleBody COMMA ForBody
{
ForClause fc = (ForClause) $3;
- fc.Add ((ForSingleBody) $1);
+ fc.Insert (0, (ForSingleBody) $1);
$$ = fc;
}
;
: LET LetBody
{
LetClause let = (LetClause) $2;
- let.Reverse ();
$$ = let;
}
;
| LetSingleBody COMMA LetBody
{
LetClause let = (LetClause) $3;
- let.Add ((LetSingleBody) $1);
+ let.Insert (0, (LetSingleBody) $1);
$$ = let;
}
} OrderSpecList
{
OrderSpecList l = (OrderSpecList) $4;
- l.Reverse ();
$$ = l;
}
| STABLE ORDER BY {
{
OrderSpecList l = (OrderSpecList) $5;
l.IsStable = true;
- l.Reverse ();
$$ = l;
}
;
| OrderSpec COMMA OrderSpecList
{
OrderSpecList l = (OrderSpecList) $3;
- l.Add ((OrderSpec) $1);
+ l.Insert (0, (OrderSpec) $1);
$$ = l;
}
;
: SOME QuantifiedExprBody SATISFIES ExprSingle
{
QuantifiedExprBodyList l = (QuantifiedExprBodyList) $2;
- l.Reverse ();
$$ = new QuantifiedExpr (false, l, (ExprSingle) $4);
}
| EVERY QuantifiedExprBody SATISFIES ExprSingle
{
QuantifiedExprBodyList l = (QuantifiedExprBodyList) $2;
- l.Reverse ();
$$ = new QuantifiedExpr (true, l, (ExprSingle) $4);
}
;
| SingleQuantifiedExprBody COMMA QuantifiedExprBody
{
QuantifiedExprBodyList l = (QuantifiedExprBodyList) $3;
- l.Add ((QuantifiedExprBody) $1);
+ l.Insert (0, (QuantifiedExprBody) $1);
$$ = l;
}
;
tokenizer.State = ParseState.Default;
} UnionExpr
{
- $$ = new UnionExpr ((ExprSingle) $1, (ExprSingle) $4);
+ $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Union);
}
| IntersectExceptExpr BAR {
tokenizer.State = ParseState.Default;
} UnionExpr
{
- $$ = new UnionExpr ((ExprSingle) $1, (ExprSingle) $4);
+ $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Union);
}
;
tokenizer.State = ParseState.Default;
} IntersectExceptExpr
{
- $$ = new IntersectExpr ((ExprSingle) $1, (ExprSingle) $4);
+ $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Intersect);
}
| ValueExpr EXCEPT {
tokenizer.State = ParseState.Default;
} IntersectExceptExpr
{
- $$ = new ExceptExpr ((ExprSingle) $1, (ExprSingle) $4);
+ $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Except);
}
;
PathExpr // returns PathExpr
: Slash
{
- $$ = new PathExprRoot ();
+ $$ = new PathRootExpr ();
}
| Slash RelativePathExpr
{
- $$ = new PathExprChild (new PathExprRoot (), (ExprSingle) $2);
+ $$ = new PathChildExpr (new PathRootExpr (), (ExprSingle) $2);
}
| Slash2 RelativePathExpr
{
- $$ = new PathExprDescendant (new PathExprRoot (), (ExprSingle) $2);
+ $$ = new PathDescendantExpr (new PathRootExpr (), (ExprSingle) $2);
}
| RelativePathExpr
;
: StepExpr
| StepExpr Slash RelativePathExpr
{
- $$ = new PathExprChild ((ExprSingle) $1, (ExprSingle) $3);
+ $$ = new PathChildExpr ((ExprSingle) $1, (ExprSingle) $3);
}
| StepExpr Slash2 RelativePathExpr
{
- $$ = new PathExprDescendant ((ExprSingle) $1, (ExprSingle) $3);
+ $$ = new PathDescendantExpr ((ExprSingle) $1, (ExprSingle) $3);
}
;
AxisStep // returns PathExpr
: ForwardOrReverseStep Predicates
{
- ExprSequenceList p = (ExprSequenceList) $2;
+ PredicateList p = (PredicateList) $2;
if (p == null)
$$ = $1;
else
- $$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequenceList) $2);
+ $$ = new FilterStepExpr ((ExprSingle) $1, (PredicateList) $2);
}
;
if ($2 == null)
$$ = (ExprSingle) $1;
else
- $$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequenceList) $2);
+ $$ = new FilterStepExpr ((ExprSingle) $1, (PredicateList) $2);
}
;
-ForwardStep // returns NodeTestExpr
+ForwardStep // returns AxisStepExpr
: ForwardAxis NodeTest
{
- $$ = new AxisStepExpr ((XPathAxis) $1, (NodeTestExpr) $2);
+ $$ = new AxisStepExpr ((XPathAxis) $1, (XPath2NodeTest) $2);
}
| AbbrevForwardStep
;
-ReverseStep // returns NodeTestExpr
+ReverseStep // returns AxisStepExpr
: ReverseAxis NodeTest
+ {
+ $$ = new AxisStepExpr ((XPathAxis) $1, (XPath2NodeTest) $2);
+ }
| AbbrevReverseStep
;
// should not appear after AT. (imagine @processing-instruction::(name)).
AbbrevForwardStep // returns NodeTestExpr
: NodeTest
+ {
+ $$ = new AxisStepExpr (XPathAxis.Child, (XPath2NodeTest) $1);
+ }
| AT NameTest
{
- $$ = new AttributeTestExpr ((XmlQualifiedName) $2);
+ $$ = new AxisStepExpr (XPathAxis.Attribute, new XPath2NodeTest ((XmlQualifiedName) $2));
}
;
-AbbrevReverseStep // returns NodeTestExpr
+AbbrevReverseStep // returns AxisStepExpr
: DOT2
{
$$ = AxisStepExpr.ParentStep;
}
;
-Predicates // returns ExprSequenceList or null
+Predicates // returns PredicateList or null
: // empty
{
$$ = null;
tokenizer.State = ParseState.Operator;
} Predicates
{
- ExprSequenceList l = (ExprSequenceList) $5;
+ PredicateList l = (PredicateList) $5;
if (l == null)
- l = new ExprSequenceList ();
+ l = new PredicateList ();
l.Insert (0, (ExprSequence) $2);
$$ = l;
}
;
-NodeTest // returns NodeTestExpr
+NodeTest // returns NodeTest
: KindTest
+ {
+ $$ = new XPath2NodeTest ((KindTest) $1);
+ }
| NameTest
{
- $$ = new AxisStepExpr (XPathAxis.Child, new NodeNameTestExpr ((XmlQualifiedName) $1));
+ $$ = new XPath2NodeTest ((XmlQualifiedName) $1);
}
;
}
;
-ItemType // returns NodeTestExpr
+ItemType // returns ItemType
: AtomicType {
tokenizer.State = ParseState.OccurenceIndicator;
}
{
- $$ = new NodeKindTestExpr ((XmlTypeCode) $1);
+ $$ = new ItemType ((XmlTypeCode) $1);
}
| KindTest
| ITEM OPEN_PAREN CLOSE_PAREN {
tokenizer.State = ParseState.OccurenceIndicator;
}
{
- $$ = new NodeKindTestExpr (XmlTypeCode.Item);
+ $$ = new ItemType (XmlTypeCode.Item);
}
;
-KindTest // returns NodeTestExpr
+KindTest // returns KindTest
: DocumentTest
| ElementTest
| AttributeTest
}
;
-PITestContent // returns NodeKindTestExpr
+PITestContent // returns KindTest
: // empty
{
- $$ = new NodeKindTestExpr (XmlTypeCode.ProcessingInstruction);
+ $$ = new KindTest (XmlTypeCode.ProcessingInstruction);
}
| NCName
{
- $$ = new XmlPITestExpr ((string) $1);
+ $$ = new XmlPITest ((string) $1);
}
| STRING_LITERAL
{
- $$ = new XmlPITestExpr ((string) $1);
+ $$ = new XmlPITest ((string) $1);
}
;
tokenizer.PopState ();
}
{
- $$ = new NodeKindTestExpr (XmlTypeCode.Comment);
+ $$ = new KindTest (XmlTypeCode.Comment);
}
;
tokenizer.PopState ();
}
{
- $$ = new NodeKindTestExpr (XmlTypeCode.Text);
+ $$ = new KindTest (XmlTypeCode.Text);
}
;
tokenizer.PopState ();
}
{
- $$ = new NodeKindTestExpr (XmlTypeCode.Node);
+ $$ = new KindTest (XmlTypeCode.Node);
}
;
-DocumentTest // returns DocumentTestExpr
+DocumentTest // returns DocumentTest
: DOCUMENT_NODE OPEN_PAREN {
tokenizer.PushState (ParseState.OccurenceIndicator);
tokenizer.State = ParseState.KindTest;
}
;
-DocumentTestContent // returns DocumentTestExpr
+DocumentTestContent // returns DocumentTest
: // empty
{
- $$ = new DocumentTestExpr (null);
+ $$ = new KindTest (XmlTypeCode.Document);
}
| ElementTest
{
- $$ = new DocumentTestExpr ((ElementTestExpr) $1);
+ $$ = new DocumentTest ((ElementTest) $1);
}
;
-ElementTest // returns ElementTestExpr
+ElementTest // returns ElementTest
: ELEMENT OPEN_PAREN {
tokenizer.PushState (ParseState.OccurenceIndicator);
tokenizer.State = ParseState.KindTest;
}
;
-ElementTestContent // returns ElementTestExpr
+ElementTestContent // returns ElementTest
: // empty
{
- $$ = null;
+ $$ = new KindTest (XmlTypeCode.Element);
}
| ElementNameOrWildcard
{
- $$ = new ElementTestExpr ((XmlQualifiedName) $1);
+ $$ = new ElementTest ((XmlQualifiedName) $1);
}
| ElementNameOrWildcard COMMA TypeName OptionalQuestion
{
- $$ = new ElementTestExpr ((XmlQualifiedName) $1, (XmlQualifiedName) $3, (bool) $4);
+ $$ = new ElementTest ((XmlQualifiedName) $1, (XmlQualifiedName) $3, (bool) $4);
}
;
}
;
-AttributeTest // returns AttributeTestExpr
+AttributeTest // returns AttributeTest
: ATTRIBUTE OPEN_PAREN {
tokenizer.PushState (ParseState.OccurenceIndicator);
tokenizer.State = ParseState.KindTest;
}
;
-AttributeTestContent // returns AttributeTestExpr
+AttributeTestContent // returns AttributeTest
: // empty
{
- $$ = AttributeTestExpr.AnyAttribute;
+ $$ = AttributeTest.AnyAttribute;
}
| AttributeNameOrWildcard
{
- $$ = new AttributeTestExpr ((XmlQualifiedName) $1);
+ $$ = new AttributeTest ((XmlQualifiedName) $1);
}
| AttributeNameOrWildcard COMMA TypeNameOrWildcard
{
- $$ = new AttributeTestExpr ((XmlQualifiedName) $1, (XmlQualifiedName) $3);
+ $$ = new AttributeTest ((XmlQualifiedName) $1, (XmlQualifiedName) $3);
}
;
| ContextItemExpr
| FunctionCall
| Constructor
+ | OrderedExpr
+ | UnorderedExpr
;
Literal
- : NUMERIC_LITERAL
+ : DECIMAL_LITERAL
+ {
+ $$ = new DecimalLiteralExpr ((decimal) $1);
+ }
+ | DOUBLE_LITERAL
{
- $$ = new NumberLiteralExpr ((decimal) $1);
+ $$ = new DoubleLiteralExpr ((double) $1);
}
| STRING_LITERAL
{
}
{
XmlQualifiedName name = (XmlQualifiedName) $1;
+ if (name.Namespace == "")
+ name = new XmlQualifiedName (name.Name, tokenizer.DefaultFunctionNamespace);
if (name.Namespace != ""
&& name.Namespace != XmlSchema.XdtNamespace
&& reservedFunctionNames [name.Name] != null)
}
;
+OrderedExpr
+ : ORDERED OPEN_BRACKET Expr CLOSE_BRACKET
+ {
+ $$ = new OrderSpecifiedExpr ((ExprSequence) $3, true);
+ }
+ ;
+
+UnorderedExpr
+ : UNORDERED OPEN_BRACKET {
+ tokenizer.PushState (ParseState.Operator);
+ tokenizer.State = ParseState.Default;
+ } Expr CLOSE_BRACKET {
+ tokenizer.PopState ();
+ }
+ {
+ $$ = new OrderSpecifiedExpr ((ExprSequence) $4, false);
+ }
+ ;
+
+
/* -----------------
Constructors
----------------- */
| XmlCData
;
-DirElemConstructor // returns ElementConstructor
+DirElemConstructor // returns XmlElemConstructor
: LESSER {
if (tokenizer.State == ParseState.ElementContent)
tokenizer.PushState (tokenizer.State);
tokenizer.PopState ();
}
{
- $$ = new ElementConstructor ((XmlQualifiedName) $3, (AttributeConstructorList) $4, (ExprSequence) $5);
+ ExprSequence expr = new ExprSequence ();
+ expr.AddRange ((ICollection) $4);
+ expr.AddRange ((ICollection) $5);
+ $$ = new XmlElemConstructor ((XmlQualifiedName) $3, expr);
}
;
}
;
-AttributeList // returns AttributeConstructorList
+AttributeList // returns XmlAttrConstructorList
: // empty
{
- $$ = new AttributeConstructorList ();
+ $$ = new XmlAttrConstructorList ();
}
| /* space */ Attribute AttributeList
{
- AttributeConstructorList al = (AttributeConstructorList) $2;
- al.Insert (0, (AttributeConstructor) $1);
+ XmlAttrConstructorList al = (XmlAttrConstructorList) $2;
+ al.Insert (0, (XmlAttrConstructor) $1);
$$ = al;
}
;
-Attribute // returns AttributeConstructor
+Attribute // returns XmlAttrConstructor
: QName EQUAL AttributeValue /* note: whitespace handling */
{
- $$ = new AttributeConstructor ((XmlQualifiedName) $1, (ExprSequence) $3);
+ $$ = new XmlAttrConstructor ((XmlQualifiedName) $1, (ExprSequence) $3);
}
;