net.sf.saxon.expr

Class ExpressionParser

public class ExpressionParser extends 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 interfaceExpressionParser.FLWORClause
static classExpressionParser.ForClause
protected static classExpressionParser.TemporaryContainer
Field Summary
protected booleancompileWithTracing
protected ExpressionParser.TemporaryContainerdefaultContainer
protected StaticContextenv
protected intlanguage
protected NameCheckernameChecker
protected Stack<Binding>rangeVariables
protected booleanscanOnly
protected static intSEQUENCE_TYPE
protected Tokenizert
protected static intXPATH
protected static intXQUERY
protected static intXSLT_PATTERN
Constructor Summary
ExpressionParser()
Create an expression parser
Method Summary
protected StringcurrentTokenDisplay()
Display the current token in an error message
protected voiddeclareRangeVariable(Binding declaration)
Declare a range variable (record its existence within the parser).
protected voidexpect(int token)
Expect a given token; fail if the current token is different.
protected BindingfindRangeVariable(StructuredQName qName)
Locate a range variable with a given name.
protected StringgetLanguage()
Get the current language (XPath or XQuery)
Stack<Binding>getRangeVariableStack()
Get the range variable stack.
TokenizergetTokenizer()
Get the tokenizer (the lexical analyzer)
protected voidgrumble(String message)
Report a syntax error (a static error with error code XP0003)
protected voidgrumble(String message, String errorCode)
Report a static error
protected voidgrumble(String message, StructuredQName errorCode)
Report a static error
booleanisCompileWithTracing()
Determine whether trace hooks are included in the compiled code.
protected booleanisKeyword(String s)
Test whether the current token is a given keyword.
protected booleanisNamespaceTestAllowed()
Ask whether the syntax namespace-node() is allowed in a node kind test.
LocalNameTestmakeLocalNameTest(short nodeType, String localName)
Make a LocalNameTest (*:name)
intmakeNameCode(String qname, boolean useDefault)
Make a NameCode, using the static context for namespace resolution
intmakeNameCodeSilently(String qname, boolean useDefault)
Make a NameCode, using the static context for namespace resolution.
NamespaceTestmakeNamespaceTest(short nodeType, String prefix)
Make a NamespaceTest (name:*)
NameTestmakeNameTest(short nodeType, String qname, boolean useDefault)
Make a NameTest, using the static context for namespace resolution
protected LiteralmakeStringLiteral(String currentTokenValue)
Method to make a string literal from a token identified as a string literal.
StructuredQNamemakeStructuredQName(String qname, boolean useDefault)
Make a Structured QName, using the static context for namespace resolution
protected ExpressionmakeTracer(int startOffset, Expression exp, int construct, StructuredQName qName)
If tracing, wrap an expression in a trace instruction
protected voidnextToken()
Read the next token, catching any exception thrown by the tokenizer
Expressionparse(String expression, int start, int terminator, int lineNumber, StaticContext env)
Parse a string representing an expression
protected ExpressionparseConstructor()
Parse a node constructor.
protected ExpressionparseDynamicFunctionCall(Expression functionItem)
Parse a dynamic function call
protected ExpressionparseExpression()
Parse a top-level Expression: ExprSingle ( ',' ExprSingle )*
protected ExpressionparseExprSingle()
Parse an ExprSingle
protected ExpressionparseExtensionExpression()
Parse an Extension Expression This construct is XQuery-only, so the XPath version of this method throws an error unconditionally
protected ExpressionparseForExpression()
Parse a FOR expression: for $x in expr (',' $y in expr)* 'return' expr
protected ExpressionparseFunctionCall()
Parse a function call. function-name '(' ( Expression (',' Expression )* )?
protected ItemTypeparseFunctionItemType()
Get the item type used for function items (XQuery 1.1 higher order functions)
protected ExpressionparseInlineFunction()
Parse an inline function "function" "(" ParamList?
protected ItemTypeparseItemType()
Parse an ItemType within a SequenceType
protected ExpressionparseLiteralFunctionItem()
Parse a literal function item (introduced in XQuery 1.1) Syntax: QName # integer The QName and # have already been read
protected ExpressionparseMappingExpression()
Parse a mapping expression.
protected NodeTestparseNodeTest(short nodeType)
Parse a NodeTest.
protected ItemTypeparseParenthesizedItemType()
Parse a parenthesized item type (allowed in XQuery 1.1 only)
PatternparsePattern(String pattern, StaticContext env)
Parse a string representing an XSLT pattern
protected ExpressionparseRelativePath()
Parse a relative path (a sequence of steps).
protected ExpressionparseRemainingPath(Expression start)
Parse the remaining steps of an absolute path expression (one starting in "/" or "//").
SequenceTypeparseSequenceType(String input, StaticContext env)
Parse a string representing a sequence type
protected SequenceTypeparseSequenceType()
Parse the sequence type production.
protected ExpressionparseStepExpression()
Parse a step (including an optional sequence of predicates)
protected ExpressionparseTryCatchExpression()
Parse a try/catch Expression This construct is XQuery-1.1 only, so the XPath version of this method throws an error unconditionally
protected ExpressionparseTypeswitchExpression()
Parse a Typeswitch Expression.
protected ExpressionparseValidateExpression()
Parse a Validate Expression.
voidsetCompileWithTracing(boolean trueOrFalse)
Set whether trace hooks are to be included in the compiled code.
protected voidsetLocation(Expression exp)
Set location information on an expression.
protected voidsetLocation(Expression exp, int offset)
Set location information on an expression.
voidsetRangeVariableStack(Stack<Binding> stack)
Set the range variable stack.
voidsetScanOnly(boolean scanOnly)
Set that we are parsing in "scan only"
protected voidundeclareRangeVariable()
Note when the most recently declared range variable has gone out of scope
protected voidwarning(String message)
Output a warning message

Field Detail

compileWithTracing

protected boolean compileWithTracing

defaultContainer

protected ExpressionParser.TemporaryContainer defaultContainer

env

protected StaticContext env

language

protected int language

nameChecker

protected NameChecker nameChecker

rangeVariables

protected Stack<Binding> rangeVariables

scanOnly

protected boolean scanOnly

SEQUENCE_TYPE

protected static final int SEQUENCE_TYPE

t

protected Tokenizer t

XPATH

protected static final int XPATH

XQUERY

protected static final int XQUERY

XSLT_PATTERN

protected static final int XSLT_PATTERN

Constructor Detail

ExpressionParser

public ExpressionParser()
Create an expression parser

Method Detail

currentTokenDisplay

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

Returns: the display representation of the token

declareRangeVariable

protected void declareRangeVariable(Binding declaration)
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

expect

protected void expect(int token)
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

findRangeVariable

protected Binding findRangeVariable(StructuredQName qName)
Locate a range variable with a given name. (By "range variable", we mean a variable declared within the expression where it is used.)

Parameters: qName identifies the name of the range variable

Returns: null if not found (this means the variable is probably a context variable); otherwise the relevant RangeVariable

getLanguage

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

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

getRangeVariableStack

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

Returns: the stack used for locally-declared variables

getTokenizer

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

Returns: the tokenizer (the lexical analyzer)

grumble

protected void grumble(String message)
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(String message, String errorCode)
Report a static error

Parameters: message the error message

Throws: XPathException always thrown: an exception containing the supplied message

grumble

protected void grumble(String message, StructuredQName errorCode)
Report a static error

Parameters: message the error message errorCode the error code

Throws: XPathException always thrown: an exception containing the supplied message

isCompileWithTracing

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

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

isKeyword

protected boolean isKeyword(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

isNamespaceTestAllowed

protected boolean isNamespaceTestAllowed()
Ask whether the syntax namespace-node() is allowed in a node kind test.

Returns: false (currently allowed only in XQuery 1.1)

makeLocalNameTest

public LocalNameTest makeLocalNameTest(short nodeType, String localName)
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

makeNameCode

public final int makeNameCode(String qname, boolean useDefault)
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(String qname, boolean useDefault)
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

makeNamespaceTest

public NamespaceTest makeNamespaceTest(short nodeType, String prefix)
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

makeNameTest

public NameTest makeNameTest(short nodeType, String qname, boolean useDefault)
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

makeStringLiteral

protected Literal makeStringLiteral(String currentTokenValue)
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

makeStructuredQName

public final StructuredQName makeStructuredQName(String qname, boolean useDefault)
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

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

nextToken

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

parse

public Expression parse(String expression, int start, int terminator, int lineNumber, StaticContext env)
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

parseConstructor

protected Expression parseConstructor()
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

parseDynamicFunctionCall

protected Expression parseDynamicFunctionCall(Expression functionItem)
Parse a dynamic function call

Returns: the expression that results from the parsing

parseExpression

protected Expression parseExpression()
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()
Parse an ExprSingle

Returns: the resulting subexpression

Throws: XPathException if any error is encountered

parseExtensionExpression

protected Expression parseExtensionExpression()
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

parseForExpression

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

Returns: the resulting subexpression

Throws: XPathException if any error is encountered

parseFunctionCall

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

Returns: the resulting subexpression

Throws: XPathException if any error is encountered

parseFunctionItemType

protected ItemType parseFunctionItemType()
Get the item type used for function items (XQuery 1.1 higher order functions)

parseInlineFunction

protected Expression parseInlineFunction()
Parse an inline function "function" "(" ParamList? ")" ("as" SequenceType)? EnclosedExpr On entry, "function (" has already been read

Throws: XPathException if a syntax error is found

parseItemType

protected ItemType parseItemType()
Parse an ItemType within a SequenceType

parseLiteralFunctionItem

protected Expression parseLiteralFunctionItem()
Parse a literal function item (introduced in XQuery 1.1) Syntax: QName # integer The QName and # have already been read

Returns: an ExternalObject representing the function item

parseMappingExpression

protected Expression parseMappingExpression()
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

parseNodeTest

protected NodeTest parseNodeTest(short nodeType)
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

parseParenthesizedItemType

protected ItemType parseParenthesizedItemType()
Parse a parenthesized item type (allowed in XQuery 1.1 only)

parsePattern

public Pattern parsePattern(String pattern, StaticContext env)
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

parseRelativePath

protected Expression parseRelativePath()
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)
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

parseSequenceType

public SequenceType parseSequenceType(String input, StaticContext env)
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

parseSequenceType

protected SequenceType parseSequenceType()
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

parseStepExpression

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

Returns: the resulting subexpression

Throws: XPathException if any error is encountered

parseTryCatchExpression

protected Expression parseTryCatchExpression()
Parse a try/catch Expression This construct is XQuery-1.1 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

parseTypeswitchExpression

protected Expression parseTypeswitchExpression()
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

parseValidateExpression

protected Expression parseValidateExpression()
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

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

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)

setRangeVariableStack

public void setRangeVariableStack(Stack<Binding> 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

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.

undeclareRangeVariable

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

warning

protected void warning(String message)
Output a warning message

Parameters: message the text of the message