📄 xpathparser.java
字号:
* Consume an expected token, throwing an exception if it * isn't there. * * @param expected The string to be expected. * * @throws javax.xml.transform.TransformerException */ private final void consumeExpected(String expected) throws javax.xml.transform.TransformerException { if (tokenIs(expected)) { nextToken(); } else { error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND, new Object[]{ expected, m_token }); //"Expected "+expected+", but found: "+m_token); // Patch for Christina's gripe. She wants her errorHandler to return from // this error and continue trying to parse, rather than throwing an exception. // Without the patch, that put us into an endless loop. throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR); } } /** * Consume an expected token, throwing an exception if it * isn't there. * * @param expected the character to be expected. * * @throws javax.xml.transform.TransformerException */ private final void consumeExpected(char expected) throws javax.xml.transform.TransformerException { if (tokenIs(expected)) { nextToken(); } else { error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND, new Object[]{ String.valueOf(expected), m_token }); //"Expected "+expected+", but found: "+m_token); // Patch for Christina's gripe. She wants her errorHandler to return from // this error and continue trying to parse, rather than throwing an exception. // Without the patch, that put us into an endless loop. throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR); } } /** * Warn the user of a problem. * * @param msg An error msgkey that corresponds to one of the constants found * in {@link com.sun.org.apache.xpath.internal.res.XPATHErrorResources}, which is * a key for a format string. * @param args An array of arguments represented in the format string, which * may be null. * * @throws TransformerException if the current ErrorListoner determines to * throw an exception. */ void warn(String msg, Object[] args) throws TransformerException { String fmsg = XSLMessages.createXPATHWarning(msg, args); ErrorListener ehandler = this.getErrorListener(); if (null != ehandler) { // TO DO: Need to get stylesheet Locator from here. ehandler.warning(new TransformerException(fmsg, m_sourceLocator)); } else { // Should never happen. System.err.println(fmsg); } } /** * Notify the user of an assertion error, and probably throw an * exception. * * @param b If false, a runtime exception will be thrown. * @param msg The assertion message, which should be informative. * * @throws RuntimeException if the b argument is false. */ private void assertion(boolean b, String msg) { if (!b) { String fMsg = XSLMessages.createXPATHMessage( XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION, new Object[]{ msg }); throw new RuntimeException(fMsg); } } /** * Notify the user of an error, and probably throw an * exception. * * @param msg An error msgkey that corresponds to one of the constants found * in {@link com.sun.org.apache.xpath.internal.res.XPATHErrorResources}, which is * a key for a format string. * @param args An array of arguments represented in the format string, which * may be null. * * @throws TransformerException if the current ErrorListoner determines to * throw an exception. */ void error(String msg, Object[] args) throws TransformerException { String fmsg = XSLMessages.createXPATHMessage(msg, args); ErrorListener ehandler = this.getErrorListener(); TransformerException te = new TransformerException(fmsg, m_sourceLocator); if (null != ehandler) { // TO DO: Need to get stylesheet Locator from here. ehandler.fatalError(te); } else { // System.err.println(fmsg); throw te; } } /** * This method is added to support DOM 3 XPath API. * <p> * This method is exactly like error(String, Object[]); except that * the underlying TransformerException is * XpathStylesheetDOM3Exception (which extends TransformerException). * <p> * So older XPath code in Xalan is not affected by this. To older XPath code * the behavior of whether error() or errorForDOM3() is called because it is * always catching TransformerException objects and is oblivious to * the new subclass of XPathStylesheetDOM3Exception. Older XPath code * runs as before. * <p> * However, newer DOM3 XPath code upon catching a TransformerException can * can check if the exception is an instance of XPathStylesheetDOM3Exception * and take appropriate action. * * @param msg An error msgkey that corresponds to one of the constants found * in {@link com.sun.org.apache.xpath.internal.res.XPATHErrorResources}, which is * a key for a format string. * @param args An array of arguments represented in the format string, which * may be null. * * @throws TransformerException if the current ErrorListoner determines to * throw an exception. */ void errorForDOM3(String msg, Object[] args) throws TransformerException { String fmsg = XSLMessages.createXPATHMessage(msg, args); ErrorListener ehandler = this.getErrorListener(); TransformerException te = new XPathStylesheetDOM3Exception(fmsg, m_sourceLocator); if (null != ehandler) { // TO DO: Need to get stylesheet Locator from here. ehandler.fatalError(te); } else { // System.err.println(fmsg); throw te; } } /** * Dump the remaining token queue. * Thanks to Craig for this. * * @return A dump of the remaining token queue, which may be appended to * an error message. */ protected String dumpRemainingTokenQueue() { int q = m_queueMark; String returnMsg; if (q < m_ops.getTokenQueueSize()) { String msg = "\n Remaining tokens: ("; while (q < m_ops.getTokenQueueSize()) { String t = (String) m_ops.m_tokenQueue.elementAt(q++); msg += (" '" + t + "'"); } returnMsg = msg + ")"; } else { returnMsg = ""; } return returnMsg; } /** * Given a string, return the corresponding function token. * * @param key A local name of a function. * * @return The function ID, which may correspond to one of the FUNC_XXX * values found in {@link com.sun.org.apache.xpath.internal.compiler.FunctionTable}, but may * be a value installed by an external module. */ final int getFunctionToken(String key) { int tok; Object id; try { // These are nodetests, xpathparser treats them as functions when parsing // a FilterExpr. id = Keywords.lookupNodeTest(key); if (null == id) id = m_functionTable.getFunctionID(key); tok = ((Integer) id).intValue(); } catch (NullPointerException npe) { tok = -1; } catch (ClassCastException cce) { tok = -1; } return tok; } /** * Insert room for operation. This will NOT set * the length value of the operation, but will update * the length value for the total expression. * * @param pos The position where the op is to be inserted. * @param length The length of the operation space in the op map. * @param op The op code to the inserted. */ void insertOp(int pos, int length, int op) { int totalLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH); for (int i = totalLen - 1; i >= pos; i--) { m_ops.setOp(i + length, m_ops.getOp(i)); } m_ops.setOp(pos,op); m_ops.setOp(OpMap.MAPINDEX_LENGTH,totalLen + length); } /** * Insert room for operation. This WILL set * the length value of the operation, and will update * the length value for the total expression. * * @param length The length of the operation. * @param op The op code to the inserted. */ void appendOp(int length, int op) { int totalLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH); m_ops.setOp(totalLen, op); m_ops.setOp(totalLen + OpMap.MAPINDEX_LENGTH, length); m_ops.setOp(OpMap.MAPINDEX_LENGTH, totalLen + length); } // ============= EXPRESSIONS FUNCTIONS ================= /** * * * Expr ::= OrExpr * * * @throws javax.xml.transform.TransformerException */ protected void Expr() throws javax.xml.transform.TransformerException { OrExpr(); } /** * * * OrExpr ::= AndExpr * | OrExpr 'or' AndExpr * * * @throws javax.xml.transform.TransformerException */ protected void OrExpr() throws javax.xml.transform.TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); AndExpr(); if ((null != m_token) && tokenIs("or")) { nextToken(); insertOp(opPos, 2, OpCodes.OP_OR); OrExpr(); m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos); } } /** * * * AndExpr ::= EqualityExpr * | AndExpr 'and' EqualityExpr * * * @throws javax.xml.transform.TransformerException */ protected void AndExpr() throws javax.xml.transform.TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); EqualityExpr(-1); if ((null != m_token) && tokenIs("and")) { nextToken(); insertOp(opPos, 2, OpCodes.OP_AND); AndExpr(); m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos); } } /** * * @returns an Object which is either a String, a Number, a Boolean, or a vector * of nodes. * * EqualityExpr ::= RelationalExpr * | EqualityExpr '=' RelationalExpr * * * @param addPos Position where expression is to be added, or -1 for append. * * @return the position at the end of the equality expression. * * @throws javax.xml.transform.TransformerException */ protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); if (-1 == addPos) addPos = opPos; RelationalExpr(-1); if (null != m_token) { if (tokenIs('!') && lookahead('=', 1)) { nextToken(); nextToken(); insertOp(addPos, 2, OpCodes.OP_NOTEQUALS); int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos; addPos = EqualityExpr(addPos); m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } else if (tokenIs('=')) { nextToken(); insertOp(addPos, 2, OpCodes.OP_EQUALS); int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos; addPos = EqualityExpr(addPos); m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } } return addPos; } /** * . * @returns an Object which is either a String, a Number, a Boolean, or a vector * of nodes. * * RelationalExpr ::= AdditiveExpr * | RelationalExpr '<' AdditiveExpr * | RelationalExpr '>' AdditiveExpr * | RelationalExpr '<=' AdditiveExpr * | RelationalExpr '>=' AdditiveExpr * * * @param addPos Position where expression is to be added, or -1 for append. * * @return the position at the end of the relational expression. * * @throws javax.xml.transform.TransformerException */ protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); if (-1 == addPos) addPos = opPos; AdditiveExpr(-1); if (null != m_token) { if (tokenIs('<')) { nextToken(); if (tokenIs('=')) { nextToken(); insertOp(addPos, 2, OpCodes.OP_LTE); } else { insertOp(addPos, 2, OpCodes.OP_LT); } int opPlusLeftHandLen = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos; addPos = RelationalExpr(addPos); m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } else if (tokenIs('>')) { nextToken(); if (tokenIs('=')) { nextToken(); insertOp(addPos, 2, OpCodes.OP_GTE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -