Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 30662 Details for
Bug 75102
[patch]
updated with sickings comments, the diff, against current tip
lexx_n_parse.diff (text/plain), 137.08 KB, created by
Axel Hecht
(
hide
)
Description:
updated with sickings comments, the diff, against current tip
Filename:
MIME Type:
Creator:
Axel Hecht
Size:
137.08 KB
patch
obsolete
>? source/xpath/UnaryExpr.cpp >? source/xpath/NCNameChar.h >? source/xpath/Letter.h >? source/xpath/Expr.cpp >Index: build/Makefile.in >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/build/Makefile.in,v >retrieving revision 1.12 >diff -u -r1.12 Makefile.in >--- Makefile.in 2001/04/08 14:33:16 1.12 >+++ Makefile.in 2001/04/12 22:47:35 >@@ -75,12 +75,12 @@ > ../source/xpath/BooleanResult.o \ > ../source/xpath/ElementExpr.o \ > ../source/xpath/ErrorFunctionCall.o \ >+ ../source/xpath/Expr.o \ > ../source/xpath/ExprLexer.o \ > ../source/xpath/ExprParser.o \ > ../source/xpath/ExtensionFunctionCall.o \ > ../source/xpath/FilterExpr.o \ > ../source/xpath/FunctionCall.o \ >- ../source/xpath/IdentityExpr.o \ > ../source/xpath/LocationStep.o \ > ../source/xpath/MultiplicativeExpr.o \ > ../source/xpath/NodeSet.o \ >@@ -89,7 +89,6 @@ > ../source/xpath/NumberExpr.o \ > ../source/xpath/NumberFunctionCall.o \ > ../source/xpath/NumberResult.o \ >- ../source/xpath/ParentExpr.o \ > ../source/xpath/PathExpr.o \ > ../source/xpath/PredicateList.o \ > ../source/xpath/RelationalExpr.o \ >@@ -99,6 +98,7 @@ > ../source/xpath/StringResult.o \ > ../source/xpath/TextExpr.o \ > ../source/xpath/UnionExpr.o \ >+ ../source/xpath/UnaryExpr.o \ > ../source/xpath/VariableRefExpr.o \ > ../source/xpath/XPathNames.o \ > ../source/xpath/XPathProcessor.o \ >Index: build/makefile.win >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/build/makefile.win,v >retrieving revision 1.15 >diff -u -r1.15 makefile.win >--- makefile.win 2001/04/08 14:32:53 1.15 >+++ makefile.win 2001/04/12 22:47:35 >@@ -76,12 +76,12 @@ > ..\source\xpath\$(OBJDIR)\BooleanResult.obj \ > ..\source\xpath\$(OBJDIR)\ElementExpr.obj \ > ..\source\xpath\$(OBJDIR)\ErrorFunctionCall.obj \ >+ ..\source\xpath\$(OBJDIR)\Expr.obj \ > ..\source\xpath\$(OBJDIR)\ExprLexer.obj \ > ..\source\xpath\$(OBJDIR)\ExprParser.obj \ > ..\source\xpath\$(OBJDIR)\ExtensionFunctionCall.obj \ > ..\source\xpath\$(OBJDIR)\FilterExpr.obj \ > ..\source\xpath\$(OBJDIR)\FunctionCall.obj \ >- ..\source\xpath\$(OBJDIR)\IdentityExpr.obj \ > ..\source\xpath\$(OBJDIR)\LocationStep.obj \ > ..\source\xpath\$(OBJDIR)\MultiplicativeExpr.obj \ > ..\source\xpath\$(OBJDIR)\NodeSet.obj \ >@@ -90,7 +90,6 @@ > ..\source\xpath\$(OBJDIR)\NumberExpr.obj \ > ..\source\xpath\$(OBJDIR)\NumberFunctionCall.obj \ > ..\source\xpath\$(OBJDIR)\NumberResult.obj \ >- ..\source\xpath\$(OBJDIR)\ParentExpr.obj \ > ..\source\xpath\$(OBJDIR)\PathExpr.obj \ > ..\source\xpath\$(OBJDIR)\PredicateList.obj \ > ..\source\xpath\$(OBJDIR)\RelationalExpr.obj \ >@@ -100,6 +99,7 @@ > ..\source\xpath\$(OBJDIR)\StringResult.obj \ > ..\source\xpath\$(OBJDIR)\TextExpr.obj \ > ..\source\xpath\$(OBJDIR)\UnionExpr.obj \ >+ ..\source\xpath\$(OBJDIR)\UnaryExpr.obj \ > ..\source\xpath\$(OBJDIR)\VariableRefExpr.obj \ > ..\source\xpath\$(OBJDIR)\XPathNames.obj \ > ..\source\xpath\$(OBJDIR)\XPathProcessor.obj \ >Index: source/main/Makefile.in >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/main/Makefile.in,v >retrieving revision 1.8 >diff -u -r1.8 Makefile.in >--- Makefile.in 2001/04/08 14:35:10 1.8 >+++ Makefile.in 2001/04/12 22:47:35 >@@ -70,12 +70,12 @@ > ../xpath/BooleanResult.o \ > ../xpath/ElementExpr.o \ > ../xpath/ErrorFunctionCall.o \ >+ ../xpath/Expr.o \ > ../xpath/ExprLexer.o \ > ../xpath/ExprParser.o \ > ../xpath/ExtensionFunctionCall.o \ > ../xpath/FilterExpr.o \ > ../xpath/FunctionCall.o \ >- ../xpath/IdentityExpr.o \ > ../xpath/LocationStep.o \ > ../xpath/MultiplicativeExpr.o \ > ../xpath/NodeSet.o \ >@@ -83,7 +83,6 @@ > ../xpath/NumberExpr.o \ > ../xpath/NumberFunctionCall.o \ > ../xpath/NumberResult.o \ >- ../xpath/ParentExpr.o \ > ../xpath/PathExpr.o \ > ../xpath/PredicateList.o \ > ../xpath/RelationalExpr.o \ >@@ -93,6 +92,7 @@ > ../xpath/StringResult.o \ > ../xpath/TextExpr.o \ > ../xpath/UnionExpr.o \ >+ ../xpath/UnaryExpr.o \ > ../xpath/VariableRefExpr.o \ > ../xpath/XPathNames.o \ > ../xml/XMLUtils.o \ >Index: source/main/makefile.win >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/main/makefile.win,v >retrieving revision 1.5 >diff -u -r1.5 makefile.win >--- makefile.win 2001/04/08 14:37:34 1.5 >+++ makefile.win 2001/04/12 22:47:35 >@@ -67,12 +67,12 @@ > ../xpath/$(OBJDIR)/BooleanResult.obj \ > ../xpath/$(OBJDIR)/ElementExpr.obj \ > ../xpath/$(OBJDIR)/ErrorFunctionCall.obj \ >+ ../xpath/$(OBJDIR)/Expr.obj \ > ../xpath/$(OBJDIR)/ExprLexer.obj \ > ../xpath/$(OBJDIR)/ExprParser.obj \ > ../xpath/$(OBJDIR)/ExtensionFunctionCall.obj \ > ../xpath/$(OBJDIR)/FilterExpr.obj \ > ../xpath/$(OBJDIR)/FunctionCall.obj \ >- ../xpath/$(OBJDIR)/IdentityExpr.obj \ > ../xpath/$(OBJDIR)/LocationStep.obj \ > ../xpath/$(OBJDIR)/MultiplicativeExpr.obj \ > ../xpath/$(OBJDIR)/NodeSet.obj \ >@@ -80,7 +80,6 @@ > ../xpath/$(OBJDIR)/NumberExpr.obj \ > ../xpath/$(OBJDIR)/NumberFunctionCall.obj \ > ../xpath/$(OBJDIR)/NumberResult.obj \ >- ../xpath/$(OBJDIR)/ParentExpr.obj \ > ../xpath/$(OBJDIR)/PathExpr.obj \ > ../xpath/$(OBJDIR)/PredicateList.obj \ > ../xpath/$(OBJDIR)/RelationalExpr.obj \ >@@ -90,6 +89,7 @@ > ../xpath/$(OBJDIR)/StringResult.obj \ > ../xpath/$(OBJDIR)/TextExpr.obj \ > ../xpath/$(OBJDIR)/UnionExpr.obj \ >+ ../xpath/$(OBJDIR)/UnaryExpr.obj \ > ../xpath/$(OBJDIR)/VariableRefExpr.obj \ > ../xpath/$(OBJDIR)/XPathNames.obj \ > ../xml/$(OBJDIR)/XMLUtils.obj \ >Index: source/xpath/BasicNodeExpr.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/BasicNodeExpr.cpp,v >retrieving revision 1.3 >diff -u -r1.3 BasicNodeExpr.cpp >--- BasicNodeExpr.cpp 2001/04/11 15:00:57 1.3 >+++ BasicNodeExpr.cpp 2001/04/12 22:47:35 >@@ -38,6 +38,7 @@ > **/ > BasicNodeExpr::BasicNodeExpr() { > this->type = NodeExpr::NODE_EXPR; >+ nodeNameSet = MB_FALSE; > } //-- BasicNodeExpr > > /** >@@ -45,6 +46,7 @@ > **/ > BasicNodeExpr::BasicNodeExpr(NodeExpr::NodeExprType nodeExprType) { > this->type = nodeExprType; >+ nodeNameSet = MB_FALSE; > } //-- BasicNodeExpr > > /** >@@ -56,6 +58,15 @@ > //- Public Methods -/ > //------------------/ > >+void BasicNodeExpr::setNodeName(const String& name) { >+ this->nodeName = name; >+ nodeNameSet = MB_TRUE; >+} >+ >+ //-----------------------------/ >+ //- Methods from NodeExpr.cpp -/ >+//-----------------------------/ >+ > /** > * Evaluates this Expr based on the given context node and processor state > * @param context the context node for evaluation of this Expr >@@ -74,17 +85,12 @@ > return nodeSet; > } //-- evaluate > >- //-----------------------------/ >- //- Methods from NodeExpr.cpp -/ >-//-----------------------------/ >- > /** >- * Returns the default priority of this Pattern based on the given Node, >+ * Returns the default priority of this Expr based on the given Node, > * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. > **/ > double BasicNodeExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { >+ if (nodeNameSet) return 0; > return -0.5; > } //-- getDefaultPriority > >@@ -106,7 +112,8 @@ > case NodeExpr::COMMENT_EXPR: > return (MBool) (node->getNodeType() == Node::COMMENT_NODE); > case NodeExpr::PI_EXPR : >- return (MBool) (node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE); >+ return (MBool) (node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE && >+ !nodeNameSet || nodeName.isEqual(node->getNodeName())); > default: //-- node() > if(node->getNodeType() == Node::TEXT_NODE) > return !cs->isStripSpaceAllowed(node); >@@ -132,7 +139,13 @@ > dest.append("comment()"); > break; > case NodeExpr::PI_EXPR : >- dest.append("processing-instruction()"); >+ dest.append("processing-instruction("); >+ if (nodeNameSet) { >+ dest.append('\''); >+ dest.append(nodeName); >+ dest.append('\''); >+ } >+ dest.append(')'); > break; > default: //-- node() > dest.append("node()"); >Index: source/xpath/Expr.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/Expr.h,v >retrieving revision 1.11 >diff -u -r1.11 Expr.h >--- Expr.h 2001/04/11 15:00:57 1.11 >+++ Expr.h 2001/04/12 22:47:35 >@@ -24,6 +24,9 @@ > * -- 19990806 > * - changed constant short declarations in many of the classes > * with enumerations, commented with //--LF >+ * Jonas Sicking, sicking@bigfoot.com >+ * -- removal of Patterns and some restructuring >+ * in the class set > * > * $Id: Expr.h,v 1.11 2001/04/11 15:00:57 axel%pike.org Exp $ > */ >@@ -52,6 +55,10 @@ > //necessary prototypes > class FunctionCall; > >+typedef class Expr Pattern; >+typedef class Expr PatternExpr; >+ >+ > /** > * The expression context and state class used when evaluating XPath Expressions. > **/ >@@ -115,7 +122,7 @@ > /** > * Virtual destructor, important for subclasses > **/ >- virtual ~Expr() {}; >+ virtual ~Expr(); > > /** > * Evaluates this Expr based on the given context node and processor state >@@ -127,6 +134,18 @@ > virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; > > /** >+ * Determines whether this Expr matches the given node within >+ * the given context >+ **/ >+ virtual MBool matches(Node* node, Node* context, ContextState* cs); >+ >+ /** >+ * Returns the default priority of this Expr based on the given Node, >+ * context Node, and ContextState. >+ **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >+ >+ /** > * Returns the String representation of this Expr. > * @param dest the String to use when creating the String > * representation. The String representation will be appended to >@@ -138,7 +157,6 @@ > > }; //-- Expr > >- > /** > * This class represents a FunctionCall as defined by the XPath 1.0 > * Recommendation. >@@ -149,23 +167,21 @@ > > static const String INVALID_PARAM_COUNT; > >- > virtual ~FunctionCall(); > > /** >- * Adds the given parameter to this FunctionCall's parameter list >- * @param expr the Expr to add to this FunctionCall's parameter list >+ * Virtual methods from Expr > **/ >- void addParam(Expr* expr); >+ virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; >+ virtual MBool matches(Node* node, Node* context, ContextState* cs); >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >+ virtual void toString(String& dest); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Adds the given parameter to this FunctionCall's parameter list >+ * @param expr the Expr to add to this FunctionCall's parameter list > **/ >- virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; >+ void addParam(Expr* expr); > > /** > * Returns the name of this FunctionCall >@@ -184,15 +200,6 @@ > * @param name the name of this Function > **/ > void setName(const String& name); >- /** >- * Returns the String representation of this Pattern. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Pattern. >- **/ >- virtual void toString(String& dest); > > > protected: >@@ -221,97 +228,8 @@ > String name; > }; //-- FunctionCall > >-/** >- * A base Pattern class >-**/ >-class Pattern { >- >-public: >- >- /** >- * Virtual destructor, important for subclasses >- **/ >- virtual ~Pattern() {}; >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; >- >- /** >- * Determines whether this Pattern matches the given node within >- * the given context >- **/ >- virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; >- >- >- /** >- * Returns the String representation of this Pattern. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Pattern. >- **/ >- virtual void toString(String& dest) = 0; >- >-}; //-- Pattern > >- > /** >- * A Base class for all Expressions and Patterns >-**/ >-class PatternExpr : >- public Expr, >- public Pattern >-{ >- >-public: >- >- /** >- * Virtual destructor, important for subclasses >- **/ >- virtual ~PatternExpr() {}; >- >- /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >- **/ >- virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; >- >- /** >- * Determines whether this PatternExpr matches the given node within >- * the given context >- **/ >- virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >- virtual void toString(String& dest) = 0; >- >-}; //-- PatternExpr >- >-/** > * Represents an AttributeValueTemplate > **/ > class AttributeValueTemplate: public Expr { >@@ -328,22 +246,9 @@ > void addExpr(Expr* expr); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > private: >@@ -355,7 +260,7 @@ > * This class represents a NodeTestExpr as defined by the XSL > * Working Draft > **/ >-class NodeExpr : public PatternExpr { >+class NodeExpr : public Expr { > > public: > >@@ -379,33 +284,16 @@ > //------------------/ > > /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; >- >- /** > * Returns the type of this NodeExpr > * @return the type of this NodeExpr > **/ > virtual short getType() = 0; > > /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >+ * Virtual methods from Expr > **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; >- >- /** >- * Returns the String representation of this Pattern. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Pattern. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; > virtual void toString(String& dest) = 0; > > }; //-- NodeExpr >@@ -440,47 +328,13 @@ > **/ > void setName(const String& name); > >- //-----------------------------------/ >- //- Method signatures from NodeExpr -/ >- //-----------------------------------/ >- > /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >+ * Virtual methods from NodeExpr > **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >- **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the type of this NodeExpr >- * @return the type of this NodeExpr >- **/ > short getType(); >- >- /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: >@@ -521,52 +375,25 @@ > * Destroys this BasicNodeExpr > **/ > virtual ~BasicNodeExpr(); >- >- //-----------------------------------/ >- //- Method signatures from NodeExpr -/ >- //-----------------------------------/ >- >+ > /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >+ * Sets the name of the node to match. Only availible for pi nodes > **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >+ void setNodeName(const String& name); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from NodeExpr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the type of this NodeExpr >- * @return the type of this NodeExpr >- **/ > short getType(); >- >- /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: > NodeExprType type; >+ String nodeName; >+ MBool nodeNameSet; > }; //-- BasicNodeExpr > > /** >@@ -597,47 +424,13 @@ > **/ > void setName(const String& name); > >- //-----------------------------------/ >- //- Method signatures from NodeExpr -/ >- //-----------------------------------/ >- > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from NodeExpr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the type of this NodeExpr >- * @return the type of this NodeExpr >- **/ > short getType(); >- >- /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >- **/ > virtual void toString(String& dest); > > private: >@@ -655,121 +448,23 @@ > }; //-- ElementExpr > > /** >- * This class represents a IdentityExpr, which only matches a node >- * if it is equal to the context node >-**/ >-class IdentityExpr : public Expr { >- >-public: >- >- //------------------/ >- //- Public Methods -/ >- //------------------/ >- >- /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >- **/ >- virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >- **/ >- virtual void toString(String& dest); >- >-}; //-- IdentityExpr >- >-/** >- * This class represents a ParentExpr, which only selects a node >- * if it is equal to the context node's parent >-**/ >-class ParentExpr : public Expr { >- >-public: >- >- //------------------/ >- //- Public Methods -/ >- //------------------/ >- >- /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >- **/ >- virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- >- /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >- **/ >- virtual void toString(String& dest); >- >-}; //-- ParentExpr >- >-/** > * This class represents a TextExpr, which only matches any text node >-**/ >-class TextExpr : public NodeExpr { >- >-public: >- >- //------------------/ >- //- Public Methods -/ >- //------------------/ >- >- /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >- **/ >- virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the type of this NodeExpr >- * @return the type of this NodeExpr >- **/ >- virtual short getType(); >- >- /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >- **/ >- virtual MBool matches(Node* node, Node* context, ContextState* cs); >+**/ >+class TextExpr : public NodeExpr { >+ >+public: > >+ //------------------/ >+ //- Public Methods -/ >+ //------------------/ > > /** >- * Returns the String representation of this NodeExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this NodeExpr. >+ * Virtual methods from NodeExpr > **/ >+ virtual ExprResult* evaluate(Node* context, ContextState* cs); >+ virtual short getType(); >+ virtual MBool matches(Node* node, Node* context, ContextState* cs); >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > }; //-- TextExpr >@@ -827,7 +522,7 @@ > List predicates; > }; //-- PredicateList > >-class LocationStep : public PredicateList, public PatternExpr { >+class LocationStep : public PredicateList, public Expr { > > public: > >@@ -887,47 +582,18 @@ > **/ > void setNodeExpr(NodeExpr* nodeExpr); > >- //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >- //------------------------------------/ >- > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Determines whether this PatternExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: > >- NodeExpr* nodeExpr; >- short axisIdentifier; >+ NodeExpr* nodeExpr; >+ short axisIdentifier; > > void fromDescendants(Node* context, ContextState* cs, NodeSet* nodes); > void fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes); >@@ -935,7 +601,7 @@ > }; //-- LocationStep > > >-class FilterExpr : public PredicateList, public PatternExpr { >+class FilterExpr : public PredicateList, public Expr { > > public: > >@@ -962,46 +628,17 @@ > **/ > void setExpr(Expr* expr); > >- //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >- //------------------------------------/ >- > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Determines whether this PatternExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: > >- Expr* expr; >+ Expr* expr; > > }; //-- FilterExpr > >@@ -1015,22 +652,9 @@ > ~NumberExpr(); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > private: >@@ -1051,22 +675,9 @@ > ~StringExpr(); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > private: >@@ -1105,22 +716,9 @@ > > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > >@@ -1132,6 +730,32 @@ > }; //-- AdditiveExpr > > /** >+ * Represents an UnaryExpr. >+**/ >+class UnaryExpr : public Expr { >+ >+public: >+ >+ UnaryExpr(); >+ UnaryExpr(Expr* expr); >+ ~UnaryExpr(); >+ >+ /** >+ * Sets the expression to negate >+ **/ >+ void setExpr(Expr* expr); >+ >+ /** >+ * Virtual methods from Expr >+ **/ >+ virtual ExprResult* evaluate(Node* context, ContextState* cs); >+ virtual void toString(String& str); >+ >+private: >+ Expr* expr; >+}; //-- UnaryExpr >+ >+/** > * Represents a BooleanExpr, a binary expression that > * performs a boolean operation between it's lvalue and rvalue:<BR/> > **/ >@@ -1147,33 +771,20 @@ > ~BooleanExpr(); > > /** >- * Sets the left side of this AdditiveExpr >+ * Sets the left side of this BooleanExpr > **/ > void setLeftExpr(Expr* leftExpr); > > /** >- * Sets the right side of this AdditiveExpr >+ * Sets the right side of this BooleanExpr > **/ > void setRightExpr(Expr* rightExpr); > > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > >@@ -1214,28 +825,12 @@ > **/ > void setRightExpr(Expr* rightExpr); > >- > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > >- >- > private: > short op; > Expr* leftExpr; >@@ -1272,26 +867,11 @@ > ~RelationalExpr(); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > >- >- > private: > short op; > Expr* leftExpr; >@@ -1319,22 +899,9 @@ > void setName(const String& name); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this Expr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this Expr. >- **/ > virtual void toString(String& str); > > private: >@@ -1345,7 +912,7 @@ > /** > * Represents a PathExpr > **/ >-class PathExpr : public PatternExpr { >+class PathExpr : public Expr { > > public: > >@@ -1360,66 +927,37 @@ > PathExpr(); > > /** >- * Destructor, will delete all Pattern Expressions >+ * Destructor, will delete all Expressions > **/ > virtual ~PathExpr(); > > /** >- * Adds the PatternExpr to this PathExpr >+ * Adds the Expr to this PathExpr > * @param expr the Expr to add to this PathExpr > * @param index the index at which to add the given Expr > **/ >- void addPatternExpr(int index, PatternExpr* expr, short ancestryOp); >+ void addExpr(int index, Expr* expr, short ancestryOp); > > /** >- * Adds the PatternExpr to this PathExpr >+ * Adds the Expr to this PathExpr > * @param expr the Expr to add to this PathExpr > **/ >- void addPatternExpr(PatternExpr* expr, short ancestryOp); >+ void addExpr(Expr* expr, short ancestryOp); > > virtual MBool isAbsolute(); > >- //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >- //------------------------------------/ >- > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Determines whether this PatternExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: > > struct PathExprItem { >- PatternExpr* pExpr; >+ Expr* expr; > short ancestryOp; > }; > >@@ -1427,13 +965,13 @@ > > /** > * Selects from the descendants of the context node >- * all nodes that match the PatternExpr >+ * all nodes that match the Expr > * -- this will be moving to a Utility class > **/ >- void fromDescendants(PatternExpr* pExpr, >+ void evalDescendants(Expr* expr, > Node* context, > ContextState* cs, >- NodeSet* nodes); >+ NodeSet* resNodes); > > }; //-- PathExpr > >@@ -1449,47 +987,22 @@ > //------------------/ > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- virtual MBool isAbsolute(); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Determines whether this NodeExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > >+ virtual MBool isAbsolute(); >+ > > }; //-- RootExpr > > /** > * Represents a UnionExpr > **/ >-class UnionExpr : public PatternExpr { >+class UnionExpr : public Expr { > > public: > >@@ -1507,49 +1020,20 @@ > * Adds the PathExpr to this UnionExpr > * @param expr the Expr to add to this UnionExpr > **/ >- void addPathExpr(PathExpr* expr); >+ void addExpr(Expr* expr); > > /** > * Adds the PathExpr to this UnionExpr at the specified index > * @param expr the Expr to add to this UnionExpr > **/ >- void addPathExpr(int index, PathExpr* expr); >- >- //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >- //------------------------------------/ >+ void addExpr(int index, Expr* expr); > > /** >- * Evaluates this Expr based on the given context node and processor state >- * @param context the context node for evaluation of this Expr >- * @param ps the ContextState containing the stack information needed >- * for evaluation >- * @return the result of the evaluation >+ * Virtual methods from Expr > **/ > virtual ExprResult* evaluate(Node* context, ContextState* cs); >- >- /** >- * Returns the default priority of this Pattern based on the given Node, >- * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. >- **/ >- virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); >- >- /** >- * Determines whether this PatternExpr matches the given node within >- * the given context >- **/ > virtual MBool matches(Node* node, Node* context, ContextState* cs); >- >- /** >- * Returns the String representation of this PatternExpr. >- * @param dest the String to use when creating the String >- * representation. The String representation will be appended to >- * any data in the destination String, to allow cascading calls to >- * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >- **/ >+ virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); > virtual void toString(String& dest); > > private: >Index: source/xpath/ExprLexer.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/ExprLexer.cpp,v >retrieving revision 1.12 >diff -u -r1.12 ExprLexer.cpp >--- ExprLexer.cpp 2001/04/03 12:25:03 1.12 >+++ ExprLexer.cpp 2001/04/12 22:47:35 >@@ -1,4 +1,4 @@ >-/* >+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- > * The contents of this file are subject to the Mozilla Public > * License Version 1.1 (the "License"); you may not use this file > * except in compliance with the License. You may obtain a copy of >@@ -29,6 +29,9 @@ > * -- Fixed bug in parse method so that we make sure we check for > * axis identifier wild cards, such as ancestor::* > * >+ * Axel Hecht <axel@pike.org> >+ * -- big beating, general overhaul >+ * > * $Id: ExprLexer.cpp,v 1.12 2001/04/03 12:25:03 peterv%netscape.com Exp $ > */ > >@@ -40,16 +43,16 @@ > > #include "ExprLexer.h" > >- //---------------------------/ >- //- Implementation of Token -/ > //---------------------------/ >+//- Implementation of Token -/ >+//---------------------------/ > > > /** > * Default constructor for Token > **/ > Token::Token() { >- this->type =0; >+ this->type =0; > } //-- Token; > > /** >@@ -57,7 +60,7 @@ > * @param type, the type of Token being represented > **/ > Token::Token(short type) { >- this->type = type; >+ this->type = type; > } //-- Token; > > /** >@@ -66,34 +69,34 @@ > * @param type, the type of Token being represented > **/ > Token::Token(const String& value, short type) { >- this->type = type; >- //-- make copy of value String >- this->value = value; >+ this->type = type; >+ //-- make copy of value String >+ this->value = value; > } //-- Token > > Token::Token(UNICODE_CHAR uniChar, short type) { >- this->type = type; >- this->value.append(uniChar); >+ this->type = type; >+ this->value.append(uniChar); > } //-- Token > > /** > * Copy Constructor > **/ > Token::Token(const Token& token) { >- this->type = token.type; >- this->value = token.value; >+ this->type = token.type; >+ this->value = token.value; > } //-- Token > > /** > * Destructor for Token > **/ > Token::~Token() { >- //-- currently nothing is needed >+ //-- currently nothing is needed > } //-- ~Token > > >- //--------------------------------/ >- //- Implementation of ExprLexer -/ >+//--------------------------------/ >+//- Implementation of ExprLexer -/ > //-------------------------------/ > > /* >@@ -110,33 +113,24 @@ > const String ExprLexer::OR = "or"; > > //-- multiplicative operators >+const String ExprLexer::MULTIPLY= "*"; > const String ExprLexer::MODULUS = "mod"; > const String ExprLexer::DIVIDE = "div"; > >- > /** >- * The set of a XSL Expression Tokens >-**/ >-const Token ExprLexer::TOKENS[] = { >- >- //-- Nodetype tokens >- Token(ExprLexer::COMMENT, Token::COMMENT), >- Token(ExprLexer::NODE, Token::NODE), >- Token(ExprLexer::PI, Token::PI), >- Token(ExprLexer::TEXT, Token::TEXT), >- //-- boolean operators >- Token(ExprLexer::AND, Token::AND_OP), >- Token(ExprLexer::OR, Token::OR_OP), >- >- //-- multiplicative operators >- Token(ExprLexer::MODULUS, Token::MODULUS_OP), >- Token(ExprLexer::DIVIDE, Token::DIVIDE_OP) >+ * The set of Lexer error messages >+ **/ >+const String ExprLexer::error_message[] = { >+ "VariableReference expected", >+ "Operator expected", >+ "Literal is not closed", >+ ": not expected", >+ "! not expected, use != or not()", >+ "found a unkown character" > }; > >-const short ExprLexer::NUMBER_OF_TOKENS = 8; >- >- //---------------/ >- //- Contructors -/ >+//---------------/ >+//- Contructors -/ > //---------------/ > > /** >@@ -144,582 +138,375 @@ > **/ > ExprLexer::ExprLexer(const String& pattern) { > >- firstItem = 0; >- lastItem = 0; >- tokenCount = 0; >- prevToken = 0; >- parse(pattern); >- currentItem = firstItem; >+ firstItem = 0; >+ lastItem = 0; >+ tokenCount = 0; >+ prevToken = 0; >+ endToken.type = Token::END; >+ parse(pattern); >+ currentItem = firstItem; > } //-- ExprLexer > > /** > * Destroys this instance of an ExprLexer > **/ > ExprLexer::~ExprLexer() { >- //-- delete tokens >+ //-- delete tokens > >- //cout << "~ExprLexer() - start"<<endl; >- currentItem = firstItem; >- while ( currentItem ) { >- TokenListItem* temp = currentItem->next; >- //cout << "deleting token: " << currentItem->token->value << endl; >- delete currentItem->token; >- delete currentItem; >- currentItem = temp; >- } >- //cout << "~ExprLexer() - done"<<endl; >+ currentItem = firstItem; >+ while ( currentItem ) { >+ TokenListItem* temp = currentItem->next; >+ delete currentItem->token; >+ delete currentItem; >+ currentItem = temp; >+ } > } //-- ~ExprLexer > > >-int ExprLexer::countAllTokens() { >- return tokenCount; >-} //-- countAllTokens >- >-int ExprLexer::countRemainingTokens() { >- TokenListItem* temp = currentItem; >- int c = 0; >- while ( temp ) { >- ++c; >- temp = temp->next; >- } >- return c; >-} //-- countRemainingTokens >- >- > MBool ExprLexer::hasMoreTokens() { >- return (MBool) ( currentItem ); >+ return (MBool) ( currentItem ); > } //-- hasMoreTokens > > Token* ExprLexer::nextToken() { >- if ( currentItem ) { >- Token* token = currentItem->token; >- currentItem = currentItem->next; >- return token; >- } >- return 0; >+ if ( currentItem ) { >+ Token* token = currentItem->token; >+ currentItem = currentItem->next; >+ return token; >+ } >+ return &endToken; > } //-- nextToken > > void ExprLexer::pushBack() { >- if ( !currentItem ) { >- currentItem = lastItem; >- } >- else currentItem = currentItem->previous; >+ if ( !currentItem ) { >+ currentItem = lastItem; >+ } >+ else currentItem = currentItem->previous; > } //-- pushBack > >-/* >-Token* ExprLexer::lastToken() { >- if (lastItem) { >- return lastItem->token; >- } >- return 0; >-} //-- lastToken >-*/ >- > Token* ExprLexer::peek() { >- Token* token = 0; >- TokenListItem* tlItem = currentItem; >- if (tlItem) token = tlItem->token; >- return token; >+ if ( currentItem ) >+ return currentItem->token; >+ return &endToken; > } //-- peek > >-Token* ExprLexer::lookAhead(int offset) { >- Token* token = 0; >- TokenListItem* tlItem = currentItem; >- //-- advance to proper offset >- for ( int i = 0; i < offset; i++ ) >- if ( tlItem ) tlItem = currentItem->next; >- >- if (tlItem) token = tlItem->token; >- return token; >-} //-- lookAhead >- > void ExprLexer::addToken(Token* token) { >- TokenListItem* tlItem = new TokenListItem; >- tlItem->token = token; >- tlItem->next = 0; >- if (lastItem) { >- tlItem->previous = lastItem; >- lastItem->next = tlItem; >- } >- if (!firstItem) firstItem = tlItem; >- lastItem = tlItem; >- prevToken = token; >- ++tokenCount; >+ TokenListItem* tlItem = new TokenListItem; >+ tlItem->token = token; >+ tlItem->next = 0; >+ if (lastItem) { >+ tlItem->previous = lastItem; >+ lastItem->next = tlItem; >+ } >+ if (!firstItem) firstItem = tlItem; >+ lastItem = tlItem; >+ prevToken = token; >+ ++tokenCount; > } //-- addToken > >+// macros for inclusion of char range headers >+#define TX_CHAR_RANGE(a,b) if (ch<a) return MB_FALSE; \ >+ if (ch<=b) return MB_TRUE >+#define TX_MATCH_CHAR(a) if (ch<a) return MB_FALSE; \ >+ if (ch==a) return MB_TRUE >+ > /** > * Returns true if the given character represents an Alpha letter > **/ >-MBool ExprLexer::isAlphaChar(Int32 ch) { >- if ((ch >= 'a' ) && (ch <= 'z' )) return MB_TRUE; >- if ((ch >= 'A' ) && (ch <= 'Z' )) return MB_TRUE; >- return MB_FALSE; >+MBool ExprLexer::isLetter(UNICODE_CHAR ch) { >+#include "Letter.h" >+ return MB_FALSE; > } //-- isAlphaChar > > /** > * Returns true if the given character represents a numeric letter (digit) > **/ >-MBool ExprLexer::isDigit(Int32 ch) { >- if ((ch >= '0') && (ch <= '9')) return MB_TRUE; >- return MB_FALSE; >+MBool ExprLexer::isDigit(UNICODE_CHAR ch) { >+ TX_CHAR_RANGE('0','9'); >+ return MB_FALSE; > } //-- isDigit > > /** > * Returns true if the given character is an allowable NCName character > **/ >-MBool ExprLexer::isNCNameChar(Int32 ch) { >- if (isDigit(ch) || isAlphaChar(ch)) return MB_TRUE; >- return (MBool) ((ch == '.') || (ch == '_') || (ch == '-')); >+MBool ExprLexer::isNCNameChar(UNICODE_CHAR ch) { >+#include "NCNameChar.h" >+ return MB_FALSE; > } //-- isNCNameChar > >-/** >- * Returns true if the given character is an allowable QName character >-**/ >-MBool ExprLexer::isQNameChar(Int32 ch) { >- return (MBool) (( ch == ':') || isNCNameChar(ch)); >-} //-- isQNameChar >- > /** >- * Returns true if the given String is a valid XML QName >-**/ >-MBool ExprLexer::isValidQName(String& name) { >- >- int size = name.length(); >- if ( size == 0 ) return MB_FALSE; >- else if ( !isAlphaChar(name.charAt(0))) return MB_FALSE; >- else { >- for ( int i = 1; i < size; i++) { >- if ( ! isQNameChar(name.charAt(i))) return MB_FALSE; >- } >- } >- return MB_TRUE; >-} //-- isValidQName >- >-MBool ExprLexer::isOperatorToken(Token* token) { >- if ( !token ) return MB_FALSE; >- switch ( token->type ) { >- //-- boolean operators >- case Token::AND_OP: >- case Token::OR_OP: >- //-- relational operators >- case Token::EQUAL_OP: >- case Token::NOT_EQUAL_OP: >- case Token::LESS_THAN_OP: >- case Token::GREATER_THAN_OP: >- case Token::LESS_OR_EQUAL_OP: >- case Token::GREATER_OR_EQUAL_OP: >- //-- additive operators >- case Token::ADDITION_OP: >- case Token::SUBTRACTION_OP: >- //-- multiplicative operators >- case Token::DIVIDE_OP: >- case Token::MODULUS_OP: >- case Token::MULTIPLY_OP: >- return MB_TRUE; >- default: >- break; >- } >- >- return MB_FALSE; >-} //-- isOperatorToken >- >-MBool ExprLexer::matchDelimiter(UNICODE_CHAR ch) { >- >- short tokenType = 0; >- MBool addChar = MB_TRUE; >- switch (ch) { >- case FORWARD_SLASH : >- tokenType = Token::PARENT_OP; >- break; >- case L_PAREN : >- tokenType = Token::L_PAREN; >- break; >- case R_PAREN : >- tokenType = Token::R_PAREN; >- break; >- case L_BRACKET : >- tokenType = Token::L_BRACKET; >- break; >- case R_BRACKET : >- tokenType = Token::R_BRACKET; >- break; >- case L_ANGLE : >- tokenType = Token::LESS_THAN_OP; >- break; >- case R_ANGLE : >- tokenType = Token::GREATER_THAN_OP; >- break; >- case COMMA : >- tokenType = Token::COMMA; >- break; >- case PERIOD : >- tokenType = Token::SELF_NODE; >- break; >- case EQUAL : >- tokenType = Token::EQUAL_OP; >- break; >- case PLUS : >- tokenType = Token::ADDITION_OP; >- break; >- case HYPHEN : >- tokenType = Token::SUBTRACTION_OP; >- break; >- case VERT_BAR: >- tokenType = Token::UNION_OP; >- break; >- case AT_SIGN: >- tokenType = Token::AT_SIGN; >- break; >- case DOLLAR_SIGN: >- tokenType = Token::VAR_REFERENCE; >- addChar = MB_FALSE; >- break; >- default: >- return MB_FALSE; >- } >- Token* token = 0; >- if ( addChar ) token = new Token(ch, tokenType); >- else token = new Token(tokenType); >- >- addToken(token); >- return MB_TRUE; >-} //-- matchDelimiter >- >-/** >- * Returns true if the value of the given String matches >- * an OperatorName >-**/ >-MBool ExprLexer::matchesOperator(String& buffer) { >- >- int index = 0; >- while (index < NUMBER_OF_TOKENS) { >- Token tok = TOKENS[index++]; >- if ( tok.value.isEqual(buffer) ) { >- if (isOperatorToken( &tok )) return MB_TRUE; >- } >- } >+ * Returns true if the following Token should be an operator. >+ * This is a helper for the first bullet of [XPath 3.7] >+ * Lexical Structure >+**/ >+MBool ExprLexer::nextIsOperatorToken(Token* token) { >+ if ( !token || token->type == Token::NULL_TOKEN) return MB_FALSE; >+ if (token->type >= Token::COMMA && >+ token->type <= Token::UNION_OP) > return MB_FALSE; >- >-} //-- matchesOperator >+ return MB_TRUE; >+} //-- nextIsOperatorToken > > /** >- * Matches the given String to the appropriate Token >- * @param buffer the current StringBuffer representing the value of the Token >- * @param ch, the current delimiter token >-**/ >-void ExprLexer::matchToken(String& buffer, UNICODE_CHAR ch) { >- >- if ( buffer.length() == 0) return; >- >- Token* match = new Token(); >- MBool foundMatch = MB_FALSE; >- int index = 0; >- >- //-- check previous token >- switch(prevToken->type) { >- case Token::VAR_REFERENCE : >- if ( prevToken->value.length() == 0) { >- prevToken->value.append(buffer); >- buffer.clear(); >- return; >- } >- break; >- default: >- break; >- } >- >- //-- look for next match >- while ( !foundMatch && (index < NUMBER_OF_TOKENS) ) { >- >- Token tok = TOKENS[index++]; >- >- if ( tok.value.isEqual(buffer) ) { >- >- foundMatch = MB_TRUE; >- >- switch (tok.type) { >- >- //-- NodeType tokens >- case Token::COMMENT: >- case Token::NODE : >- case Token::PI : >- case Token::TEXT : >- // make sure next delimiter is '(' >- if ( ch != L_PAREN) { >- foundMatch = MB_FALSE; >- break; >- } >- //-- copy buffer >- match->value = buffer; >- //-- copy type >- match->type = tok.type; >- break; >- case Token::MULTIPLY_OP : >- case Token::DIVIDE_OP: >- case Token::MODULUS_OP: >- switch ( prevToken->type ) { >- case Token::AT_SIGN : >- case Token::NULL_TOKEN: >- case Token::L_PAREN: >- case Token::L_BRACKET: >- foundMatch = MB_FALSE; >- break; //-- do not match >- default: >- if ( isOperatorToken(prevToken) ) { >- foundMatch = MB_FALSE; >- break; //-- do not match >- } >- match->value = buffer; >- match->type = tok.type; >- } >- break; >- default : >- //-- copy buffer >- match->value = buffer; >- match->type = tok.type; >- break; >- } >- } //-- if equal >- } //-- while >- >- if (!foundMatch) { >- //-- copy buffer >- match->value = buffer; >- //-- look for function name >- if ( ch == L_PAREN) match->type = Token::FUNCTION_NAME; >- else match->type = Token::CNAME; >- } >- addToken(match); >- buffer.clear(); >-} //-- matchToken >- >-/** > * Parses the given String into the set of Tokens > **/ > void ExprLexer::parse(const String& pattern) { > >+ String tokenBuffer; > >- String tokenBuffer; >- UNICODE_CHAR inLiteral = '\0'; >- MBool inNumber = MB_FALSE; >- >- Int32 currentPos = 0; >- >- UNICODE_CHAR ch = '\0'; >- UNICODE_CHAR prevCh = ch; >- >- //-- initialize previous token, this will automatically get >- //-- deleted when it goes out of scope >- Token nullToken('\0', Token::NULL_TOKEN); >- >- prevToken = &nullToken; >- >- while (currentPos < pattern.length()) { >- >- prevCh = ch; >- ch = pattern.charAt(currentPos); >- >- if ( inLiteral ) { >- //-- look for end of literal >- if ( ch == inLiteral ) { >- inLiteral = '\0'; >- addToken(new Token(tokenBuffer, Token::LITERAL)); >- tokenBuffer.clear(); >- } >- else { >- tokenBuffer.append(ch); >- } >+ Int32 iter = 0, start; >+ Int32 size = pattern.length(); >+ short defType; >+ UNICODE_CHAR ch; >+ if ( size==0 ) return; >+ >+ //-- initialize previous token, this will automatically get >+ //-- deleted when it goes out of scope >+ Token nullToken('\0', Token::NULL_TOKEN); >+ >+ prevToken = &nullToken; >+ >+ while (iter < size) { >+ >+ ch = pattern.charAt(iter); >+ defType = Token::CNAME; >+ >+ if (ch==DOLLAR_SIGN) { >+ if (++iter == size || !isLetter(ch=pattern.charAt(iter))) { >+ // Error, VariableReference expected >+ errorPos = iter; >+ errorCode = ERROR_UNRESOLVED_VAR_REFERENCE; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail >+ } else >+ defType = Token::VAR_REFERENCE; >+ } >+ // just reuse the QName parsing, which will use defType >+ // the token to construct >+ >+ if ( isLetter(ch) ) { >+ // NCName, can get QName or OperatorName; >+ // FunctionName, NodeName, and AxisSpecifier may want whitespace, >+ // and are dealt with below >+ start = iter; >+ while (++iter < size && >+ isNCNameChar(pattern.charAt(iter))) /* just go */ ; >+ Int32 end = iter; >+ if (pattern.charAt(iter)==COLON) { >+ // try QName or wildcard, might need to step back for axis >+ if (++iter < size) >+ if (isLetter(pattern.charAt(iter))) >+ while(++iter < size && >+ isNCNameChar(pattern.charAt(iter))) /* just go */ ; >+ else if (pattern.charAt(iter)=='*') >+ ++iter; /* eat wildcard */ >+ else >+ iter--; // step back >+ } >+ if (nextIsOperatorToken(prevToken)) { >+ if (pattern.subString(start,end,subStr).isEqual(AND)) >+ defType = Token::AND_OP; >+ else if (pattern.subString(start,end,subStr).isEqual(OR)) >+ defType = Token::OR_OP; >+ else if (pattern.subString(start,end,subStr).isEqual(MODULUS)) >+ defType = Token::MODULUS_OP; >+ else if (pattern.subString(start,end,subStr).isEqual(DIVIDE)) >+ defType = Token::DIVIDE_OP; >+ else { >+ // Error "operator expected" >+ // XXX QUESTION: spec is not too precise >+ // badops is sure an error, but is bad:ops, too? We say yes! >+ errorPos = iter; >+ errorCode = ERROR_OP_EXPECTED; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail > } >- else if ( inNumber ) { >- if (isDigit(ch) || (ch == '.')) { >- tokenBuffer.append(ch); >- } >- else { >- inNumber = MB_FALSE; >- addToken(new Token(tokenBuffer, Token::NUMBER)); >- tokenBuffer.clear(); >- //-- push back last char >- --currentPos; >- } >+ } >+ addToken(new Token(pattern.subString(start,iter,subStr),defType)); >+ } else if ( isDigit(ch) ) { >+ start = iter; >+ while (++iter < size && >+ isDigit(pattern.charAt(iter))) /* just go */; >+ if (pattern.charAt(iter)=='.') >+ while (++iter < size && >+ isDigit(pattern.charAt(iter))) /* just go */; >+ addToken(new Token(pattern.subString(start,iter,subStr),Token::NUMBER)); >+ } else { >+ switch (ch) { >+ //-- ignore whitespace >+ case SPACE: >+ case TX_TAB: >+ case TX_CR: >+ case TX_LF: >+ ++iter; >+ break; >+ case S_QUOTE : >+ case D_QUOTE : >+ start=iter; >+ iter = pattern.indexOf(ch,start+1); >+ if (iter==NOT_FOUND) { >+ // XXX Error reporting "unclosed literal" >+ errorPos = start; >+ errorCode = ERROR_UNCLOSED_LITERAL; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail >+ } else { >+ addToken(new Token(pattern.subString(start+1,iter,subStr), >+ Token::LITERAL)); >+ ++iter; > } >- else if (isDigit(ch)) { >- if ((tokenBuffer.length() == 0 ) || matchesOperator(tokenBuffer) ) { >- //-- match operator and free up token buffer >- matchToken(tokenBuffer, ch); >- inNumber = MB_TRUE; >- } >- else if (( tokenBuffer.length() == 1 ) && (prevCh = '-')) { >- inNumber = MB_TRUE; >- } >- tokenBuffer.append(ch); >+ break; >+ case PERIOD: >+ // period can be .., .(DIGITS)+ or ., check next >+ if (++iter < size) { >+ ch=pattern.charAt(iter); >+ if (isDigit(ch)) { >+ start=iter-1; >+ while (++iter < size && >+ isDigit(pattern.charAt(iter))) /* just go */; >+ addToken(new Token(pattern.subString(start,iter,subStr), >+ Token::NUMBER)); >+ } else if (ch==PERIOD) { >+ addToken(new Token(pattern.subString(iter-1,iter++,subStr), >+ Token::PARENT_NODE)); >+ } else >+ addToken(new Token(PERIOD, Token::SELF_NODE)); >+ } else >+ addToken(new Token(ch, Token::SELF_NODE)); >+ // iter++ is already in the number test >+ >+ break; >+ case COLON: // QNames are dealt above, must be axis ident >+ if (++iter < size && pattern.charAt(iter)==COLON && >+ prevToken->type == Token::CNAME) { >+ prevToken->type = Token::AXIS_IDENTIFIER; >+ ++iter; >+ } else { >+ // XXX Error report "colon is neither QName nor axis" >+ errorPos = iter; >+ errorCode = ERROR_COLON; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail > } >- else { >- switch (ch) { >- //-- ignore whitespace >- case SPACE: >- case TX_TAB: >- case TX_CR: >- case TX_LF: >- break; >- case S_QUOTE : >- case D_QUOTE : >- matchToken(tokenBuffer, ch); >- inLiteral = ch; >- break; >- case PERIOD: >- if ( inNumber ) tokenBuffer.append(ch); >- else if ( prevToken->type == Token::SELF_NODE ) { >- prevToken->type = Token::PARENT_NODE; >- } >- else if ( tokenBuffer.length() > 0 ) >- tokenBuffer.append(ch); >- else matchDelimiter(ch); >- break; >- case COLON: >- if ( prevCh == ch) { >- Int32 bufSize = tokenBuffer.length(); >- tokenBuffer.setLength(bufSize-1); >- addToken(new Token(tokenBuffer, Token::AXIS_IDENTIFIER)); >- tokenBuffer.clear(); >- } >- else tokenBuffer.append(ch); >- break; >- case FORWARD_SLASH : >- matchToken(tokenBuffer, ch); >- if ( prevToken->type == Token::PARENT_OP ) { >- prevToken->type = Token::ANCESTOR_OP; >- prevToken->value.append(ch); >- } >- //-- handle possible error in using / >- else if ( prevToken->type == Token::NUMBER ) { >- prevToken->type = Token::ERROR; >- prevToken->value = "Error in expression, misuse of '/', try 'div' instead."; >- } >- else matchDelimiter(ch); >- break; >- case BANG : //-- used as previous...see EQUAL >- matchToken(tokenBuffer,ch); >- addToken(new Token(ch, Token::ERROR)); >- break; >- case EQUAL: >- switch ( prevCh ) { >- case BANG: >- prevToken->type = Token::NOT_EQUAL_OP; >- prevToken->value.append("="); >- break; >- case L_ANGLE: >- prevToken->type = Token::LESS_OR_EQUAL_OP; >- prevToken->value.append("="); >- break; >- case R_ANGLE: >- prevToken->type = Token::GREATER_OR_EQUAL_OP; >- prevToken->value.append("="); >- break; >- default: >- matchToken(tokenBuffer, ch); >- matchDelimiter(ch); >- break; >- } >- break; >- case L_ANGLE : >- case R_ANGLE : >- matchToken(tokenBuffer, ch); >- matchDelimiter(ch); >- break; >- case HYPHEN : >- if ( isValidQName(tokenBuffer) && >- !( prevCh==SPACE || prevCh==TX_TAB|| >- prevCh==TX_CR || prevCh==TX_LF ) ) >- tokenBuffer.append(ch); >- else { >- switch ( prevToken->type ) { >- case Token::NULL_TOKEN: >- case Token::L_PAREN: >- case Token::L_BRACKET: >- case Token::COMMA: >- inNumber = MB_TRUE; >- tokenBuffer.append(ch); >- break; >- default: >- matchToken(tokenBuffer, ch); >- matchDelimiter(ch); >- break; >- } >- } >- break; >- case ASTERIX: >- matchToken(tokenBuffer, ch); >- switch ( prevToken->type ) { >- //-- temporary fix for Namespace wild-cards - KV >- case Token::CNAME : >- prevToken->value.append(ch); >- break; >- //-- end temporary fix for Namespace wild-cards >- >- //-- Fix: make sure check for axis identifier wild cards, such as >- //-- ancestor::* - Marina M. >- case Token::AXIS_IDENTIFIER : >- //-- End Fix >- case Token::PARENT_OP : >- case Token::ANCESTOR_OP: >- case Token::AT_SIGN : >- case Token::NULL_TOKEN: >- case Token::L_PAREN: >- case Token::L_BRACKET: >- tokenBuffer.append(ch); >- //matchDelimiter(ch); >- break; >- default: >- if ( isOperatorToken(prevToken) ) { >- matchDelimiter(ch); >- break; //-- do not match >- } >- addToken( new Token(ch, Token::MULTIPLY_OP) ); >- } >- break; >- case L_PAREN: >- case R_PAREN: >- case L_BRACKET: >- case R_BRACKET: >- case COMMA: >- case AT_SIGN : >- case PLUS: >- case DOLLAR_SIGN : >- matchToken(tokenBuffer, ch); >- matchDelimiter(ch); >- break; >- case VERT_BAR: >- matchToken(tokenBuffer, ch); >- matchDelimiter(ch); >- //-- Reset previous token to Null, since this is the "Union Operator" >- //-- and the next set of tokens should start as a fresh expression >- prevToken = &nullToken; >- break; >- default: >- switch (prevCh) { >- case SPACE : >- case TX_TAB : >- case TX_CR : >- case TX_LF : >- matchToken(tokenBuffer, ch); >- tokenBuffer.append(ch); >- break; >- default: >- tokenBuffer.append(ch); >- break; >- } >- break; >- } >+ break; >+ case FORWARD_SLASH : >+ if (++iter < size && pattern.charAt(iter)==ch) { >+ addToken(new Token(pattern.subString(iter-1,++iter,subStr), >+ Token::ANCESTOR_OP)); >+ } else { >+ addToken(new Token(ch, Token::PARENT_OP)); > } >- ++currentPos; >- } >- //-- end lexical parsing of current token >- //-- freeBuffer if needed >- >- if ( inNumber ) { >- addToken(new Token(tokenBuffer, Token::NUMBER)); >+ break; >+ case BANG : // can only be != >+ if (++iter < size && pattern.charAt(iter)==EQUAL) { >+ addToken(new Token(pattern.subString(iter-1,++iter,subStr), >+ Token::NOT_EQUAL_OP)); >+ } else { >+ // Error ! is not not() >+ errorPos = iter; >+ errorCode = ERROR_BANG; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail >+ } >+ break; >+ case EQUAL: >+ addToken(new Token(ch,Token::EQUAL_OP)); >+ ++iter; >+ break; >+ case L_ANGLE: >+ if (++iter < size && pattern.charAt(iter)==EQUAL) { >+ addToken(new Token(pattern.subString(iter-1,++iter,subStr), >+ Token::LESS_OR_EQUAL_OP)); >+ } else >+ addToken(new Token(ch,Token::LESS_THAN_OP)); >+ break; >+ case R_ANGLE: >+ if (++iter < size && pattern.charAt(iter)==EQUAL) { >+ addToken(new Token(pattern.subString(iter-1,++iter,subStr), >+ Token::GREATER_OR_EQUAL_OP)); >+ } else >+ addToken(new Token(ch,Token::GREATER_THAN_OP)); >+ break; >+ case HYPHEN : >+ addToken(new Token(ch,Token::SUBTRACTION_OP)); >+ ++iter; >+ break; >+ case ASTERIX: >+ if (nextIsOperatorToken(prevToken)) >+ addToken(new Token(ch,Token::MULTIPLY_OP)); >+ else >+ addToken(new Token(ch,Token::CNAME)); >+ ++iter; >+ break; >+ case L_PAREN: >+ if (prevToken->type == Token::CNAME) { >+ if (prevToken->value.isEqual(COMMENT)) >+ prevToken->type = Token::COMMENT; >+ else if (prevToken->value.isEqual(NODE)) >+ prevToken->type = Token::NODE; >+ else if (prevToken->value.isEqual(PI)) >+ prevToken->type = Token::PI; >+ else if (prevToken->value.isEqual(TEXT)) >+ prevToken->type = Token::TEXT; >+ else >+ prevToken->type = Token::FUNCTION_NAME; >+ } >+ ++iter; >+ addToken(new Token(ch,Token::L_PAREN)); >+ break; >+ case R_PAREN: >+ ++iter; >+ addToken(new Token(ch,Token::R_PAREN)); >+ break; >+ case L_BRACKET: >+ ++iter; >+ addToken(new Token(ch,Token::L_BRACKET)); >+ break; >+ case R_BRACKET: >+ ++iter; >+ addToken(new Token(ch,Token::R_BRACKET)); >+ break; >+ case COMMA: >+ ++iter; >+ addToken(new Token(ch,Token::COMMA)); >+ break; >+ case AT_SIGN : >+ ++iter; >+ addToken(new Token(ch,Token::AT_SIGN)); >+ break; >+ case PLUS: >+ ++iter; >+ addToken(new Token(ch,Token::ADDITION_OP)); >+ break; >+ case VERT_BAR: >+ ++iter; >+ addToken(new Token(ch,Token::UNION_OP)); >+ break; >+ default: >+ // Error, don't grok character :-( >+ errorPos = iter; >+ errorCode = ERROR_UNKNOWN_CHAR; >+ if (firstItem) >+ firstItem->token->type=Token::ERROR; >+ else >+ addToken(new Token('\0',Token::ERROR)); >+ iter=size; // bail >+ } > } >- else matchToken(tokenBuffer, ch); >- prevToken = 0; >+ } > } //-- parse > >Index: source/xpath/ExprLexer.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/ExprLexer.h,v >retrieving revision 1.6 >diff -u -r1.6 ExprLexer.h >--- ExprLexer.h 2001/04/08 14:36:50 1.6 >+++ ExprLexer.h 2001/04/12 22:47:35 >@@ -1,4 +1,4 @@ >-/* >+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- > * The contents of this file are subject to the Mozilla Public > * License Version 1.1 (the "License"); you may not use this file > * except in compliance with the License. You may obtain a copy of >@@ -25,7 +25,7 @@ > * -- changed constant short declarations in Token and ExprLexer to > * enumerations, commented with //--LF > * >- * $Id: ExprLexer.h,v 1.6 2001/04/08 14:36:50 peterv%netscape.com Exp $ >+ * $Id: ExprLexer.h,v 1.5 2001/01/22 09:36:16 kvisco%ziplink.net Exp $ > */ > > >@@ -41,7 +41,7 @@ > * This class was ported from XSL:P, an open source Java based > * XSLT processor, written by yours truly. > * @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a> >- * @version $Revision: 1.6 $ $Date: 2001/04/08 14:36:50 $ >+ * @version $Revision: 1.5 $ $Date: 2001/01/22 09:36:16 $ > **/ > class Token { > >@@ -60,48 +60,57 @@ > LITERAL, > NUMBER, > CNAME, >- L_PAREN, >- R_PAREN, >- L_BRACKET, >- R_BRACKET, >- COMMA, > FUNCTION_NAME, >- AT_SIGN, > VAR_REFERENCE, > PARENT_NODE, > SELF_NODE, >+ R_PAREN, >+ R_BRACKET, // 10 >+ /** >+ * start of tokens for 3.7, bullet 1 -/ >+ **/ >+ COMMA, >+ AT_SIGN, >+ L_PAREN, >+ L_BRACKET, > AXIS_IDENTIFIER, > //-------------/ > //- operators -/ > //-------------/ > > //-- boolean ops >- AND_OP, >+ AND_OP, // 16 > OR_OP, > > //-- relational >- EQUAL_OP, >+ EQUAL_OP, // 18 > NOT_EQUAL_OP, > LESS_THAN_OP, > GREATER_THAN_OP, > LESS_OR_EQUAL_OP, > GREATER_OR_EQUAL_OP, > //-- additive operators >- ADDITION_OP, >+ ADDITION_OP, // 24 > SUBTRACTION_OP, > //-- multiplicative >- DIVIDE_OP , >+ DIVIDE_OP , // 26 > MULTIPLY_OP, > MODULUS_OP, > //-- path operators >- PARENT_OP, >+ PARENT_OP, // 29 > ANCESTOR_OP, > UNION_OP, >+ /** >+ * end of tokens for 3.7, bullet 1 -/ >+ **/ > //-- node type tokens >- COMMENT, >+ COMMENT, // 32 > NODE, > PI, >- TEXT >+ TEXT, >+ >+ //-- Special endtoken >+ END // 36 > }; > > >@@ -166,6 +175,17 @@ > TX_LF = '\r' > }; > >+ enum _error_consts { >+ ERROR_UNRESOLVED_VAR_REFERENCE = 0, >+ ERROR_OP_EXPECTED, >+ ERROR_UNCLOSED_LITERAL, >+ ERROR_COLON, >+ ERROR_BANG, >+ ERROR_UNKNOWN_CHAR >+ }; >+ static const String error_message[]; >+ Int32 errorPos; >+ short errorCode; > > /* > * Complex Tokens >@@ -181,15 +201,10 @@ > static const String OR; > > //-- Multiplicative >+ static const String MULTIPLY; > static const String MODULUS; > static const String DIVIDE; > >- /* >- * Default Token Set >- */ >- static const Token TOKENS[]; >- static const short NUMBER_OF_TOKENS; >- > /** > * Constructor for ExprLexer > **/ >@@ -198,30 +213,14 @@ > ~ExprLexer(); > > /** >- * Counts the total number of tokens in this Lexer, even if the token >- * has already been seen >- * @return the total number of tokens in this Lexer >+ * Functions for iterating over the TokenList > **/ >- int countAllTokens(); > >- /** >- * Counts the remaining number of tokens in this Lexer >- * @return the number of remaining tokens in this Lexer >- **/ >- int countRemainingTokens(); >- >- /** >- * Returns the type of token that was last return by a call to nextToken >- **/ >- >- Token* lookAhead(int offset); > Token* nextToken(); > Token* peek(); > void pushBack(); > MBool hasMoreTokens(); > >- MBool isOperatorToken(Token* token); >- > private: > > struct TokenListItem { >@@ -237,50 +236,33 @@ > int tokenCount; > > Token* prevToken; >+ Token endToken; > > void addToken(Token* token); > > /** >- * Returns true if the given character represents an Alpha letter >- **/ >- static MBool isAlphaChar(Int32 ch); >+ * Returns true if the following Token should be an operator. >+ * This is a helper for the first bullet of [XPath 3.7] >+ * Lexical Structure >+ **/ >+ MBool nextIsOperatorToken(Token* token); > > /** >- * Returns true if the given character represents a numeric letter (digit) >+ * Returns true if the given character represents an Alpha letter > **/ >- static MBool isDigit(Int32 ch); >+ static MBool isLetter(UNICODE_CHAR ch); > > /** >- * Returns true if the given character is an allowable QName character >+ * Returns true if the given character represents a numeric letter (digit) > **/ >- static MBool isQNameChar(Int32 ch); >+ static MBool isDigit(UNICODE_CHAR ch); > > /** > * Returns true if the given character is an allowable NCName character >- **/ >- static MBool isNCNameChar(Int32 ch); >- >- /** >- * Returns true if the given String is a valid XML QName >- **/ >- static MBool isValidQName(String& name); >- >- MBool matchDelimiter(UNICODE_CHAR ch); >- >- /** >- * Returns true if the value of the given String matches >- * an OperatorName > **/ >- MBool matchesOperator(String& buffer); >- >- /** >- * Matches the given String to the appropriate Token >- * @param buffer the current StringBuffer representing the value of the Token >- * @param ch, the current delimiter token >- **/ >- void matchToken(String& buffer, UNICODE_CHAR ch); >- >+ static MBool isNCNameChar(UNICODE_CHAR ch); > >+ String subStr; > void parse(const String& pattern); > > }; //-- ExprLexer >Index: source/xpath/ExprParser.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/ExprParser.cpp,v >retrieving revision 1.10 >diff -u -r1.10 ExprParser.cpp >--- ExprParser.cpp 2001/04/08 14:33:57 1.10 >+++ ExprParser.cpp 2001/04/12 22:47:35 >@@ -45,9 +45,6 @@ > #include "FunctionLib.h" > #include "Names.h" > >-const String ExprParser::L_CURLY_BRACE = "{"; >-const String ExprParser::R_CURLY_BRACE = "}"; >- > /** > * Creates a new ExprParser > **/ >@@ -60,86 +57,101 @@ > > /** > * Creates an Attribute Value Template using the given value >+ * This should move to XSLProcessor class > **/ > AttributeValueTemplate* ExprParser::createAttributeValueTemplate > (const String& attValue) > { > > AttributeValueTemplate* avt = new AttributeValueTemplate(); >+ > Int32 size = attValue.length(); >+ if ( size == 0) return avt; //XXX should return 0, but that causes crash in lre12 >+ > int cc = 0; >+ UNICODE_CHAR nextCh; >+ UNICODE_CHAR ch; > String buffer; > MBool inExpr = MB_FALSE; > MBool inLiteral = MB_FALSE; >- UNICODE_CHAR endLiteral = '"'; >- UNICODE_CHAR prevCh = '\0'; >+ UNICODE_CHAR endLiteral; > >- while ( cc < size) { >- UNICODE_CHAR ch = attValue.charAt(cc++); >+ nextCh = attValue.charAt(cc); >+ while ( cc++ < size) { >+ ch = nextCh; >+ nextCh = cc != size ? attValue.charAt(cc) : 0; >+ > // if in literal just add ch to buffer > if ( inLiteral && (ch != endLiteral) ) { > buffer.append(ch); >- prevCh = ch; > continue; > } > switch ( ch ) { > case '\'' : > case '"' : > buffer.append(ch); >- if (inLiteral) inLiteral = MB_FALSE; >- else { >+ if (inLiteral) >+ inLiteral = MB_FALSE; >+ else if (inExpr) { > inLiteral = MB_TRUE; > endLiteral = ch; > } > break; > case '{' : >- // Ignore case where we find two { without a } > if (!inExpr) { >- //-- clear buffer >- if ( buffer.length() > 0) { >- avt->addExpr(new StringExpr(buffer)); >+ // Ignore case where we find two { >+ if ( nextCh == ch ) { >+ buffer.append(ch); //-- append '{' >+ cc++; >+ nextCh = cc != size ? attValue.charAt(cc) : 0; >+ } >+ else { >+ if ( buffer.length() > 0) >+ avt->addExpr(new StringExpr(buffer)); > buffer.clear(); >+ inExpr = MB_TRUE; > } >- inExpr = MB_TRUE; > } >- else if (prevCh == ch) { >- inExpr = MB_FALSE; >- buffer.append(ch); >- } >- else { >+ else > buffer.append(ch); //-- simply append '{' >- ch = '\0'; >- } > break; > case '}': > if (inExpr) { > inExpr = MB_FALSE; >- avt->addExpr(createExpr(buffer)); >+ Expr* expr = createExpr(buffer); >+ if (!expr) { >+ delete avt; >+ return 0; >+ } >+ avt->addExpr(expr); > buffer.clear(); >- //-- change in case another '}' follows >- ch = '\0'; > } >- else if (prevCh != ch) { >- if ( buffer.length() > 0) buffer.append('}'); >- else avt->addExpr(new StringExpr(R_CURLY_BRACE)); >+ else if (nextCh == ch) { >+ buffer.append(ch); >+ cc++; >+ nextCh = cc != size ? attValue.charAt(cc) : 0; > } >+ else { >+ //XXX ErrorReport: unmatched '}' found >+ delete avt; >+ return 0; >+ } > break; > default: > buffer.append(ch); > break; > } >- prevCh = ch; > } >- if ( buffer.length() > 0) { >- if ( inExpr ) { >- //-- error >- String errMsg("#error evaluating AttributeValueTemplate. "); >- errMsg.append("Missing '}' after: "); >- errMsg.append(buffer); >- avt->addExpr(new StringExpr(errMsg)); >- } >- else avt->addExpr(new StringExpr(buffer)); >+ >+ if ( inExpr ) { >+ //XXX ErrorReport: ending '}' missing >+ delete avt; >+ return 0; > } >+ >+ if ( buffer.length() > 0) >+ avt->addExpr(new StringExpr(buffer)); >+ > return avt; > > } //-- createAttributeValueTemplate >@@ -149,9 +161,10 @@ > return createExpr(lexer); > } //-- createExpr > >-PatternExpr* ExprParser::createPatternExpr(const String& pattern) { >+Expr* ExprParser::createPatternExpr(const String& pattern) { > ExprLexer lexer(pattern); >- return createUnionExpr(lexer); >+ Expr* expr = createUnionExpr(lexer); >+ return expr; > } //-- createPatternExpr > > LocationStep* ExprParser::createLocationStep(const String& path) { >@@ -216,7 +229,7 @@ > } //-- createBinaryExpr > > >-Expr* ExprParser::createExpr(ExprLexer& lexer) { >+Expr* ExprParser::createExpr(ExprLexer& lexer) { > > MBool done = MB_FALSE; > >@@ -224,68 +237,28 @@ > > Stack exprs; > Stack ops; >+ >+ if (lexer.peek()->type == Token::ERROR) { >+ done = MB_TRUE; >+ // XXX Error notification of caller >+ } >+ while ( !done ) { >+ >+ MBool unary = MB_FALSE; >+ while( lexer.peek()->type == Token::SUBTRACTION_OP ) { >+ unary = !unary; >+ lexer.nextToken(); >+ } >+ >+ expr = createUnionExpr(lexer); >+ if ( !expr ) >+ break; > >- while ( lexer.hasMoreTokens() && (!done)) { >+ if ( unary ) >+ expr = new UnaryExpr(expr); > > Token* tok = lexer.nextToken(); > switch ( tok->type ) { >- case Token::L_BRACKET: // Predicate starts here >- case Token::R_BRACKET: >- case Token::R_PAREN: >- case Token::COMMA : >- lexer.pushBack(); >- done = MB_TRUE; >- break; >- case Token::L_PAREN: //-- Grouping Expression >- expr = createExpr(lexer); >- //-- look for end ')' >- if ( lexer.hasMoreTokens() && >- ( lexer.nextToken()->type == Token::R_PAREN ) ) break; >- else { >- //-- error >- delete expr; >- expr = new StringExpr("missing ')' in expression"); >- } >- break; >- case Token::ANCESTOR_OP: >- case Token::PARENT_OP: >- lexer.pushBack(); >- if ( !expr ) expr = createPathExpr(lexer); >- else { >- PathExpr* pathExpr = createPathExpr(lexer); >- pathExpr->addPatternExpr(0, (PatternExpr*)expr, >- PathExpr::RELATIVE_OP); >- expr = pathExpr; >- } >- //done = MB_TRUE; >- break; >- case Token::UNION_OP : >- { >- UnionExpr* unionExpr = createUnionExpr(lexer); >- unionExpr->addPathExpr(0, (PathExpr*)expr ); >- expr = unionExpr; >- done = MB_TRUE; >- break; >- } >- case Token::LITERAL : >- expr = new StringExpr(tok->value); >- break; >- case Token::NUMBER: >- { >- StringResult str(tok->value); >- expr = new NumberExpr(str.numberValue()); >- break; >- } >- case Token::FUNCTION_NAME: >- { >- lexer.pushBack(); >- expr = createFunctionCall(lexer); >- break; >- } >- case Token::VAR_REFERENCE: >- expr = new VariableRefExpr(tok->value); >- break; >- //-- additive ops > case Token::ADDITION_OP: > case Token::DIVIDE_OP: > //-- boolean ops >@@ -304,28 +277,30 @@ > case Token::MULTIPLY_OP: > case Token::SUBTRACTION_OP: > { >- if ( !exprs.empty() ) { >- short ttype = ((Token*)ops.peek())->type; >- if (precedenceLevel(tok->type) < precedenceLevel(ttype)) { >- expr = createBinaryExpr((Expr*)exprs.pop(), expr, >- (Token*)ops.pop()); >- } >+ while ( !exprs.empty() && >+ precedenceLevel(tok->type) <= precedenceLevel(((Token*)ops.peek())->type)) { >+ expr = createBinaryExpr((Expr*)exprs.pop(), >+ expr, >+ (Token*)ops.pop()); > } > exprs.push(expr); > ops.push(tok); >- expr = 0; // OG, prevent reuse of expr > break; > } > default: > lexer.pushBack(); >- expr = createPatternExpr(lexer); >+ done = MB_TRUE; > break; > } > } > >- // make sure expr != 0, will this happen? >- if (( expr == 0 ) && (!exprs.empty())) >- expr = (Expr*) exprs.pop(); >+ // make sure expr != 0 >+ if ( expr == 0 ) { >+ while (!exprs.empty() ) { >+ delete (Expr*)exprs.pop(); >+ } >+ return 0; >+ } > > while (!exprs.empty() ) { > expr = createBinaryExpr((Expr*)exprs.pop(), expr, (Token*)ops.pop()); >@@ -335,67 +310,73 @@ > > } //-- createExpr > >-FilterExpr* ExprParser::createFilterExpr(ExprLexer& lexer) { >+Expr* ExprParser::createFilterExpr(ExprLexer& lexer) { > >- FilterExpr* filterExpr = new FilterExpr(); > Token* tok = lexer.nextToken(); >- if ( !tok ) return filterExpr; > > Expr* expr = 0; > switch ( tok->type ) { > case Token::FUNCTION_NAME : >+ lexer.pushBack(); > expr = createFunctionCall(lexer); >- filterExpr->setExpr(expr); > break; > case Token::VAR_REFERENCE : > expr = new VariableRefExpr(tok->value); >- filterExpr->setExpr(expr); > break; > case Token::L_PAREN: >- //-- primary group expr: > expr = createExpr(lexer); >- tok = lexer.nextToken(); >- if ( (!tok) || (tok->type != Token::R_PAREN ) ) { >- String errMsg("error: "); >- expr->toString(errMsg); >- errMsg.append(" - missing ')'"); >- delete expr; //-- free up current expr >- expr = new ErrorFunctionCall(errMsg); >+ if(!expr) return 0; >+ >+ if ( lexer.nextToken()->type != Token::R_PAREN ) { >+ lexer.pushBack(); >+ //XXX ErrorReport: right parenthesis expected >+ delete expr; >+ return 0; > } >- filterExpr->setExpr(expr); > break; >- case Token::PARENT_NODE : >- expr = new ParentExpr(); >- filterExpr->setExpr(expr); >+ case Token::LITERAL : >+ expr = new StringExpr(tok->value); > break; >- case Token::SELF_NODE : >- expr = new IdentityExpr(); >- filterExpr->setExpr(expr); >+ case Token::NUMBER: >+ { >+ StringResult str(tok->value); >+ expr = new NumberExpr(str.numberValue()); > break; >+ } > default: >+ // this should never ever happen. >+ lexer.pushBack(); >+ //XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org >+ return 0; > break; > } >+ if(!expr) return 0; > >- //-- handle predicates >- parsePredicates(filterExpr, lexer); >+ if ( lexer.peek()->type == Token::L_BRACKET ) { > >- return filterExpr; >+ FilterExpr* filterExpr = new FilterExpr(); >+ filterExpr->setExpr(expr); >+ >+ //-- handle predicates >+ if(!parsePredicates(filterExpr, lexer)) { >+ delete filterExpr; >+ return 0; >+ } >+ expr = filterExpr; >+ } > >+ return expr; >+ > } //-- createFilterExpr > > FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) { > >- if ( !lexer.hasMoreTokens() ) { >- //-- should never see this, I hope >- return new ErrorFunctionCall("no tokens, invalid function call"); >- } >- > FunctionCall* fnCall = 0; > > Token* tok = lexer.nextToken(); >- > if ( tok->type != Token::FUNCTION_NAME ) { >- return new ErrorFunctionCall("invalid function call"); >+ //XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org >+ return 0; > } > > String fnName = tok->value; >@@ -491,22 +472,11 @@ > //-- not our job to report an invalid function call here > fnCall = new ExtensionFunctionCall(fnName); > } >+ > //-- handle parametes >- List params; >- String* errMsg = parseParameters(¶ms, lexer); >- if (errMsg) { >- String err("error with function call, \""); >- err.append(fnName); >- err.append("\" : "); >- err.append(*errMsg); >- fnCall = new ErrorFunctionCall(err); >- delete errMsg; >- } >- // copy params >- else if (params.getLength() > 0) { >- ListIterator* iter = params.iterator(); >- while ( iter->hasNext() ) fnCall->addParam( (Expr*)iter->next() ); >- delete iter; >+ if(!parseParameters(fnCall, lexer)) { >+ delete fnCall; >+ return 0; > } > return fnCall; > } //-- createFunctionCall >@@ -514,9 +484,12 @@ > LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) { > > LocationStep* lstep = new LocationStep(); >+ >+ //-- child axis is default > short axisIdentifier = LocationStep::CHILD_AXIS; >+ NodeExpr* nodeExpr = 0; > >- //-- get Axis Identifier, if present >+ //-- get Axis Identifier or AbbreviatedStep, if present > Token* tok = lexer.peek(); > switch (tok->type) { > case Token::AXIS_IDENTIFIER: >@@ -550,11 +523,10 @@ > axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS; > else if ( SELF_AXIS.isEqual(tok->value) ) > axisIdentifier = LocationStep::SELF_AXIS; >- //-- child axis is default >- else if (!CHILD_AXIS.isEqual(tok->value)) { >- //-- handle error gracefully, simply ignore invalid axis and >- //-- use default. Add error message when message observer >- //-- is implemented >+ else { >+ delete lstep; >+ //XXX ErrorReport: unknow axis >+ return 0; > } > break; > } >@@ -563,49 +535,53 @@ > lexer.nextToken(); > axisIdentifier = LocationStep::ATTRIBUTE_AXIS; > break; >+ case Token::PARENT_NODE : >+ //-- eat token >+ lexer.nextToken(); >+ axisIdentifier = LocationStep::PARENT_AXIS; >+ nodeExpr = new BasicNodeExpr(); >+ break; >+ case Token::SELF_NODE : >+ //-- eat token >+ lexer.nextToken(); >+ axisIdentifier = LocationStep::SELF_AXIS; >+ nodeExpr = new BasicNodeExpr(); >+ break; > default: > break; > } >- >- lstep->setAxisIdentifier(axisIdentifier); >- >- >- NodeExpr* nodeExpr = 0; >- >- tok = lexer.peek(); >- if (!tok) { >- ///XXXXX We need to create an ErrorExpr or something to >- ///XXXXX handle errors >- } >- // NameTest >- else if (tok->type == Token::CNAME) { >- //-- handle NameTest >- //-- eat token >- lexer.nextToken(); >- if (axisIdentifier == LocationStep::ATTRIBUTE_AXIS) >- nodeExpr = new AttributeExpr(tok->value); >- else >- nodeExpr = new ElementExpr(tok->value); > >- } >- // NodeType >- else { >- nodeExpr = createNodeExpr(lexer); >+ //-- get NodeTest unless AbbreviatedStep was found >+ if ( !nodeExpr ) { >+ tok = lexer.nextToken(); >+ >+ switch(tok->type) { >+ case Token::CNAME : >+ // NameTest >+ // XXX Namespace: handle namespaces here >+ if (axisIdentifier == LocationStep::ATTRIBUTE_AXIS) >+ nodeExpr = new AttributeExpr(tok->value); >+ else >+ nodeExpr = new ElementExpr(tok->value); >+ break; >+ default: >+ lexer.pushBack(); >+ nodeExpr = createNodeExpr(lexer); >+ if(!nodeExpr) { >+ delete lstep; >+ return 0; >+ } >+ } > } >- >+ >+ lstep->setAxisIdentifier(axisIdentifier); > lstep->setNodeExpr(nodeExpr); > >- >- > //-- handle predicates >- >- parsePredicates(lstep, lexer); >- >- //<debug> >- //String tmp; >- //lstep->toString(tmp); >- //cout << "returning LocationStep: "<< tmp <<endl; >- //</debug> >+ if(!parsePredicates(lstep, lexer)) { >+ delete lstep; >+ return 0; >+ } > > return lstep; > } //-- createLocationPath >@@ -616,48 +592,48 @@ > **/ > NodeExpr* ExprParser::createNodeExpr(ExprLexer& lexer) { > >- //cout << "creating NodeExpr: "<<endl; >- if (!lexer.hasMoreTokens() ) cout << "Lexer has no Tokens"<<endl; >- >- if (!lexer.hasMoreTokens() ) return 0; >- > NodeExpr* nodeExpr = 0; >- >- Token* tok = lexer.nextToken(); >- //cout << "Token #" << tok->type <<endl; >- List params; > >- String* errMsg = 0; >+ Token* nodeTok = lexer.nextToken(); > >- switch ( tok->type ) { >+ switch ( nodeTok->type ) { > case Token::COMMENT: > nodeExpr = new BasicNodeExpr(NodeExpr::COMMENT_EXPR); >- errMsg = parseParameters(¶ms, lexer); >- //-- ignore errMsg for now >- delete errMsg; > break; > case Token::NODE : > nodeExpr = new BasicNodeExpr(); >- errMsg = parseParameters(¶ms, lexer); >- //-- ignore errMsg for now >- delete errMsg; > break; > case Token::PI : > nodeExpr = new BasicNodeExpr(NodeExpr::PI_EXPR); >- errMsg = parseParameters(¶ms, lexer); >- //-- ignore errMsg for now >- delete errMsg; > break; > case Token::TEXT : > nodeExpr = new TextExpr(); >- errMsg = parseParameters(¶ms, lexer); >- //-- ignore errMsg for now >- delete errMsg; > break; > default: >- //XXXX ignore error for now >+ lexer.pushBack(); >+ // XXX ErrorReport: unexpected token >+ return 0; > break; > } >+ >+ if ( lexer.nextToken()->type != Token::L_PAREN ) { >+ lexer.pushBack(); >+ //XXX ErrorReport: left parenthesis expected >+ delete nodeExpr; >+ return 0; >+ } >+ if ( nodeTok->type == Token::PI && lexer.peek()->type == Token::LITERAL ) { >+ Token* tok = lexer.nextToken(); >+ ((BasicNodeExpr*)nodeExpr)->setNodeName(tok->value); >+ } >+ if ( lexer.nextToken()->type != Token::R_PAREN ) { >+ lexer.pushBack(); >+ //XXX ErrorReport: right parenthesis expected (or literal for pi) >+ delete nodeExpr; >+ return 0; >+ } >+ >+ > return nodeExpr; > } //-- createNodeExpr > >@@ -665,37 +641,51 @@ > * Creates a PathExpr using the given ExprLexer > * @param lexer the ExprLexer for retrieving Tokens > **/ >-PathExpr* ExprParser::createPathExpr(ExprLexer& lexer) { >+Expr* ExprParser::createPathExpr(ExprLexer& lexer) { > >+ Expr* expr = 0; > >- //-- check for RootExpr >- if ( lexer.countRemainingTokens() == 1 ) { >- if ( lexer.peek()->type == Token::PARENT_OP ) { >- lexer.nextToken(); //-- eat token >- return new RootExpr(); >- } >+ Token* tok = lexer.peek(); >+ >+ // is this a root expression? >+ if ( tok->type == Token::PARENT_OP ) { >+ lexer.nextToken(); >+ if ( !isLocationStepToken(lexer.peek()) ) >+ return new RootExpr; >+ >+ lexer.pushBack(); > } > >- PathExpr* pathExpr = new PathExpr(); >- short ancestryOp = PathExpr::RELATIVE_OP; >+ // parse first step (possibly a FilterExpr) >+ if ( tok->type != Token::PARENT_OP && >+ tok->type != Token::ANCESTOR_OP ) { >+ if ( isFilterExprToken(tok) ) { >+ expr = createFilterExpr(lexer); >+ } >+ else >+ expr = createLocationStep(lexer); > >- while ( lexer.hasMoreTokens() ) { >- Token* tok = lexer.nextToken(); >- if ( lexer.isOperatorToken(tok) ) { >- lexer.pushBack(); >- return pathExpr; >+ if ( !expr ) { >+ return 0; > } >+ >+ // is this a singlestep path expression? >+ tok = lexer.peek(); >+ if ( tok->type != Token::PARENT_OP && >+ tok->type != Token::ANCESTOR_OP) >+ return expr; >+ } >+ >+ //we have a pathexpression containing several steps >+ PathExpr* pathExpr = new PathExpr(); >+ if(expr) >+ pathExpr->addExpr(expr, PathExpr::RELATIVE_OP); >+ >+ // this is ugly >+ while (1) { >+ short ancestryOp; >+ tok = lexer.nextToken(); > switch ( tok->type ) { >- case Token::R_PAREN: >- case Token::R_BRACKET: >- case Token::UNION_OP: >- //Marina, addition start >- // When parsing a list of parameters for a function comma should signal a spot >- // without it further processing pathExpr was causing "invalid token" error >- case Token::COMMA: >- // Marina, addition ends >- lexer.pushBack(); >- return pathExpr; > case Token::ANCESTOR_OP : > ancestryOp = PathExpr::ANCESTOR_OP; > break; >@@ -704,83 +694,64 @@ > break; > default: > lexer.pushBack(); >- pathExpr->addPatternExpr(createPatternExpr(lexer), ancestryOp); >- ancestryOp = PathExpr::RELATIVE_OP; >- break; >+ return pathExpr; >+ } >+ >+ expr = createLocationStep(lexer); >+ if ( !expr ) { >+ delete pathExpr; >+ return 0; > } >+ >+ pathExpr->addExpr(expr, ancestryOp); > } > >- /* <debug> * >- String tmp; >- pathExpr->toString(tmp); >- cout << "creating pathExpr: " << tmp << endl; >- /* </debug> */ >- > return pathExpr; > } //-- createPathExpr > > /** >- * Creates a PatternExpr using the given ExprLexer >+ * Creates a PathExpr using the given ExprLexer >+ * XXX temporary use as top of XSLT Pattern > * @param lexer the ExprLexer for retrieving Tokens > **/ >-PatternExpr* ExprParser::createPatternExpr(ExprLexer& lexer) { >+Expr* ExprParser::createUnionExpr(ExprLexer& lexer) { > >- PatternExpr* pExpr = 0; >- Token* tok = lexer.peek(); >- if ( isLocationStepToken(tok) ) { >- pExpr = createLocationStep(lexer); >+ if (lexer.peek()->type == Token::ERROR) { >+ // XXX Error notification of caller >+ return 0; > } >- else if ( isFilterExprToken(tok) ) { >- pExpr = createFilterExpr(lexer); >- } >- else { >- cout << "invalid token: " << tok->value << endl; >- //-- eat token for now >- lexer.nextToken(); >- } >- return pExpr; >-} //-- createPatternExpr > >-/** >- * Creates a PathExpr using the given ExprLexer >- * @param lexer the ExprLexer for retrieving Tokens >-**/ >-UnionExpr* ExprParser::createUnionExpr(ExprLexer& lexer) { >+ Expr* expr = createPathExpr(lexer); >+ if(!expr) >+ return 0; >+ >+ if ( lexer.peek()->type != Token::UNION_OP ) >+ return expr; >+ > UnionExpr* unionExpr = new UnionExpr(); >+ unionExpr->addExpr(expr); > >- while ( lexer.hasMoreTokens() ) { >- Token* tok = lexer.nextToken(); >- switch ( tok->type ) { >+ while ( lexer.peek()->type == Token::UNION_OP ) { >+ lexer.nextToken(); //-- eat token > >- case Token::R_PAREN: >- case Token::R_BRACKET: >- lexer.pushBack(); >- return unionExpr; >- case Token::UNION_OP : >- //-- eat token >- break; >- default: >- lexer.pushBack(); >- unionExpr->addPathExpr(createPathExpr(lexer)); >- break; >+ expr = createPathExpr(lexer); >+ if ( !expr ) { >+ delete unionExpr; >+ return 0; > } >+ unionExpr->addExpr(expr); > } >- //String tmp; >- //unionExpr->toString(tmp); >- //cout << "creating UnionExpr: " << tmp << endl; >+ > return unionExpr; > } //-- createUnionExpr > > MBool ExprParser::isFilterExprToken(Token* token) { >- if ( !token ) return MB_FALSE; > switch (token->type) { > case Token::LITERAL: > case Token::NUMBER: > case Token::FUNCTION_NAME: > case Token::VAR_REFERENCE: > case Token::L_PAREN: // grouping expr >- case Token::PARENT_NODE: >- case Token::SELF_NODE : > return MB_TRUE; > default: > return MB_FALSE; >@@ -788,15 +759,19 @@ > } //-- isFilterExprToken > > MBool ExprParser::isLocationStepToken(Token* token) { >- if (!token) return MB_FALSE; >- return ((token->type == Token::AXIS_IDENTIFIER) || isNodeTypeToken(token)); >+ switch (token->type) { >+ case Token::AXIS_IDENTIFIER : >+ case Token::AT_SIGN : >+ case Token::PARENT_NODE : >+ case Token::SELF_NODE : >+ return MB_TRUE; >+ default: >+ return isNodeTypeToken(token); >+ } > } //-- isLocationStepToken > > MBool ExprParser::isNodeTypeToken(Token* token) { >- if (!token) return MB_FALSE; >- > switch ( token->type ) { >- case Token::AT_SIGN: > case Token::CNAME: > case Token::COMMENT: > case Token::NODE : >@@ -806,7 +781,7 @@ > default: > return MB_FALSE; > } >-} //-- isLocationStepToken >+} //-- isNodeTypeToken > > /** > * Using the given lexer, parses the tokens if they represent a predicate list >@@ -816,43 +791,28 @@ > * @param lexer the ExprLexer to use for parsing tokens > * @return 0 if successful, or a String pointer to the error message > **/ >-String* ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer) { >+MBool ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer) { > > String* errorMsg = 0; >- >- Token* tok = lexer.peek(); >- >- if ( !tok ) return 0; //-- no predicates >- if ( tok->type != Token::L_BRACKET ) return 0; //-- not start of predicate list > >- lexer.nextToken(); >+ while ( lexer.peek()->type == Token::L_BRACKET ) { >+ //-- eat Token >+ lexer.nextToken(); > >- while ( lexer.hasMoreTokens() ) { >- tok = lexer.peek(); >- if(!tok) { >- //-- error missing ']' >- errorMsg = new String("missing close of predicate expression ']'"); >- break; >- } >- if ( tok->type == Token::R_BRACKET) { >- lexer.nextToken(); //-- eat ']' >+ Expr* expr = createExpr(lexer); >+ if(!expr) >+ return MB_FALSE; > >+ predicateList->add(expr); > >- //-- Fix: look ahead at next token for mulitple predicates - Marina M. >- tok = lexer.peek(); >- if ((!tok) || ( tok->type != Token::L_BRACKET )) break; >- //-- /Fix >+ if(lexer.nextToken()->type != Token::R_BRACKET) { >+ lexer.pushBack(); >+ //XXX ErrorReport: right bracket expected >+ return MB_FALSE; > } > >- //-- Fix: handle multiple predicates - Marina M. >- if (tok->type == Token::L_BRACKET) >- lexer.nextToken(); //-- swallow '[' >- //-- /Fix >- >- Expr* expr = createExpr(lexer); >- predicateList->add(expr); > } >- return errorMsg; >+ return MB_TRUE; > > } //-- parsePredicates > >@@ -863,48 +823,41 @@ > * error message. > * @param list, the List to add parameter expressions to > * @param lexer the ExprLexer to use for parsing tokens >- * @return 0 if successful, or a String pointer to the error message >+ * @return MB_TRUE if successful, or a MB_FALSE otherwise > **/ >-String* ExprParser::parseParameters(List* list, ExprLexer& lexer) { >- >- String* errorMsg = 0; >+MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer) { > >- Token* tok = lexer.peek(); >- >- if ( !tok ) return 0; //-- no params >- if ( tok->type != Token::L_PAREN ) return 0; //-- not start of param list >+ if ( lexer.nextToken()->type != Token::L_PAREN ) { >+ lexer.pushBack(); >+ //XXX ErrorReport: left parenthesis expected >+ return MB_FALSE; >+ } > >- lexer.nextToken(); //-- eat L_PAREN >+ if( lexer.peek()->type == Token::R_PAREN ) { >+ lexer.nextToken(); >+ return MB_TRUE; >+ } > >- MBool done = MB_FALSE; >- MBool foundSep = MB_FALSE; >+ while ( 1 ) { >+ Expr* expr = createExpr(lexer); >+ if(!expr) >+ return MB_FALSE; > >- while ( lexer.hasMoreTokens() && !done) { >- tok = lexer.peek(); >- switch ( tok->type ) { >+ fnCall->addParam(expr); >+ >+ switch ( lexer.nextToken()->type ) { > case Token::R_PAREN : >- if (foundSep) errorMsg = new String("missing expression after ','"); >- lexer.nextToken(); //-- eat R_PAREN >- done = MB_TRUE; >- break; >+ return MB_TRUE; > case Token::COMMA: //-- param separator >- //-- eat COMMA >- lexer.nextToken(); >- foundSep = MB_TRUE; > break; > default: >- if ((list->getLength() > 0) && (!foundSep)) { >- errorMsg = new String("missing ',' or ')'"); >- done = MB_TRUE; >- break; >- } >- foundSep = MB_FALSE; >- Expr* expr = createExpr(lexer); >- list->add(expr); >- break; >+ lexer.pushBack(); >+ //XXX ErrorReport: right parenthesis or comma expected >+ return MB_FALSE; > } > } >- return errorMsg; >+ >+ return MB_FALSE; > > } //-- parseParameters > >Index: source/xpath/ExprParser.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/ExprParser.h,v >retrieving revision 1.4 >diff -u -r1.4 ExprParser.h >--- ExprParser.h 2001/04/08 14:38:23 1.4 >+++ ExprParser.h 2001/04/12 22:47:35 >@@ -44,9 +44,6 @@ > > public: > >- static const String R_CURLY_BRACE; >- static const String L_CURLY_BRACE; >- > /** > * Creates a new ExprParser > **/ >@@ -58,7 +55,7 @@ > ~ExprParser(); > > Expr* createExpr (const String& pattern); >- PatternExpr* createPatternExpr (const String& pattern); >+ Expr* createPatternExpr (const String& pattern); > LocationStep* createLocationStep(const String& path); > > /** >@@ -72,13 +69,12 @@ > > Expr* createBinaryExpr (Expr* left, Expr* right, Token* op); > Expr* createExpr (ExprLexer& lexer); >- FilterExpr* createFilterExpr (ExprLexer& lexer); >+ Expr* createFilterExpr (ExprLexer& lexer); > FunctionCall* createFunctionCall (ExprLexer& lexer); > LocationStep* createLocationStep (ExprLexer& lexer); > NodeExpr* createNodeExpr (ExprLexer& lexer); >- PathExpr* createPathExpr (ExprLexer& lexer); >- PatternExpr* createPatternExpr (ExprLexer& lexer); >- UnionExpr* createUnionExpr (ExprLexer& lexer); >+ Expr* createPathExpr (ExprLexer& lexer); >+ Expr* createUnionExpr (ExprLexer& lexer); > > MBool isFilterExprToken (Token* tok); > MBool isLocationStepToken (Token* tok); >@@ -94,8 +90,8 @@ > * @param lexer the ExprLexer to use for parsing tokens > * @return 0 if successful, or a String pointer to the error message > **/ >- String* parsePredicates(PredicateList* predicateList, ExprLexer& lexer); >- String* parseParameters(List* list, ExprLexer& lexer); >+ MBool parsePredicates(PredicateList* predicateList, ExprLexer& lexer); >+ MBool parseParameters(FunctionCall* fnCall, ExprLexer& lexer); > > > }; //-- ExprParser >Index: source/xpath/FunctionCall.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/FunctionCall.cpp,v >retrieving revision 1.2 >diff -u -r1.2 FunctionCall.cpp >--- FunctionCall.cpp 2000/04/19 10:36:17 1.2 >+++ FunctionCall.cpp 2001/04/12 22:47:35 >@@ -101,6 +101,31 @@ > } //-- addParam > > /** >+ * Returns the default priority of this Expr based on the given Node, >+ * context Node, and ContextState. >+**/ >+double FunctionCall::getDefaultPriority(Node* node, Node* context, ContextState* cs) { >+ return 0.5; >+} //-- getDefaultPriority >+ >+/** >+ * Determines whether this Expr matches the given node within >+ * the given context >+**/ >+MBool FunctionCall::matches(Node* node, Node* context, ContextState* cs) { >+ >+ MBool result = MB_FALSE; >+ ExprResult* exprResult = evaluate(node, cs); >+ if ( exprResult->getResultType() == ExprResult::NODESET ) { >+ NodeSet* nodes = (NodeSet*)exprResult; >+ result = (nodes->contains(node)); >+ } >+ delete exprResult; >+ return result; >+ >+} //-- matches >+ >+/** > * Evaluates the given Expression and converts it's result to a String. > * The value is appended to the given destination String > **/ >Index: source/xpath/Makefile >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/Makefile,v >retrieving revision 1.3 >diff -u -r1.3 Makefile >--- Makefile 2001/01/22 09:36:17 1.3 >+++ Makefile 2001/04/12 22:47:35 >@@ -23,17 +23,16 @@ > BooleanExpr.o \ > BooleanResult.o \ > ElementExpr.o \ >+ Expr.o \ > ExprLexer.o \ > ExprParser.o \ > FilterExpr.o \ >- IdentityExpr.o \ > LocationStep.o \ > MultiplicativeExpr.o \ > NodeSet.o \ > NumberExpr.o \ > NumberResult.o \ > PredicateList.o \ >- ParentExpr.o \ > PathExpr.o \ > RelationalExpr.o \ > RootExpr.o \ >@@ -41,6 +40,7 @@ > StringResult.o \ > TextExpr.o \ > UnionExpr.o \ >+ UnaryExpr.o \ > VariableRefExpr.o \ > XPathNames.o > >@@ -80,6 +80,9 @@ > ElementExpr.o: Expr.h ElementExpr.cpp > $(CC) $(INCLUDE_PATHS) -c ElementExpr.cpp > >+Expr.o: Expr.cpp Expr.h >+ $(CC) $(INCLUDE_PATHS) -c Expr.cpp >+ > ExprLexer.o: ExprLexer.cpp ExprLexer.h > $(CC) $(INCLUDE_PATHS) -c ExprLexer.cpp > >@@ -133,6 +136,9 @@ > > UnionExpr.o: Expr.h UnionExpr.cpp > $(CC) $(INCLUDE_PATHS) -c UnionExpr.cpp >+ >+UnaryExpr.o: Expr.h UnaryExpr.cpp >+ $(CC) $(INCLUDE_PATHS) -c UnaryExpr.cpp > > VariableRefExpr.o: Expr.h VariableRefExpr.cpp > $(CC) $(INCLUDE_PATHS) -c VariableRefExpr.cpp >Index: source/xpath/Makefile.in >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/Makefile.in,v >retrieving revision 1.7 >diff -u -r1.7 Makefile.in >--- Makefile.in 2001/01/22 14:12:16 1.7 >+++ Makefile.in 2001/04/12 22:47:35 >@@ -35,12 +35,12 @@ > BooleanResult.cpp \ > ElementExpr.cpp \ > ErrorFunctionCall.cpp \ >+ Expr.cpp \ > ExprLexer.cpp \ > ExprParser.cpp \ > ExtensionFunctionCall.cpp \ > FilterExpr.cpp \ > FunctionCall.cpp \ >- IdentityExpr.cpp \ > LocationStep.cpp \ > MultiplicativeExpr.cpp \ > NodeSet.cpp \ >@@ -48,7 +48,6 @@ > NumberExpr.cpp \ > NumberFunctionCall.cpp \ > NumberResult.cpp \ >- ParentExpr.cpp \ > PathExpr.cpp \ > PredicateList.cpp \ > RelationalExpr.cpp \ >@@ -58,6 +57,7 @@ > StringResult.cpp \ > TextExpr.cpp \ > UnionExpr.cpp \ >+ UnaryExpr.cpp \ > VariableRefExpr.cpp \ > XPathNames.cpp > ifdef MOZ_XSL >Index: source/xpath/PathExpr.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/PathExpr.cpp,v >retrieving revision 1.5 >diff -u -r1.5 PathExpr.cpp >--- PathExpr.cpp 2001/01/12 20:06:36 1.5 >+++ PathExpr.cpp 2001/04/12 22:47:35 >@@ -47,41 +47,41 @@ > } > > /** >- * Destructor, will delete all Pattern Expressions >+ * Destructor, will delete all Expressions > **/ > PathExpr::~PathExpr() { > ListIterator* iter = expressions.iterator(); > while ( iter->hasNext() ) { > iter->next(); > PathExprItem* pxi = (PathExprItem*)iter->remove(); >- delete pxi->pExpr; >+ delete pxi->expr; > delete pxi; > } > delete iter; > } //-- ~PathExpr > > /** >- * Adds the PatternExpr to this PathExpr >+ * Adds the Expr to this PathExpr > * @param expr the Expr to add to this PathExpr > * @param index the index at which to add the given Expr > **/ >-void PathExpr::addPatternExpr(int index, PatternExpr* expr, short ancestryOp) { >+void PathExpr::addExpr(int index, Expr* expr, short ancestryOp) { > if (expr) { > PathExprItem* pxi = new PathExprItem; >- pxi->pExpr = expr; >+ pxi->expr = expr; > pxi->ancestryOp = ancestryOp; > expressions.insert(index, pxi); > } > } //-- addPattenExpr > > /** >- * Adds the PatternExpr to this PathExpr >+ * Adds the Expr to this PathExpr > * @param expr the Expr to add to this PathExpr > **/ >-void PathExpr::addPatternExpr(PatternExpr* expr, short ancestryOp) { >+void PathExpr::addExpr(Expr* expr, short ancestryOp) { > if (expr) { > PathExprItem* pxi = new PathExprItem; >- pxi->pExpr = expr; >+ pxi->expr = expr; > pxi->ancestryOp = ancestryOp; > expressions.add(pxi); > } >@@ -97,9 +97,9 @@ > return MB_FALSE; > } //-- isAbsolute > >- //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >-//------------------------------------/ >+ //-----------------------------/ >+ //- Virtual methods from Expr -/ >+//-----------------------------/ > > /** > * Evaluates this Expr based on the given context node and processor state >@@ -124,33 +124,37 @@ > > ListIterator* iter = expressions.iterator(); > >- MBool ancestorMode = MB_FALSE; > while ( iter->hasNext() ) { > > PathExprItem* pxi = (PathExprItem*)iter->next(); >- ancestorMode = (ancestorMode || (pxi->ancestryOp == ANCESTOR_OP)); > NodeSet* tmpNodes = 0; > cs->getNodeSetStack()->push(nodes); > for (int i = 0; i < nodes->size(); i++) { > Node* node = nodes->get(i); >-#if 0 >- NodeSet* xNodes = (NodeSet*) pxi->pExpr->evaluate(node, cs); >-#else >- ExprResult *res = pxi->pExpr->evaluate(node, cs); >- if (!res || res->getResultType() != ExprResult::NODESET) >- continue; >- NodeSet* xNodes = (NodeSet *) res; >-#endif >- if ( tmpNodes ) { >- xNodes->copyInto(*tmpNodes); >+ >+ NodeSet* resNodes; >+ if ( pxi->ancestryOp == ANCESTOR_OP) { >+ resNodes = new NodeSet; >+ evalDescendants(pxi->expr, node, cs, resNodes); > } > else { >- tmpNodes = xNodes; >- xNodes = 0; >+ ExprResult *res = pxi->expr->evaluate(node, cs); >+ if (!res || res->getResultType() != ExprResult::NODESET) { >+ //XXX ErrorReport: report nonnodeset error >+ delete res; >+ res = new NodeSet; >+ } >+ >+ resNodes = (NodeSet*)res; > } >- delete xNodes; >- //-- handle ancestorMode >- if ( ancestorMode ) fromDescendants(pxi->pExpr, node, cs, tmpNodes); >+ >+ if ( tmpNodes ) { >+ resNodes->copyInto(*tmpNodes); >+ delete resNodes; >+ } >+ else >+ tmpNodes = resNodes; >+ > } > delete (NodeSet*) cs->getNodeSetStack()->pop(); > nodes = tmpNodes; >@@ -163,51 +167,50 @@ > > /** > * Selects from the descendants of the context node >- * all nodes that match the PatternExpr >+ * all nodes that match the Expr > * -- this will be moving to a Utility class > **/ >-void PathExpr::fromDescendants >- (PatternExpr* pExpr, Node* context, ContextState* cs, NodeSet* nodes) >+void PathExpr::evalDescendants >+ (Expr* expr, Node* context, ContextState* cs, NodeSet* resNodes) > { > >- if (( !context ) || (! pExpr )) return; >- >- NodeList* nl = context->getChildNodes(); >- for (UInt32 i = 0; i < nl->getLength(); i++) { >- Node* child = nl->item(i); >- if (pExpr->matches(child, context, cs)) >- nodes->add(child); >- //-- check childs descendants >- if (child->hasChildNodes()) >- fromDescendants(pExpr, child, cs, nodes); >+ ExprResult *res = expr->evaluate(context, cs); >+ if (!res || res->getResultType() != ExprResult::NODESET) { >+ //XXX ErrorReport: report nonnodeset error >+ } >+ ((NodeSet*)res)->copyInto(*resNodes); >+ delete res; >+ >+ Node* child = context->getFirstChild(); >+ while(child) { >+ //XXX WhiteSpace: filter whitespace nodes >+ evalDescendants(expr, child, cs, resNodes); >+ child = child->getNextSibling(); > } >+ >+ > } //-- fromDescendants > > /** >- * Returns the default priority of this Pattern based on the given Node, >+ * Returns the default priority of this Expr based on the given Node, > * context Node, and ContextState. >- * If this pattern does not match the given Node under the current context Node and >- * ContextState then Negative Infinity is returned. > **/ > double PathExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { > >- if ( matches(node, context, cs) ) { >- int size = expressions.getLength(); >- if ( size == 1) { >- ListIterator* iter = expressions.iterator(); >- PathExprItem* pxi = (PathExprItem*)iter->next(); >- delete iter; >- return pxi->pExpr->getDefaultPriority(node, context, cs); >- } >- else if ( size > 1 ) { >- return 0.5; >- } >+ int size = expressions.getLength(); >+ if ( size > 1 || isAbsolute() ) { >+ return 0.5; > } >- return Double::NEGATIVE_INFINITY; >+ >+ ListIterator* iter = expressions.iterator(); >+ PathExprItem* pxi = (PathExprItem*)iter->next(); >+ delete iter; >+ return pxi->expr->getDefaultPriority(node, context, cs); >+ > } //-- getDefaultPriority > > /** >- * Determines whether this PatternExpr matches the given node within >+ * Determines whether this Expr matches the given node within > * the given context > **/ > MBool PathExpr::matches(Node* node, Node* context, ContextState* cs) { >@@ -231,7 +234,7 @@ > { > Node* ancestor = node; > while (ancestor = cs->getParentNode(ancestor)) { >- if (pxi->pExpr->matches(node, ancestor, cs)) >+ if (pxi->expr->matches(node, ancestor, cs)) > return MB_TRUE; > } > break; >@@ -242,12 +245,12 @@ > if (parent) { > //-- make sure node is Document node > if (parent->getNodeType() == Node::DOCUMENT_NODE) >- return pxi->pExpr->matches(node, parent, cs); >+ return pxi->expr->matches(node, parent, cs); > } > break; > } > default: >- return pxi->pExpr->matches(node, context, cs); >+ return pxi->expr->matches(node, context, cs); > > } > >@@ -280,7 +283,7 @@ > { > Node* parent = tnode; > while (parent = cs->getParentNode(parent)) { >- if (pxi->pExpr->matches(tnode, parent, cs)) >+ if (pxi->expr->matches(tnode, parent, cs)) > tmpNodes.add(parent); > } > break; >@@ -294,7 +297,7 @@ > if ( !iter->hasNext() ) > if (parent->getNodeType() != Node::DOCUMENT_NODE) break; > >- if (pxi->pExpr->matches(tnode, parent, cs)) >+ if (pxi->expr->matches(tnode, parent, cs)) > tmpNodes.add(parent); > } > break; >@@ -303,15 +306,15 @@ > if ( !iter->hasNext() ) { > > /* >- // PREVIOUS // result = pxi->pExpr->matches(tnode, context, cs); >+ // PREVIOUS // result = pxi->expr->matches(tnode, context, cs); > // result was being overwritten if there was more than one > // node in nodes during the final iteration (Marina) > >- result = result || pxi->pExpr->matches(tnode, context, cs) >+ result = result || pxi->expr->matches(tnode, context, cs) > */ > > //-- Just return true if we match here >- if (pxi->pExpr->matches(tnode, context, cs)) { >+ if (pxi->expr->matches(tnode, context, cs)) { > delete iter; > return MB_TRUE; > } >@@ -352,12 +355,12 @@ > > > /** >- * Returns the String representation of this PatternExpr. >+ * Returns the String representation of this Expr. > * @param dest the String to use when creating the String > * representation. The String representation will be appended to > * any data in the destination String, to allow cascading calls to > * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >+ * @return the String representation of this Expr. > **/ > void PathExpr::toString(String& dest) { > ListIterator* iter = expressions.iterator(); >@@ -374,7 +377,7 @@ > default: > break; > } >- pxi->pExpr->toString(dest); >+ pxi->expr->toString(dest); > } > delete iter; > } //-- toString >Index: source/xpath/StringExpr.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/StringExpr.cpp,v >retrieving revision 1.1 >diff -u -r1.1 StringExpr.cpp >--- StringExpr.cpp 2000/04/06 07:45:39 1.1 >+++ StringExpr.cpp 2001/04/12 22:47:35 >@@ -72,8 +72,11 @@ > * @return the String representation of this Expr. > **/ > void StringExpr::toString(String& str) { >- str.append('\''); >+ UNICODE_CHAR ch = '\''; >+ if ( value.indexOf(ch) != NOT_FOUND ) >+ ch = '\"'; >+ str.append(ch); > str.append(value); >- str.append('\''); >+ str.append(ch); > } //-- toString > >Index: source/xpath/UnionExpr.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/UnionExpr.cpp,v >retrieving revision 1.1 >diff -u -r1.1 UnionExpr.cpp >--- UnionExpr.cpp 2000/04/06 07:45:52 1.1 >+++ UnionExpr.cpp 2001/04/12 22:47:35 >@@ -45,29 +45,29 @@ > ListIterator* iter = expressions.iterator(); > while ( iter->hasNext() ) { > iter->next(); >- delete (PathExpr*)iter->remove(); >+ delete (Expr*)iter->remove(); > } > delete iter; > } //-- ~UnionExpr > > /** >- * Adds the PathExpr to this UnionExpr >- * @param pathExpr the PathExpr to add to this UnionExpr >+ * Adds the Expr to this UnionExpr >+ * @param expr the Expr to add to this UnionExpr > **/ >-void UnionExpr::addPathExpr(PathExpr* pathExpr) { >- if (pathExpr) expressions.add(pathExpr); >-} //-- addPathExpr >+void UnionExpr::addExpr(Expr* expr) { >+ if (expr) expressions.add(expr); >+} //-- addExpr > > /** >- * Adds the PathExpr to this UnionExpr >- * @param pathExpr the PathExpr to add to this UnionExpr >+ * Adds the Expr to this UnionExpr >+ * @param expr the Expr to add to this UnionExpr > **/ >-void UnionExpr::addPathExpr(int index, PathExpr* pathExpr) { >- if (pathExpr) expressions.insert(index, pathExpr); >-} //-- addPathExpr >+void UnionExpr::addExpr(int index, Expr* expr) { >+ if (expr) expressions.insert(index, expr); >+} //-- addExpr > > //------------------------------------/ >- //- Virtual methods from PatternExpr -/ >+ //- Virtual methods from Expr -/ > //------------------------------------/ > > /** >@@ -88,12 +88,11 @@ > > while ( iter->hasNext() ) { > >- PathExpr* pExpr = (PathExpr*)iter->next(); >- NodeSet* tmpNodes = (NodeSet*)pExpr->evaluate(context, cs); >- for (int j = 0; j < tmpNodes->size(); j++) { >- nodes->add(tmpNodes->get(j)); >+ Expr* expr = (Expr*)iter->next(); >+ ExprResult* exprResult = expr->evaluate(context, cs); >+ if ( exprResult->getResultType() == ExprResult::NODESET ) { >+ ((NodeSet*)exprResult)->copyInto(*nodes); > } >- delete tmpNodes; > } > > delete iter; >@@ -112,9 +111,9 @@ > double priority = Double::NEGATIVE_INFINITY; > ListIterator* iter = expressions.iterator(); > while ( iter->hasNext() ) { >- PathExpr* pExpr = (PathExpr*)iter->next(); >- if ( pExpr->matches(node, context, cs) ) { >- double tmpPriority = pExpr->getDefaultPriority(node, context, cs); >+ Expr* expr = (Expr*)iter->next(); >+ if ( expr->matches(node, context, cs) ) { >+ double tmpPriority = expr->getDefaultPriority(node, context, cs); > priority = (tmpPriority > priority) ? tmpPriority : priority; > } > } >@@ -132,8 +131,8 @@ > ListIterator* iter = expressions.iterator(); > > while ( iter->hasNext() ) { >- PathExpr* pExpr = (PathExpr*)iter->next(); >- if ( pExpr->matches(node, context, cs) ) { >+ Expr* expr = (Expr*)iter->next(); >+ if ( expr->matches(node, context, cs) ) { > delete iter; > return MB_TRUE; > } >@@ -144,12 +143,12 @@ > > > /** >- * Returns the String representation of this PatternExpr. >+ * Returns the String representation of this Expr. > * @param dest the String to use when creating the String > * representation. The String representation will be appended to > * any data in the destination String, to allow cascading calls to > * other #toString() methods for Expressions. >- * @return the String representation of this PatternExpr. >+ * @return the String representation of this Expr. > **/ > void UnionExpr::toString(String& dest) { > ListIterator* iter = expressions.iterator(); >@@ -158,7 +157,7 @@ > while ( iter->hasNext() ) { > //-- set operator > if (count > 0) dest.append(" | "); >- ((PathExpr*)iter->next())->toString(dest); >+ ((Expr*)iter->next())->toString(dest); > ++count; > } > delete iter; >Index: source/xpath/makefile.win >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xpath/makefile.win,v >retrieving revision 1.11 >diff -u -r1.11 makefile.win >--- makefile.win 2001/01/22 15:03:12 1.11 >+++ makefile.win 2001/04/12 22:47:35 >@@ -35,12 +35,12 @@ > BooleanResult.cpp \ > ElementExpr.cpp \ > ErrorFunctionCall.cpp \ >+ Expr.cpp \ > ExprLexer.cpp \ > ExprParser.cpp \ > ExtensionFunctionCall.cpp \ > FilterExpr.cpp \ > FunctionCall.cpp \ >- IdentityExpr.cpp \ > LocationStep.cpp \ > MultiplicativeExpr.cpp \ > NodeSet.cpp \ >@@ -48,7 +48,6 @@ > NumberExpr.cpp \ > NumberFunctionCall.cpp \ > NumberResult.cpp \ >- ParentExpr.cpp \ > PathExpr.cpp \ > PredicateList.cpp \ > RelationalExpr.cpp \ >@@ -58,6 +57,7 @@ > StringResult.cpp \ > TextExpr.cpp \ > UnionExpr.cpp \ >+ UnaryExpr.cpp \ > VariableRefExpr.cpp \ > XPathNames.cpp \ > !if defined(MOZ_XSL) >@@ -76,12 +76,12 @@ > .\$(OBJDIR)\BooleanResult.obj \ > .\$(OBJDIR)\ElementExpr.obj \ > .\$(OBJDIR)\ErrorFunctionCall.obj \ >+ .\$(OBJDIR)\Expr.obj \ > .\$(OBJDIR)\ExprLexer.obj \ > .\$(OBJDIR)\ExprParser.obj \ > .\$(OBJDIR)\ExtensionFunctionCall.obj \ > .\$(OBJDIR)\FilterExpr.obj \ > .\$(OBJDIR)\FunctionCall.obj \ >- .\$(OBJDIR)\IdentityExpr.obj \ > .\$(OBJDIR)\LocationStep.obj \ > .\$(OBJDIR)\MultiplicativeExpr.obj \ > .\$(OBJDIR)\NodeSet.obj \ >@@ -89,7 +89,6 @@ > .\$(OBJDIR)\NumberExpr.obj \ > .\$(OBJDIR)\NumberFunctionCall.obj \ > .\$(OBJDIR)\NumberResult.obj \ >- .\$(OBJDIR)\ParentExpr.obj \ > .\$(OBJDIR)\PathExpr.obj \ > .\$(OBJDIR)\PredicateList.obj \ > .\$(OBJDIR)\RelationalExpr.obj \ >@@ -99,6 +98,7 @@ > .\$(OBJDIR)\StringResult.obj \ > .\$(OBJDIR)\TextExpr.obj \ > .\$(OBJDIR)\UnionExpr.obj \ >+ .\$(OBJDIR)\UnaryExpr.obj \ > .\$(OBJDIR)\VariableRefExpr.obj \ > .\$(OBJDIR)\XPathNames.obj \ > !if defined(MOZ_XSL) >Index: source/xslt/ProcessorState.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/transformiix/source/xslt/ProcessorState.cpp,v >retrieving revision 1.25 >diff -u -r1.25 ProcessorState.cpp >--- ProcessorState.cpp 2001/04/12 14:04:49 1.25 >+++ ProcessorState.cpp 2001/04/12 22:47:35 >@@ -197,8 +197,10 @@ > namedTemplates.put(name,mObj); > if ( oldObj ) delete oldObj; > } >- patternExprHash.put(match, exprParser.createPatternExpr(match)); >- templates.add(xslTemplate); >+ if ( match.length() > 0 ) { >+ patternExprHash.put(match, exprParser.createPatternExpr(match)); >+ templates.add(xslTemplate); >+ } > } //-- addTempalte > > /**
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
|
Review
Attachments on
bug 75102
:
30266
|
30268
|
30269
|
30270
|
30271
| 30662 |
30663
|
30664
|
30666
|
37652
|
37653
|
38503
|
38508
|
38590
|
38591
|
38595
|
38596
|
39504
|
40618