Package net.sf.saxon.expr
Class ExpressionParser
- java.lang.Object
-
- net.sf.saxon.expr.ExpressionParser
-
- Direct Known Subclasses:
QueryParser
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
Nested Classes Modifier and Type Class Description static class
ExpressionParser.ForClause
protected static class
ExpressionParser.TemporaryContainer
-
Field Summary
Fields Modifier and Type Field Description 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
Constructors Constructor Description ExpressionParser()
Create an expression parser
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected java.lang.String
currentTokenDisplay()
Display the current token in an error messageprotected 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 errorboolean
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 resolutionint
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 resolutionprotected 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 resolutionprotected Expression
makeTracer(int startOffset, Expression exp, int construct, StructuredQName qName)
If tracing, wrap an expression in a trace instructionprotected void
nextToken()
Read the next token, catching any exception thrown by the tokenizerExpression
parse(java.lang.String expression, int start, int terminator, int lineNumber, StaticContext env)
Parse a string representing an expressionprotected Expression
parseConstructor()
Parse a node constructor.protected Expression
parseExpression()
Parse a top-level Expression: ExprSingle ( ',' ExprSingle )*protected Expression
parseExprSingle()
Parse an ExprSingleprotected Expression
parseExtensionExpression()
Parse an Extension Expression This construct is XQuery-only, so the XPath version of this method throws an error unconditionallyprotected Expression
parseForExpression()
Parse a FOR expression: for $x in expr (',' $y in expr)* 'return' exprprotected 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 patternprotected 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 typeprotected 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 scopeprotected void
warning(java.lang.String message)
Output a warning message
-
-
-
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
-
-
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 messageerrorCode
- 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 Stringstart
- offset within the string where parsing is to startterminator
- character to treat as terminating the expressionlineNumber
- location of the start of the expression, for diagnosticsenv
- 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 Stringenv
- 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 productionenv
- 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) exprOn 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 undeclaredQNameException
-
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 nodeuseDefault
- 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 requiredprefix
- 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 matchedlocalName
- 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 setoffset
- 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 soruceexp
- the expression to be wrappedconstruct
- integer constant identifying the kind of constructqName
- 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.
-
-