Class XPathParser

java.lang.Object
net.sf.saxon.expr.parser.XPathParser
Direct Known Subclasses:
PatternParser, SelectionParser, XQueryParser

public class XPathParser 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)

The base class handles parsing of XPath 2.0, XPath 3.0 and XPath 3.1 syntax (switched by a languageVersion variable). Subclasses refine this to handle XQuery syntax (1.0, 3.0 and 3.1) and XQuery Update syntax.

  • Field Details

    • t

      protected Tokenizer t
    • env

      protected StaticContext env
    • rangeVariables

      protected IndexedStack<LocalBinding> rangeVariables
    • inlineFunctionStack

      public IndexedStack<XPathParser.InlineFunctionDetails> inlineFunctionStack
    • qNameParser

      protected QNameParser qNameParser
    • parserExtension

      protected ParserExtension parserExtension
    • charChecker

      protected IntPredicateProxy charChecker
    • allowXPath30Syntax

      protected boolean allowXPath30Syntax
    • allowXPath30XSLTExtensions

      protected boolean allowXPath30XSLTExtensions
    • allowXPath31Syntax

      protected boolean allowXPath31Syntax
    • allowXPath40Syntax

      protected boolean allowXPath40Syntax
    • allowSaxonExtensions

      protected boolean allowSaxonExtensions
    • scanOnly

      protected boolean scanOnly
    • codeInjector

      protected CodeInjector codeInjector
    • language

      protected XPathParser.ParsedLanguage language
    • languageVersion

      protected int languageVersion
    • catchDepth

      protected int catchDepth
  • Constructor Details

    • XPathParser

      public XPathParser(StaticContext env)
      Create an expression parser
  • Method Details

    • setCodeInjector

      public void setCodeInjector(CodeInjector injector)
      Set a CodeInjector which can be used to modify or wrap expressions on the tree as the expression is parsed and the tree is constructed. This is typically used to add tracing code.
      Parameters:
      injector - the code injector to be used
    • getCodeInjector

      public CodeInjector getCodeInjector()
      Set a CodeInjector which can be used to modify or wrap expressions on the tree as the expression is parsed and the tree is constructed. This is typically used to add tracing code.
      Returns:
      the code injector in use, if any; or null otherwise
    • setAccelerator

      public void setAccelerator(XPathParser.Accelerator accelerator)
      Set an accelerator which can be used for fast parsing of special cases
      Parameters:
      accelerator - a parsing accelerator
    • getTokenizer

      public Tokenizer getTokenizer()
      Get the tokenizer (the lexical analyzer)
      Returns:
      the tokenizer (the lexical analyzer)
    • getStaticContext

      public StaticContext getStaticContext()
      Get the static context used by this expression parser
      Returns:
      the static context
    • setParserExtension

      public void setParserExtension(ParserExtension extension)
      Set a parser extension which can handle extensions to the XPath syntax, e.g. for XQuery update extensions
      Parameters:
      extension - a parser extension
    • setCatchDepth

      public void setCatchDepth(int depth)
      Set the depth of nesting within try/catch
      Parameters:
      depth - the depth of nesting
    • nextToken

      public void nextToken() throws XPathException
      Read the next token, catching any exception thrown by the tokenizer
      Throws:
      XPathException - if an invalid token is found
    • expect

      public 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

      public void grumble(String message) throws XPathException
      Report a syntax error (a static error with error code XPST0003)
      Parameters:
      message - the error message
      Throws:
      XPathException - always thrown: an exception containing the supplied message
    • grumble

      public void grumble(String message, 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
    • grumble

      public void grumble(String message, String errorCode, int offset) throws XPathException
      Report a static error, with location information
      Parameters:
      message - the error message
      errorCode - the error code
      offset - the coded location of the error, or -1 if the location of the current token should be used
      Throws:
      XPathException - always thrown: an exception containing the supplied message
    • grumble

      protected void grumble(String message, StructuredQName errorCode, int offset) throws XPathException
      Report a static error
      Parameters:
      message - the error message
      errorCode - the error code
      offset - the coded location of the error, or -1 if the location of the current token should be used
      Throws:
      XPathException - always thrown: an exception containing the supplied message
    • grumble

      protected void grumble(String message, StructuredQName errorCode) throws XPathException
      Throws:
      XPathException
    • warning

      protected void warning(String message, String errorCode)
      Output a warning message
      Parameters:
      message - the text of the message
      errorCode - the error code associated with the warning
    • setLanguage

      protected void setLanguage(XPathParser.ParsedLanguage language, int version)
      Set the current language (XPath or XQuery, XSLT Pattern, or SequenceType)
      Parameters:
      language - one of the constants XPathParser.ParsedLanguage.XPATH, XPathParser.ParsedLanguage.XQUERY, XPathParser.ParsedLanguage.XSLT_PATTERN, XPathParser.ParsedLanguage.SEQUENCE_TYPE etc
      version - The XPath or XQuery language version. For XQuery the value must be 10 (for "1.0"), 30 (for "3.0") or 31 (for "3.1"); for XPath it must be 20 (="2.0"), 30 (="3.0") or 31 (="3.1"). The value 305 is also recognized to mean XPath 3.0 plus the extensions defined in XSLT 3.0
    • 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
    • isAllowXPath31Syntax

      public boolean isAllowXPath31Syntax()
      Ask if XPath 3.1 is in use
      Returns:
      true if XPath 3.1 syntax (and therefore XQuery 3.1 syntax) is permitted
    • setQNameParser

      public void setQNameParser(QNameParser qp)
      Set the QNameParser to be used while parsing
      Parameters:
      qp - the QNameParser
    • getQNameParser

      public QNameParser getQNameParser()
      Get the QNameParser to be used while parsing
      Returns:
      the QNameParser
    • currentTokenDisplay

      protected String currentTokenDisplay()
      Display the current token in an error message
      Returns:
      the display representation of the token
    • parse

      public Expression parse(String expression, int start, int terminator, StaticContext env) throws XPathException
      Parse a string representing an expression. This will accept an XPath expression if called on an ExpressionParser, or an XQuery expression if called on a QueryParser.
      Parameters:
      expression - the expression expressed as a String
      start - offset within the string where parsing is to start
      terminator - token to treat as terminating the expression
      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
    • customizeTokenizer

      protected void customizeTokenizer(Tokenizer t)
      Callback to tailor the tokenizer
      Parameters:
      t - the Tokenizer to be customized
    • parseSequenceType

      public SequenceType parseSequenceType(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
    • parseExtendedItemType

      public ItemType parseExtendedItemType(String input, StaticContext env) throws XPathException
      Parse a string representing an extended item type: specifically, the content of itemType or nodeTest attributes in an exported package. As well as regular itemType syntax, these allow combined node tests separated with "|", "except", or "intersect" operators. Expressions using these operators will always be parenthesized.
      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
    • parseExtendedSequenceType

      public SequenceType parseExtendedSequenceType(String input, StaticContext env) throws XPathException
      Parse a string representing a sequence type with syntax extensions used in exported stylesheets. Also allows the extensions permitted in saxon:as, e.g. tuple types, type aliases
      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

      public 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

      public Expression parseExprSingle() throws XPathException
      Parse an ExprSingle
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • parseBinaryExpression

      public Expression parseBinaryExpression(Expression lhs, int minPrecedence) throws XPathException
      Parse a binary expression, using operator precedence parsing. This is used to parse the part of the grammar consisting largely of binary operators distinguished by precedence: from "or expressions" down to "unary expressions". Algorithm for the mainstream binary operators is from Wikipedia article on precedence parsing; operator precedences are from the XQuery specification appendix B.
      Parameters:
      lhs - Left-hand side "basic expression"
      minPrecedence - the minimum precedence of an operator that is to be treated as not terminating the current expression
      Returns:
      the parsed expression
      Throws:
      XPathException - if a static error is found
    • operatorPrecedence

      public static int operatorPrecedence(int operator)
      Get the precedence associated with a given operator
      Parameters:
      operator - the operator in question
      Returns:
      a higher number for higher precedence (closer binding)
    • 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 - if a static error is found
    • parseSwitchExpression

      protected Expression parseSwitchExpression() throws XPathException
      Parse a Switch Expression. This construct is XQuery-only. SwitchExpr ::= "switch" "(" Expr ")" SwitchCaseClause+ "default" "return" ExprSingle SwitchCaseClause ::= ("case" ExprSingle)+ "return" ExprSingle
      Returns:
      the parsed expression
      Throws:
      XPathException - in the event of a syntax error
    • 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 - if a static error is found
    • 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 - if a static error is found
    • parseTryCatchExpression

      protected Expression parseTryCatchExpression() throws XPathException
      Parse a try/catch Expression This construct is XQuery-3.0 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 - if a static error is found
    • parseFLWORExpression

      protected Expression parseFLWORExpression() throws XPathException
      Parse a FOR or LET expression: for 'member'? $x in expr (',' 'member'? $y in expr)* 'return' expr let $x := expr (', $y := expr)* 'return' expr This version of the method handles the subset of the FLWOR syntax allowed in XPath
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • getPlainType

      public ItemType getPlainType(StructuredQName sq) throws XPathException
      Throws:
      XPathException
    • whyDisallowedType

      public static String whyDisallowedType(PackageData pack, BuiltInAtomicType type)
      Determine whether a given built-in type is disallowed in a given environment, and in the case where it is disallowed, return a string explaining why
      Parameters:
      pack - the containing package
      type - the built-in type to be tested
      Returns:
      null if the type is OK to be used; or a string explaining why not.
    • parseSequenceType

      public 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
    • parseOccurrenceIndicator

      public int parseOccurrenceIndicator() throws XPathException
      Throws:
      XPathException
    • parseItemType

      public ItemType parseItemType() throws XPathException
      Parse an ItemType within a SequenceType
      Returns:
      the ItemType after parsing
      Throws:
      XPathException - if a static error is found
    • parseUnionType

      public ItemType parseUnionType() throws XPathException
      Parse a union type (Saxon 9.8 extension). Syntax: "union" "(" qname ("," qname)* ")"
      Returns:
      the item type
      Throws:
      XPathException - if a syntax error is found
    • parseEnumType

      public EnumerationType parseEnumType() throws XPathException
      Parse an enum type (XPath 4.0 proposal). Syntax: "enum" "(" StringLiteral ("," StringLiteral)* ")"
      Returns:
      the item type
      Throws:
      XPathException - if a syntax error is found
    • parseFunctionItemType

      protected ItemType parseFunctionItemType(AnnotationList annotations) throws XPathException
      Parse the item type used for function items (for higher order functions) Syntax (changed by WG decision on 2009-09-22): function '(' '*' ') | function '(' (SeqType (',' SeqType)*)? ')' 'as' SeqType The "function(" has already been read
      Parameters:
      annotations - the list of annotation assertions for this function item type
      Returns:
      the ItemType after parsing
      Throws:
      XPathException - if a static error is found
    • parseMapItemType

      protected ItemType parseMapItemType() throws XPathException
      Parse the item type used for maps (XSLT extension to XPath 3.0) Syntax: map '(' '*' ') | map '(' ItemType ',' SeqType ')' 'as' SeqType The "map(" has already been read
      Returns:
      the item type of the map
      Throws:
      XPathException - if a parsing error occurs or if the map syntax is not available
    • parseArrayItemType

      protected ItemType parseArrayItemType() throws XPathException
      Get the item type used for array items (XPath 3.1) Syntax: array '(' '*' ') | array '(' SeqType ')' The "array(" has already been read
      Returns:
      the item type of the array
      Throws:
      XPathException - if a parsing error occurs or if the array syntax is not available
    • atStartOfRelativePath

      protected boolean atStartOfRelativePath()
      Test whether the current token is one that can start a RelativePathExpression
      Returns:
      the resulting subexpression
    • disallowedAtStartOfRelativePath

      protected boolean disallowedAtStartOfRelativePath()
      Test whether the current token is one that is disallowed after a "leading lone slash". These composite tokens have been parsed as operators, but are not allowed after "/" under the rules of erratum E24
      Returns:
      the resulting subexpression
    • parsePathExpression

      protected Expression parsePathExpression() throws XPathException
      Parse a PathExpresssion. This includes "true" path expressions such as A/B/C, and also constructs that may start a path expression such as a variable reference $name or a parenthesed expression (A|B). Numeric and string literals also come under this heading.
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • parseSimpleMappingExpression

      protected Expression parseSimpleMappingExpression() throws XPathException
      Parse an XPath 3.0 simple mapping expression ("!" operator)
      Returns:
      the parsed expression
      Throws:
      XPathException - in the event of a syntax error
    • 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 - if a static error is found
    • parseStepExpression

      protected Expression parseStepExpression(boolean firstInPattern) throws XPathException
      Parse a step (including an optional sequence of predicates)
      Parameters:
      firstInPattern - true only if we are parsing the first step in a RelativePathPattern in the XSLT Pattern syntax
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • parsePredicate

      protected Expression parsePredicate(Expression step) throws XPathException
      Throws:
      XPathException
    • parseArrowPostfix

      protected Expression parseArrowPostfix(Expression lhs) throws XPathException
      Parse an XPath 3.1 arrow operator ("=>")
      Parameters:
      lhs - the expression on the left of the arrow operator
      Returns:
      the expression that results from the parsing
      Throws:
      XPathException - if the syntax is wrong
    • parseMappingArrowPostfix

      protected Expression parseMappingArrowPostfix(Expression lhs) throws XPathException
      Parse an XPath 4.0 mapping arrow operator ("=!>")
      Parameters:
      lhs - the expression on the left of the arrow operator
      Returns:
      the expression that results from the parsing
      Throws:
      XPathException - if the syntax is wrong
    • parsePredicate

      protected Expression parsePredicate() throws XPathException
      Parse the expression within a predicate. A separate method so it can be overridden
      Returns:
      the expression within the predicate
      Throws:
      XPathException - if a static error is found
    • isReservedInQuery

      protected boolean isReservedInQuery(NamespaceUri uri)
    • parseBasicStep

      protected Expression parseBasicStep(boolean firstInPattern) throws XPathException
      Parse a basic step expression (without the predicates)
      Parameters:
      firstInPattern - true only if we are parsing the first step in a RelativePathPattern in the XSLT Pattern syntax
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • parseParenthesizedExpression

      public Expression parseParenthesizedExpression() throws XPathException
      Throws:
      XPathException
    • parseLambdaParams

      public List<StructuredQName> parseLambdaParams() throws XPathException
      Attempt to parse the parameter list of a lambda expression. No errors are thrown, except for unresolvable QNames. If the grammar isn't matched, return null, so the caller can backtrack.
      Returns:
      either a list of parameter names, or null.
      Throws:
      XPathException - only for low-level errors like failure to tokenize, or failure to resolve a QName.
    • testPermittedAxis

      protected void testPermittedAxis(int axis, String errorCode) throws XPathException
      Throws:
      XPathException
    • parseNumericLiteral

      public Expression parseNumericLiteral(boolean traceable) throws XPathException
      Throws:
      XPathException
    • parseHexLiteral

      public Expression parseHexLiteral(boolean traceable) throws XPathException
      Throws:
      XPathException
    • parseBinaryLiteral

      public Expression parseBinaryLiteral(boolean traceable) throws XPathException
      Throws:
      XPathException
    • parseStringLiteral

      protected Expression parseStringLiteral(boolean traceable) throws XPathException
      Throws:
      XPathException
    • parseBackTickedStringLiteral

      protected Expression parseBackTickedStringLiteral() throws XPathException
      Throws:
      XPathException
    • parseStringConstructor

      protected Expression parseStringConstructor() throws XPathException
      Throws:
      XPathException
    • parseStringTemplate

      public Expression parseStringTemplate() throws XPathException
      Throws:
      XPathException
    • parseVariableName

      public StructuredQName parseVariableName() throws XPathException
      Throws:
      XPathException
    • resolveVariableReference

      public Expression resolveVariableReference(int offset, StructuredQName vtest) throws XPathException
      Throws:
      XPathException
    • makeStringLiteral

      protected Literal makeStringLiteral(String currentTokenValue, boolean unescape) 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)
      unescape - true if (in XQuery only) entity and character references are to be unescaped
      Returns:
      The string value of the string literal
      Throws:
      XPathException - if a static error is found
    • unescape

      protected String unescape(String token) throws XPathException
      Unescape character references and built-in entity references in a string. Does nothing in XPath, because XPath does not recognize entity references in string literals
      Parameters:
      token - the input string, which may include XML-style character references or built-in entity references
      Returns:
      the string with character references and built-in entity references replaced by their expansion
      Throws:
      XPathException - if a malformed character or entity reference is found
    • 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 - if a static error occurs
    • parseDynamicFunctionCall

      public Expression parseDynamicFunctionCall(Expression functionItem, Expression prefixArgument) throws XPathException
      Parse a dynamic function call
      Parameters:
      functionItem - the expression that determines the function to be called
      prefixArgument - the LHS of an arrow operator, or null if this is not part of an arrow expression
      Returns:
      the expression that results from the parsing
      Throws:
      XPathException - if a static error is found
    • generateApplyCall

      protected Expression generateApplyCall(Expression functionItem, ArrayList<Expression> args)
    • parseLookup

      protected Expression parseLookup(Expression lhs) throws XPathException
      Parse a lookup operator ("?")
      Parameters:
      lhs - the expression that the function to be called
      Returns:
      the expression that results from the parsing
      Throws:
      XPathException - if a static error is found
    • 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
    • parseUnionNodeTest

      protected NodeTest parseUnionNodeTest(short nodeType) throws XPathException
      Throws:
      XPathException
    • parseNameTestUnion

      public List<NodeTest> parseNameTestUnion(int nodeKind) throws XPathException
      Throws:
      XPathException
    • isNamespaceTestAllowed

      protected boolean isNamespaceTestAllowed()
      Ask whether the syntax namespace-node() is allowed in a node kind test.
      Returns:
      true unless XPath 2.0 / XQuery 1.0 syntax is required
    • checkLanguageVersion30

      protected void checkLanguageVersion30() throws XPathException
      Check that XPath 3.0 is in use
      Throws:
      XPathException - if XPath 3.0 support was not requested
    • checkLanguageVersion31

      protected void checkLanguageVersion31() throws XPathException
      Check that XPath 3.1 is in use
      Throws:
      XPathException - if XPath 3.1 support was not requested
    • checkLanguageVersion40

      protected void checkLanguageVersion40() throws XPathException
      Check that XPath/XQuery 4.0 is in use
      Throws:
      XPathException - if XPath 3.1 support was not requested
    • checkMapExtensions

      protected void checkMapExtensions() throws XPathException
      Check that the map syntax is enabled: this covers the extensions to XPath 3.0 syntax defined in XSLT 3.0 (and also, of course, in XPath 3.1)
      Throws:
      XPathException - if XPath 3.1 support was not requested
    • checkSyntaxExtensions

      public void checkSyntaxExtensions(String construct) throws XPathException
      Check that Saxon syntax extensions are permitted
      Parameters:
      construct - name of the construct, for use in error messages
      Throws:
      XPathException - if Saxon syntax extensions have not been enabled
    • parseMapExpression

      protected Expression parseMapExpression() throws XPathException
      Parse a map expression. Requires XPath/XQuery 3.0 Provisional syntax map { expr : expr (, expr : expr )*} }
      Returns:
      the map expression
      Throws:
      XPathException - if parsing fails
    • parseArraySquareConstructor

      protected Expression parseArraySquareConstructor() throws XPathException
      Parse a "square" array constructor "[" (exprSingle ("," exprSingle)* )? "]" Applies to XPath/XQuery 3.1 only
      Returns:
      the parsed expression
      Throws:
      XPathException - if the syntax is wrong
    • parseArrayCurlyConstructor

      protected Expression parseArrayCurlyConstructor() throws XPathException
      Parse a "curly" array constructor array "{" expr "}" Applies to XPath/XQuery 3.1 only
      Returns:
      the parsed expression
      Throws:
      XPathException - if the syntax is invalid or the construct is not permitted
    • parseFunctionCall

      public Expression parseFunctionCall(Expression prefixArgument) throws XPathException
      Parse a function call. function-name '(' ( Expression (',' Expression )* )? ')'
      Parameters:
      prefixArgument - left hand operand of arrow operator, or null in the case of a conventional function call
      Returns:
      the resulting subexpression
      Throws:
      XPathException - if any error is encountered
    • makeCurriedFunction

      public Expression makeCurriedFunction(XPathParser parser, int offset, StructuredQName name, Expression[] args, IntSet placeMarkers) throws XPathException
      Process a function call in which one or more of the argument positions are represented as "?" placemarkers (indicating partial application or currying)
      Parameters:
      parser - the XPath parser
      offset - offset in the query source of the start of the expression
      name - the function call (as if there were no currying)
      args - the arguments (with EmptySequence in the placemarker positions)
      placeMarkers - the positions of the placemarkers @return the curried function
      Returns:
      the curried function
      Throws:
      XPathException - if a dynamic error occurs
    • curryFunction

      public static Expression curryFunction(Expression functionExp, Expression[] args, IntSet placeMarkers)
      Process a function expression in which one or more of the argument positions are represented as "?" placemarkers (indicating partial application or currying)
      Parameters:
      functionExp - an expression that returns the function to be curried
      args - the arguments (with EmptySequence in the placemarker positions)
      placeMarkers - the positions of the placemarkers
      Returns:
      the curried function
    • createDynamicCurriedFunction

      public Expression createDynamicCurriedFunction(XPathParser p, Expression functionItem, ArrayList<Expression> args, IntSet placeMarkers)
    • handleExternalFunctionDeclaration

      public void handleExternalFunctionDeclaration(XQueryParser p, XQueryFunction func) throws XPathException
      Throws:
      XPathException
    • reportMissingFunction

      public Expression reportMissingFunction(int offset, StructuredQName functionName, Expression[] arguments, List<String> reasons) throws XPathException
      Throws:
      XPathException
    • getMissingFunctionExplanation

      public static String getMissingFunctionExplanation(StructuredQName functionName, Configuration config)
      Get a message containing suggestions as to why a requested function might not be available
      Parameters:
      functionName - the name of the required function
      config - the Saxon configuration
      Returns:
      a suggestion as to why the function was not found; or null if no suggestions can be offered.
    • resolveFunctionName

      protected StructuredQName resolveFunctionName(String fname) throws XPathException
      Interpret a function name, returning it as a resolved QName
      Parameters:
      fname - the lexical QName used as the function name; or an EQName presented by the tokenizer as a name in Clark notation
      Returns:
      the Structured QName obtained by resolving any prefix in the function name
      Throws:
      XPathException - if the supplied name is not a valid QName or if its prefix is not in scope
    • parseFunctionArgument

      public Expression parseFunctionArgument() throws XPathException
      Parse an argument to a function call. Separate method so it can be overridden. With higher-order-function syntax in XPath 3.0/XQuery 3.0, this returns null if the pseudo-argument "?" is found.
      Returns:
      the Expression used as the argument, or null if the argument is the place-holder "?"
      Throws:
      XPathException - if the argument expression does not parse correctly
    • parseNamedFunctionReference

      protected Expression parseNamedFunctionReference() throws XPathException
      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
      Throws:
      XPathException - if a static error is encountered
    • parseAnnotationsList

      protected AnnotationList parseAnnotationsList() throws XPathException
      Parse the annotations that can appear in a variable or function declaration
      Returns:
      the annotations as a list
      Throws:
      XPathException - in the event of a syntax error
    • parseInlineFunction

      protected Expression parseInlineFunction(AnnotationList annotations) throws XPathException
      Throws:
      XPathException
    • parseInlineFunctionBody

      protected Expression parseInlineFunctionBody(AnnotationList annotations, List<UserFunctionParameter> params, SequenceType resultType) throws XPathException
      Throws:
      XPathException
    • makeInlineFunctionValue

      public static Expression makeInlineFunctionValue(XPathParser p, AnnotationList annotations, XPathParser.InlineFunctionDetails details, List<UserFunctionParameter> params, SequenceType resultType, Expression body)
    • findOuterRangeVariable

      public LocalBinding findOuterRangeVariable(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
    • findOuterRangeVariable

      public static LocalBinding findOuterRangeVariable(StructuredQName qName, IndexedStack<XPathParser.InlineFunctionDetails> inlineFunctionStack, StaticContext env)
      When a variable reference occurs within an inline function, it might be a reference to a variable declared outside the inline function (which needs to become part of the closure). This code looks for such an outer variable
      Parameters:
      qName - the name of the variable
      inlineFunctionStack - the stack of inline functions that we are within
      env - the static context
      Returns:
      a binding for the variable; this will typically be a binding to a newly added parameter for the innermost function in which the variable reference appears. As a side effect, all the inline functions between the declaration of the variable and its use will have this variable as an additional parameter, each one bound to the corresponding parameter in the containing function.
    • parseFocusFunction

      public Expression parseFocusFunction(AnnotationList annotations) throws XPathException
      Throws:
      XPathException
    • isReservedFunctionName

      public static boolean isReservedFunctionName(String name, int version)
      Check whether a function name is reserved in XPath 3.1 or 4.0 (when unprefixed)
      Parameters:
      name - the function name (the local-name as a string)
      version - set to 31 for XPath 3.1, 40 for XPath 4.0
      Returns:
      true if the function name is reserved
    • getRangeVariables

      public IndexedStack<LocalBinding> getRangeVariables()
      Get the stack of in-scope range variables
      Returns:
      the stack of variables
    • setRangeVariables

      public void setRangeVariables(IndexedStack<LocalBinding> variables)
      Set a new stack of in-scope range variables
      Parameters:
      variables - the stack of variables
    • declareRangeVariable

      public void declareRangeVariable(LocalBinding 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
    • undeclareRangeVariable

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

      protected LocalBinding 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
    • setRangeVariableStack

      public void setRangeVariableStack(IndexedStack<LocalBinding> 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
    • makeFingerprint

      public final int makeFingerprint(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"; alternatively, a QName in Clark notation ({uri}local)
      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 fingerprint, which can be used to identify this name in the name pool
      Throws:
      XPathException - if the name is invalid, or the prefix undeclared
    • makeStructuredQNameSilently

      public final StructuredQName makeStructuredQNameSilently(String qname, NamespaceUri defaultUri) throws XPathException
      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"
      defaultUri - Defines the URI to be returned if there is no prefix.
      Returns:
      the structured QName
      Throws:
      XPathException - if the name is invalid, or the prefix undeclared or if the name is not a lexically valid QName
    • makeStructuredQName

      public final StructuredQName makeStructuredQName(String qname, NamespaceUri defaultUri) throws XPathException
      Make a Structured QName, using the static context for namespace resolution
      Parameters:
      qname - The name as written, in the form "[prefix:]localname"; alternatively, a QName in Clark format ({uri}local)
      defaultUri - The URI to be used if the name is written as a localname with no prefix
      Returns:
      the QName as an instance of StructuredQName
      Throws:
      XPathException - if the name is invalid, or the prefix undeclared
    • makeNodeName

      public final NodeName makeNodeName(String qname, boolean useDefault) throws XPathException
      Make a FingerprintedQName, using the static context for namespace resolution
      Parameters:
      qname - The name as written, in the form "[prefix:]localname"; alternatively, a QName in Clark format ({uri}local)
      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 fingerprinted QName
      Throws:
      XPathException - if the name is invalid, or the prefix undeclared
    • makeNameTest

      public NodeTest makeNameTest(int nodeKind, String qname, boolean useDefault) throws XPathException
      Make a NameTest, using the static context for namespace resolution
      Parameters:
      nodeKind - the type of node required (identified by a constant in class Type)
      qname - the lexical QName of the required node; alternatively, a QName in Clark notation ({uri}local)
      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
    • makeQNameTest

      public QNameTest makeQNameTest(int nodeKind, String qname) throws XPathException
      Throws:
      XPathException
    • makeNamespaceTest

      public NamespaceTest makeNamespaceTest(int nodeKind, String prefix) throws XPathException
      Make a NamespaceTest (name:*)
      Parameters:
      nodeKind - integer code identifying the type of node required
      prefix - either the namespace prefix, or a string in the form Q{uri}* (including the final '*').
      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(int nodeKind, String localName) throws XPathException
      Make a LocalNameTest (*:name)
      Parameters:
      nodeKind - 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

      public 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)
    • makeLocation

      public Location makeLocation(int offset)
      Make a location object corresponding to a specified offset in the query
      Parameters:
      offset - the offset (character position) in the query
      Returns:
      an object containing location information
    • setLocation

      public void setLocation(Clause clause, int offset)
      Set location information on a clause of a FLWOR expression. 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:
      clause - the clause whose location information is to be set
      offset - the character position within the expression (ignoring newlines)
    • makeLocation

      public Location makeLocation()
    • makeNestedLocation

      public Location makeNestedLocation(Location containingLoc, int line, int column, String nearbyText)
      Make a Location object relative to an existing location
      Parameters:
      containingLoc - the containing location
      line - the line number relative to the containing location (zero-based)
      column - the column number relative to the containing location (zero-based)
      nearbyText - (maybe null) expression text around the point of the error
      Returns:
      a suitable Location object
    • makeTracer

      public Expression makeTracer(Expression exp, StructuredQName qName)
      If tracing, wrap an expression in a trace instruction

      NB, this no longer happens. Instead of creating trace expressions in the course of parsing and buildint the expression tree, trace code is now injected into the tree after the event, when parsing is complete. See ExpressionTool.injectCode(Expression, CodeInjector).

      However, the method has another effect, which is to set the retainedStaticContext in the node in the expression tree.

      Parameters:
      exp - the expression to be wrapped
      qName - the name of the construct (if applicable)
      Returns:
      the expression that does the tracing
    • 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
    • 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.
    • setAllowAbsentExpression

      public void setAllowAbsentExpression(boolean allowEmpty)
      Say whether an absent expression is permitted
      Parameters:
      allowEmpty - true if it is permitted for the expression to consist only of whitespace and comments, in which case the result of parsing will be an EmptySequence literal
    • isAllowAbsentExpression

      public boolean isAllowAbsentExpression()
      Ask whether an absent expression is permitted
      Returns:
      true if it is permitted for the expression to consist only of whitespace and comments, in which case the result of parsing will be an EmptySequence literal