net.sf.saxon.expr
Class ExpressionParser

java.lang.Object
  extended by net.sf.saxon.expr.ExpressionParser
Direct Known Subclasses:
QueryParser, SelectionParser

public class ExpressionParser
extends java.lang.Object

Parser for XPath expressions and XSLT patterns. This code was originally inspired by James Clark's xt but has been totally rewritten (several times)

Author:
Michael Kay

Nested Class Summary
static class ExpressionParser.ForClause
           
protected static class ExpressionParser.TemporaryContainer
           
 
Field Summary
protected  boolean compileWithTracing
           
protected  StaticContext env
           
protected  int language
           
protected  NameChecker nameChecker
           
protected  java.util.Stack rangeVariables
           
protected  boolean scanOnly
           
protected static int SEQUENCE_TYPE
           
protected  Tokenizer t
           
protected static int XPATH
           
protected static int XQUERY
           
protected static int XSLT_PATTERN
           
 
Constructor Summary
ExpressionParser()
          Create an expression parser
 
Method Summary
protected  java.lang.String currentTokenDisplay()
          Display the current token in an error message
protected  void declareRangeVariable(Binding declaration)
          Declare a range variable (record its existence within the parser).
protected  void expect(int token)
          Expect a given token; fail if the current token is different.
protected  java.lang.String getLanguage()
          Get the current language (XPath or XQuery)
 java.util.Stack getRangeVariableStack()
          Get the range variable stack.
 Tokenizer getTokenizer()
          Get the tokenizer (the lexical analyzer)
protected  void grumble(java.lang.String message)
          Report a syntax error (a static error with error code XP0003)
protected  void grumble(java.lang.String message, java.lang.String errorCode)
          Report a static error
 boolean isCompileWithTracing()
          Determine whether trace hooks are included in the compiled code.
protected  boolean isKeyword(java.lang.String s)
          Test whether the current token is a given keyword.
 LocalNameTest makeLocalNameTest(short nodeType, java.lang.String localName)
          Make a LocalNameTest (*:name)
 int makeNameCode(java.lang.String qname, boolean useDefault)
          Make a NameCode, using the static context for namespace resolution
 int makeNameCodeSilently(java.lang.String qname, boolean useDefault)
          Make a NameCode, using the static context for namespace resolution.
 NamespaceTest makeNamespaceTest(short nodeType, java.lang.String prefix)
          Make a NamespaceTest (name:*)
 NameTest makeNameTest(short nodeType, java.lang.String qname, boolean useDefault)
          Make a NameTest, using the static context for namespace resolution
protected  Literal makeStringLiteral(java.lang.String currentTokenValue)
          Method to make a string literal from a token identified as a string literal.
 StructuredQName makeStructuredQName(java.lang.String qname, boolean useDefault)
          Make a Structured QName, using the static context for namespace resolution
protected  Expression makeTracer(int startOffset, Expression exp, int construct, StructuredQName qName)
          If tracing, wrap an expression in a trace instruction
protected  void nextToken()
          Read the next token, catching any exception thrown by the tokenizer
 Expression parse(java.lang.String expression, int start, int terminator, int lineNumber, StaticContext env)
          Parse a string representing an expression
protected  Expression parseConstructor()
          Parse a node constructor.
protected  Expression parseExpression()
          Parse a top-level Expression: ExprSingle ( ',' ExprSingle )*
protected  Expression parseExprSingle()
          Parse an ExprSingle
protected  Expression parseExtensionExpression()
          Parse an Extension Expression This construct is XQuery-only, so the XPath version of this method throws an error unconditionally
protected  Expression parseForExpression()
          Parse a FOR expression: for $x in expr (',' $y in expr)* 'return' expr
protected  Expression parseFunctionCall()
          Parse a function call.
protected  Expression parseMappingExpression()
          Parse a mapping expression.
protected  NodeTest parseNodeTest(short nodeType)
          Parse a NodeTest.
 Pattern parsePattern(java.lang.String pattern, StaticContext env)
          Parse a string representing an XSLT pattern
protected  Expression parseRelativePath()
          Parse a relative path (a sequence of steps).
protected  Expression parseRemainingPath(Expression start)
          Parse the remaining steps of an absolute path expression (one starting in "/" or "//").
protected  SequenceType parseSequenceType()
          Parse the sequence type production.
 SequenceType parseSequenceType(java.lang.String input, StaticContext env)
          Parse a string representing a sequence type
protected  Expression parseStepExpression()
          Parse a step (including an optional sequence of predicates)
protected  Expression parseTypeswitchExpression()
          Parse a Typeswitch Expression.
protected  Expression parseValidateExpression()
          Parse a Validate Expression.
 void setCompileWithTracing(boolean trueOrFalse)
          Set whether trace hooks are to be included in the compiled code.
protected  void setLocation(Expression exp)
          Set location information on an expression.
protected  void setLocation(Expression exp, int offset)
          Set location information on an expression.
 void setRangeVariableStack(java.util.Stack stack)
          Set the range variable stack.
 void setScanOnly(boolean scanOnly)
          Set that we are parsing in "scan only"
protected  void undeclareRangeVariable()
          Note when the most recently declared range variable has gone out of scope
protected  void warning(java.lang.String message)
          Output a warning message
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

t

protected Tokenizer t

env

protected StaticContext env

rangeVariables

protected java.util.Stack rangeVariables

nameChecker

protected NameChecker nameChecker

scanOnly

protected boolean scanOnly

compileWithTracing

protected boolean compileWithTracing

language

protected int language

XPATH

protected static final int XPATH
See Also:
Constant Field Values

XSLT_PATTERN

protected static final int XSLT_PATTERN
See Also:
Constant Field Values

SEQUENCE_TYPE

protected static final int SEQUENCE_TYPE
See Also:
Constant Field Values

XQUERY

protected static final int XQUERY
See Also:
Constant Field Values
Constructor Detail

ExpressionParser

public ExpressionParser()
Create an expression parser

Method Detail

setCompileWithTracing

public void setCompileWithTracing(boolean trueOrFalse)
Set whether trace hooks are to be included in the compiled code. To use tracing, it is necessary both to compile the code with trace hooks included, and to supply a TraceListener at run-time

Parameters:
trueOrFalse - true if trace code is to be compiled in, false otherwise

isCompileWithTracing

public boolean isCompileWithTracing()
Determine whether trace hooks are included in the compiled code.

Returns:
true if trace hooks are included, false if not.

getTokenizer

public Tokenizer getTokenizer()
Get the tokenizer (the lexical analyzer)

Returns:
the tokenizer (the lexical analyzer)

nextToken

protected void nextToken()
                  throws XPathException
Read the next token, catching any exception thrown by the tokenizer

Throws:
XPathException

expect

protected void expect(int token)
               throws XPathException
Expect a given token; fail if the current token is different. Note that this method does not read any tokens.

Parameters:
token - the expected token
Throws:
XPathException - if the current token is not the expected token

grumble

protected void grumble(java.lang.String message)
                throws XPathException
Report a syntax error (a static error with error code XP0003)

Parameters:
message - the error message
Throws:
XPathException - always thrown: an exception containing the supplied message

grumble

protected void grumble(java.lang.String message,
                       java.lang.String errorCode)
                throws XPathException
Report a static error

Parameters:
message - the error message
errorCode - the error code
Throws:
XPathException - always thrown: an exception containing the supplied message

warning

protected void warning(java.lang.String message)
                throws XPathException
Output a warning message

Parameters:
message - the text of the message
Throws:
XPathException

getLanguage

protected java.lang.String getLanguage()
Get the current language (XPath or XQuery)

Returns:
a string representation of the language being parsed, for use in error messages

currentTokenDisplay

protected java.lang.String currentTokenDisplay()
Display the current token in an error message

Returns:
the display representation of the token

parse

public Expression parse(java.lang.String expression,
                        int start,
                        int terminator,
                        int lineNumber,
                        StaticContext env)
                 throws XPathException
Parse a string representing an expression

Parameters:
expression - the expression expressed as a String
start - offset within the string where parsing is to start
terminator - character to treat as terminating the expression
lineNumber - location of the start of the expression, for diagnostics
env - the static context for the expression
Returns:
an Expression object representing the result of parsing
Throws:
XPathException - if the expression contains a syntax error

parsePattern

public Pattern parsePattern(java.lang.String pattern,
                            StaticContext env)
                     throws XPathException
Parse a string representing an XSLT pattern

Parameters:
pattern - the pattern expressed as a String
env - the static context for the pattern
Returns:
a Pattern object representing the result of parsing
Throws:
XPathException - if the pattern contains a syntax error

parseSequenceType

public SequenceType parseSequenceType(java.lang.String input,
                                      StaticContext env)
                               throws XPathException
Parse a string representing a sequence type

Parameters:
input - the string, which should conform to the XPath SequenceType production
env - the static context
Returns:
a SequenceType object representing the type
Throws:
XPathException - if any error is encountered

parseExpression

protected Expression parseExpression()
                              throws XPathException
Parse a top-level Expression: ExprSingle ( ',' ExprSingle )*

Returns:
the Expression object that results from parsing
Throws:
XPathException - if the expression contains a syntax error

parseExprSingle

protected Expression parseExprSingle()
                              throws XPathException
Parse an ExprSingle

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

parseTypeswitchExpression

protected Expression parseTypeswitchExpression()
                                        throws XPathException
Parse a Typeswitch Expression. This construct is XQuery-only, so the XPath version of this method throws an error unconditionally

Returns:
the expression that results from the parsing
Throws:
XPathException

parseValidateExpression

protected Expression parseValidateExpression()
                                      throws XPathException
Parse a Validate Expression. This construct is XQuery-only, so the XPath version of this method throws an error unconditionally

Returns:
the parsed expression; except that this version of the method always throws an exception
Throws:
XPathException

parseExtensionExpression

protected Expression parseExtensionExpression()
                                       throws XPathException
Parse an Extension Expression This construct is XQuery-only, so the XPath version of this method throws an error unconditionally

Returns:
the parsed expression; except that this version of the method always throws an exception
Throws:
XPathException

parseForExpression

protected Expression parseForExpression()
                                 throws XPathException
Parse a FOR expression: for $x in expr (',' $y in expr)* 'return' expr

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

parseMappingExpression

protected Expression parseMappingExpression()
                                     throws XPathException
Parse a mapping expression. This is a common routine that handles XPath 'for' expressions and quantified expressions.

Syntax:
(for|some|every) $x in expr (',' $y in expr)* (return|satisfies) expr

On entry, the current token indicates whether a for, some, or every expression is expected.

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

parseSequenceType

protected SequenceType parseSequenceType()
                                  throws XPathException
Parse the sequence type production. The QName must be the name of a built-in schema-defined data type.

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

parseRelativePath

protected Expression parseRelativePath()
                                throws XPathException
Parse a relative path (a sequence of steps). Called when the current token immediately follows a separator (/ or //), or an implicit separator (XYZ is equivalent to ./XYZ)

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

parseRemainingPath

protected Expression parseRemainingPath(Expression start)
                                 throws XPathException
Parse the remaining steps of an absolute path expression (one starting in "/" or "//"). Note that the token immediately after the "/" or "//" has already been read, and in the case of "/", it has been confirmed that we have a path expression starting with "/" rather than a standalone "/" expression.

Parameters:
start - the initial implicit expression: root() in the case of "/", root()/descendant-or-self::node in the case of "//"
Returns:
the completed path expression
Throws:
XPathException

parseStepExpression

protected Expression parseStepExpression()
                                  throws XPathException
Parse a step (including an optional sequence of predicates)

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

makeStringLiteral

protected Literal makeStringLiteral(java.lang.String currentTokenValue)
                             throws XPathException
Method to make a string literal from a token identified as a string literal. This is trivial in XPath, but in XQuery the method is overridden to identify pseudo-XML character and entity references. Note that the job of handling doubled string delimiters is done by the tokenizer.

Parameters:
currentTokenValue - the token as read (excluding quotation marks)
Returns:
The string value of the string literal
Throws:
XPathException

parseConstructor

protected Expression parseConstructor()
                               throws XPathException
Parse a node constructor. This is allowed only in XQuery, so the method throws an error for XPath.

Returns:
the expression that results from the parsing
Throws:
XPathException

parseNodeTest

protected NodeTest parseNodeTest(short nodeType)
                          throws XPathException
Parse a NodeTest. One of QName, prefix:*, *:suffix, *, text(), node(), comment(), or processing-instruction(literal?), or element(~,~), attribute(~,~), etc.

Parameters:
nodeType - the node type being sought if one is specified
Returns:
the resulting NodeTest object
Throws:
XPathException - if any error is encountered

parseFunctionCall

protected Expression parseFunctionCall()
                                throws XPathException
Parse a function call. function-name '(' ( Expression (',' Expression )* )? ')'

Returns:
the resulting subexpression
Throws:
XPathException - if any error is encountered

declareRangeVariable

protected void declareRangeVariable(Binding declaration)
                             throws XPathException
Declare a range variable (record its existence within the parser). A range variable is a variable declared within an expression, as distinct from a variable declared in the context.

Parameters:
declaration - the variable declaration to be added to the stack
Throws:
XPathException - if any error is encountered

undeclareRangeVariable

protected void undeclareRangeVariable()
Note when the most recently declared range variable has gone out of scope


getRangeVariableStack

public java.util.Stack getRangeVariableStack()
Get the range variable stack. Used when parsing a nested subexpression inside an attribute constructor

Returns:
the stack used for locally-declared variables

setRangeVariableStack

public void setRangeVariableStack(java.util.Stack stack)
Set the range variable stack. Used when parsing a nested subexpression inside an attribute constructor.

Parameters:
stack - the stack to be used for local variables declared within the expression

makeNameCode

public final int makeNameCode(java.lang.String qname,
                              boolean useDefault)
                       throws XPathException
Make a NameCode, using the static context for namespace resolution

Parameters:
qname - The name as written, in the form "[prefix:]localname"
useDefault - Defines the action when there is no prefix. If true, use the default namespace URI for element names. If false, use no namespace URI (as for attribute names).
Returns:
the namecode, which can be used to identify this name in the name pool
Throws:
XPathException - if the name is invalid, or the prefix undeclared

makeNameCodeSilently

public final int makeNameCodeSilently(java.lang.String qname,
                                      boolean useDefault)
                               throws XPathException,
                                      QNameException
Make a NameCode, using the static context for namespace resolution. This variant of the method does not call "grumble" to report any errors to the ErrorListener, it only reports errors by throwing exceptions. This allows the caller to control the message output.

Parameters:
qname - The name as written, in the form "[prefix:]localname"
useDefault - Defines the action when there is no prefix. If true, use the default namespace URI for element names. If false, use no namespace URI (as for attribute names).
Returns:
the namecode, which can be used to identify this name in the name pool
Throws:
XPathException - if the name is invalid, or the prefix undeclared
QNameException

makeStructuredQName

public final StructuredQName makeStructuredQName(java.lang.String qname,
                                                 boolean useDefault)
                                          throws XPathException
Make a Structured QName, using the static context for namespace resolution

Parameters:
qname - The name as written, in the form "[prefix:]localname"
useDefault - Defines the action when there is no prefix. If true, use the default namespace URI for element names. If false, use no namespace URI (as for attribute names).
Returns:
the namecode, which can be used to identify this name in the name pool
Throws:
XPathException - if the name is invalid, or the prefix undeclared

makeNameTest

public NameTest makeNameTest(short nodeType,
                             java.lang.String qname,
                             boolean useDefault)
                      throws XPathException
Make a NameTest, using the static context for namespace resolution

Parameters:
nodeType - the type of node required (identified by a constant in class Type)
qname - the lexical QName of the required node
useDefault - true if the default namespace should be used when the QName is unprefixed
Returns:
a NameTest, representing a pattern that tests for a node of a given node kind and a given name
Throws:
XPathException - if the QName is invalid

makeNamespaceTest

public NamespaceTest makeNamespaceTest(short nodeType,
                                       java.lang.String prefix)
                                throws XPathException
Make a NamespaceTest (name:*)

Parameters:
nodeType - integer code identifying the type of node required
prefix - the namespace prefix
Returns:
the NamespaceTest, a pattern that matches all nodes in this namespace
Throws:
XPathException - if the namespace prefix is not declared

makeLocalNameTest

public LocalNameTest makeLocalNameTest(short nodeType,
                                       java.lang.String localName)
                                throws XPathException
Make a LocalNameTest (*:name)

Parameters:
nodeType - the kind of node to be matched
localName - the requred local name
Returns:
a LocalNameTest, a pattern which matches all nodes of a given local name, regardless of namespace
Throws:
XPathException - if the local name is invalid

setLocation

protected void setLocation(Expression exp)
Set location information on an expression. At present this consists of a simple line number. Needed mainly for XQuery.

Parameters:
exp - the expression whose location information is to be set

setLocation

protected void setLocation(Expression exp,
                           int offset)
Set location information on an expression. At present only the line number is retained. Needed mainly for XQuery. This version of the method supplies an explicit offset (character position within the expression or query), which the tokenizer can convert to a line number and column number.

Parameters:
exp - the expression whose location information is to be set
offset - the character position within the expression (ignoring newlines)

makeTracer

protected Expression makeTracer(int startOffset,
                                Expression exp,
                                int construct,
                                StructuredQName qName)
If tracing, wrap an expression in a trace instruction

Parameters:
startOffset - the position of the expression in the soruce
exp - the expression to be wrapped
construct - integer constant identifying the kind of construct
qName - the name of the construct (if applicable)
Returns:
the expression that does the tracing

isKeyword

protected boolean isKeyword(java.lang.String s)
Test whether the current token is a given keyword.

Parameters:
s - The string to be compared with the current token
Returns:
true if they are the same

setScanOnly

public void setScanOnly(boolean scanOnly)
Set that we are parsing in "scan only"

Parameters:
scanOnly - true if parsing is to proceed in scan-only mode. In this mode namespace bindings are not yet known, so no attempt is made to look up namespace prefixes.


Copyright (c) Saxonica Limited. All rights reserved.