📄 compiler.java
字号:
addMagicSelf = false; argLen = getOp(opPos + OpMap.MAPINDEX_LENGTH); pattern = new FunctionPattern(compileFunction(opPos), Axis.PARENT, Axis.CHILD); break; case OpCodes.FROM_ROOT : if(DEBUG) System.out.println("FROM_ROOT, "+m_currentPattern); addMagicSelf = false; argLen = getArgLengthOfStep(opPos); opPos = getFirstChildPosOfStep(opPos); pattern = new StepPattern(DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT, Axis.PARENT, Axis.CHILD); break; case OpCodes.MATCH_ATTRIBUTE : if(DEBUG) System.out.println("MATCH_ATTRIBUTE: "+getStepLocalName(startOpPos)+", "+m_currentPattern); argLen = getArgLengthOfStep(opPos); opPos = getFirstChildPosOfStep(opPos); pattern = new StepPattern(DTMFilter.SHOW_ATTRIBUTE, getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.PARENT, Axis.ATTRIBUTE); break; case OpCodes.MATCH_ANY_ANCESTOR : if(DEBUG) System.out.println("MATCH_ANY_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern); argLen = getArgLengthOfStep(opPos); opPos = getFirstChildPosOfStep(opPos); int what = getWhatToShow(startOpPos); // bit-o-hackery, but this code is due for the morgue anyway... if(0x00000500 == what) addMagicSelf = false; pattern = new StepPattern(getWhatToShow(startOpPos), getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.ANCESTOR, Axis.CHILD); break; case OpCodes.MATCH_IMMEDIATE_ANCESTOR : if(DEBUG) System.out.println("MATCH_IMMEDIATE_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern); argLen = getArgLengthOfStep(opPos); opPos = getFirstChildPosOfStep(opPos); pattern = new StepPattern(getWhatToShow(startOpPos), getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.PARENT, Axis.CHILD); break; default : error(XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION, null); //"unknown match operation!"); return null; } pattern.setPredicates(getCompiledPredicates(opPos + argLen)); if(null == ancestorPattern) { // This is the magic and invisible "." at the head of every // match pattern, and corresponds to the current node in the context // list, from where predicates are counted. // So, in order to calculate "foo[3]", it has to count from the // current node in the context list, so, from that current node, // the full pattern is really "self::node()/child::foo[3]". If you // translate this to a select pattern from the node being tested, // which is really how we're treating match patterns, it works out to // self::foo/parent::node[child::foo[3]]", or close enough. /* if(addMagicSelf && pattern.getPredicateCount() > 0) { StepPattern selfPattern = new StepPattern(DTMFilter.SHOW_ALL, Axis.PARENT, Axis.CHILD); // We need to keep the new nodetest from affecting the score... XNumber score = pattern.getStaticScore(); pattern.setRelativePathPattern(selfPattern); pattern.setStaticScore(score); selfPattern.setStaticScore(score); }*/ } else { // System.out.println("Setting "+ancestorPattern+" as relative to "+pattern); pattern.setRelativePathPattern(ancestorPattern); } StepPattern relativePathPattern = stepPattern(endStep, stepCount + 1, pattern); return (null != relativePathPattern) ? relativePathPattern : pattern; } /** * Compile a zero or more predicates for a given match pattern. * * @param opPos The position of the first predicate the m_opMap array. * * @return reference to array of {@link com.sun.org.apache.xpath.internal.Expression} instances. * * @throws TransformerException if a error occurs creating the Expression. */ public Expression[] getCompiledPredicates(int opPos) throws TransformerException { int count = countPredicates(opPos); if (count > 0) { Expression[] predicates = new Expression[count]; compilePredicates(opPos, predicates); return predicates; } return null; } /** * Count the number of predicates in the step. * * @param opPos The position of the first predicate the m_opMap array. * * @return The number of predicates for this step. * * @throws TransformerException if a error occurs creating the Expression. */ public int countPredicates(int opPos) throws TransformerException { int count = 0; while (OpCodes.OP_PREDICATE == getOp(opPos)) { count++; opPos = getNextOpPos(opPos); } return count; } /** * Compiles predicates in the step. * * @param opPos The position of the first predicate the m_opMap array. * @param predicates An empty pre-determined array of * {@link com.sun.org.apache.xpath.internal.Expression}s, that will be filled in. * * @throws TransformerException */ private void compilePredicates(int opPos, Expression[] predicates) throws TransformerException { for (int i = 0; OpCodes.OP_PREDICATE == getOp(opPos); i++) { predicates[i] = predicate(opPos); opPos = getNextOpPos(opPos); } } /** * Compile a built-in XPath function. * * @param opPos The current position in the m_opMap array. * * @return reference to {@link com.sun.org.apache.xpath.internal.functions.Function} instance. * * @throws TransformerException if a error occurs creating the Expression. */ Expression compileFunction(int opPos) throws TransformerException { int endFunc = opPos + getOp(opPos + 1) - 1; opPos = getFirstChildPos(opPos); int funcID = getOp(opPos); opPos++; if (-1 != funcID) { Function func = m_functionTable.getFunction(funcID); /** * It is a trick for function-available. Since the function table is an * instance field, insert this table at compilation time for later usage */ if (func instanceof FuncExtFunctionAvailable) ((FuncExtFunctionAvailable) func).setFunctionTable(m_functionTable); func.postCompileStep(this); try { int i = 0; for (int p = opPos; p < endFunc; p = getNextOpPos(p), i++) { // System.out.println("argPos: "+ p); // System.out.println("argCode: "+ m_opMap[p]); func.setArg(compile(p), i); } func.checkNumberArgs(i); } catch (WrongNumberArgsException wnae) { java.lang.String name = m_functionTable.getFunctionName(funcID); m_errorHandler.fatalError( new TransformerException( XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ONLY_ALLOWS, new Object[]{name, wnae.getMessage()}), m_locator)); //"name + " only allows " + wnae.getMessage() + " arguments", m_locator)); } return func; } else { error(XPATHErrorResources.ER_FUNCTION_TOKEN_NOT_FOUND, null); //"function token not found."); return null; } } // The current id for extension functions. private static long s_nextMethodId = 0; /** * Get the next available method id */ synchronized private long getNextMethodId() { if (s_nextMethodId == Long.MAX_VALUE) s_nextMethodId = 0; return s_nextMethodId++; } /** * Compile an extension function. * * @param opPos The current position in the m_opMap array. * * @return reference to {@link com.sun.org.apache.xpath.internal.functions.FuncExtFunction} instance. * * @throws TransformerException if a error occurs creating the Expression. */ private Expression compileExtension(int opPos) throws TransformerException { int endExtFunc = opPos + getOp(opPos + 1) - 1; opPos = getFirstChildPos(opPos); java.lang.String ns = (java.lang.String) getTokenQueue().elementAt(getOp(opPos)); opPos++; java.lang.String funcName = (java.lang.String) getTokenQueue().elementAt(getOp(opPos)); opPos++; // We create a method key to uniquely identify this function so that we // can cache the object needed to invoke it. This way, we only pay the // reflection overhead on the first call. Function extension = new FuncExtFunction(ns, funcName, String.valueOf(getNextMethodId())); try { int i = 0; while (opPos < endExtFunc) { int nextOpPos = getNextOpPos(opPos); extension.setArg(this.compile(opPos), i); opPos = nextOpPos; i++; } } catch (WrongNumberArgsException wnae) { ; // should never happen } return extension; } /** * Warn the user of an 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. */ public void warn(String msg, Object[] args) throws TransformerException { java.lang.String fmsg = XSLMessages.createXPATHWarning(msg, args); if (null != m_errorHandler) { m_errorHandler.warning(new TransformerException(fmsg, m_locator)); } else { System.out.println(fmsg +"; file "+m_locator.getSystemId() +"; line "+m_locator.getLineNumber() +"; column "+m_locator.getColumnNumber()); } } /** * Tell 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. */ public void assertion(boolean b, java.lang.String msg) { if (!b) { java.lang.String fMsg = XSLMessages.createXPATHMessage( XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION, new Object[]{ msg }); throw new RuntimeException(fMsg); } } /** * Tell 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. */ public void error(String msg, Object[] args) throws TransformerException { java.lang.String fmsg = XSLMessages.createXPATHMessage(msg, args); if (null != m_errorHandler) { m_errorHandler.fatalError(new TransformerException(fmsg, m_locator)); } else { // System.out.println(te.getMessage() // +"; file "+te.getSystemId() // +"; line "+te.getLineNumber() // +"; column "+te.getColumnNumber()); throw new TransformerException(fmsg, (SAXSourceLocator)m_locator); } } /** * The current prefixResolver for the execution context. */ private PrefixResolver m_currentPrefixResolver = null; /** * Get the current namespace context for the xpath. * * @return The current prefix resolver, *may* be null, though hopefully not. */ public PrefixResolver getNamespaceContext() { return m_currentPrefixResolver; } /** * Set the current namespace context for the xpath. * * @param pr The resolver for prefixes in the XPath expression. */ public void setNamespaceContext(PrefixResolver pr) { m_currentPrefixResolver = pr; } /** The error listener where errors will be sent. If this is null, errors * and warnings will be sent to System.err. May be null. */ ErrorListener m_errorHandler; /** The source locator for the expression being compiled. May be null. */ SourceLocator m_locator; /** * The FunctionTable for all xpath build-in functions */ private FunctionTable m_functionTable;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -