lexer.java

来自「java jdk 1.4的源码」· Java 代码 · 共 694 行 · 第 1/2 页

JAVA
694
字号
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation.  All rights  * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment:   *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written  *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    nor may "Apache" appear in their name, without prior written *    permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.xpath.compiler;import java.util.Vector;import org.apache.xml.utils.PrefixResolver;import org.apache.xpath.res.XPATHErrorResources;/** * This class is in charge of lexical processing of the XPath * expression into tokens. */class Lexer{  /**   * The target XPath.   */  private Compiler m_compiler;  /**   * The prefix resolver to map prefixes to namespaces in the XPath.   */  PrefixResolver m_namespaceContext;  /**   * The XPath processor object.   */  XPathParser m_processor;  /**   * This value is added to each element name in the TARGETEXTRA   * that is a 'target' (right-most top-level element name).   */  static final int TARGETEXTRA = 10000;  /**   * Ignore this, it is going away.   * This holds a map to the m_tokenQueue that tells where the top-level elements are.   * It is used for pattern matching so the m_tokenQueue can be walked backwards.   * Each element that is a 'target', (right-most top level element name) has   * TARGETEXTRA added to it.   *   */  private int m_patternMap[] = new int[100];  /**   * Ignore this, it is going away.   * The number of elements that m_patternMap maps;   */  private int m_patternMapSize;  /**   * Create a Lexer object.   *   * @param compiler The owning compiler for this lexer.   * @param resolver The prefix resolver for mapping qualified name prefixes    *                 to namespace URIs.   * @param xpathProcessor The parser that is processing strings to opcodes.   */  Lexer(Compiler compiler, PrefixResolver resolver,        XPathParser xpathProcessor)  {    m_compiler = compiler;    m_namespaceContext = resolver;    m_processor = xpathProcessor;  }  /**   * Walk through the expression and build a token queue, and a map of the top-level   * elements.   * @param pat XSLT Expression.   *   * @throws javax.xml.transform.TransformerException   */  void tokenize(String pat) throws javax.xml.transform.TransformerException  {    tokenize(pat, null);  }  /**   * Walk through the expression and build a token queue, and a map of the top-level   * elements.   * @param pat XSLT Expression.   * @param targetStrings Vector to hold Strings, may be null.   *   * @throws javax.xml.transform.TransformerException   */  void tokenize(String pat, Vector targetStrings)          throws javax.xml.transform.TransformerException  {    m_compiler.m_currentPattern = pat;    m_patternMapSize = 0;     // This needs to grow too.    m_compiler.m_opMap = new OpMapVector(OpMap.MAXTOKENQUEUESIZE * 5, OpMap.BLOCKTOKENQUEUESIZE * 5, OpMap.MAPINDEX_LENGTH);    int nChars = pat.length();    int startSubstring = -1;     int posOfNSSep = -1;    boolean isStartOfPat = true;    boolean isAttrName = false;    boolean isNum = false;    // Nesting of '[' so we can know if the given element should be    // counted inside the m_patternMap.    int nesting = 0;    // char[] chars = pat.toCharArray();    for (int i = 0; i < nChars; i++)    {      char c = pat.charAt(i);      switch (c)      {      case '\"' :      {        if (startSubstring != -1)        {          isNum = false;          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);          isAttrName = false;          if (-1 != posOfNSSep)          {            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);          }          else          {            addToTokenQueue(pat.substring(startSubstring, i));          }        }        startSubstring = i;        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\"'); i++);        if (c == '\"' && i < nChars)        {          addToTokenQueue(pat.substring(startSubstring, i + 1));          startSubstring = -1;        }        else        {          m_processor.error(XPATHErrorResources.ER_EXPECTED_DOUBLE_QUOTE,                            null);  //"misquoted literal... expected double quote!");        }      }      break;      case '\'' :        if (startSubstring != -1)        {          isNum = false;          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);          isAttrName = false;          if (-1 != posOfNSSep)          {            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);          }          else          {            addToTokenQueue(pat.substring(startSubstring, i));          }        }        startSubstring = i;        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\''); i++);        if (c == '\'' && i < nChars)        {          addToTokenQueue(pat.substring(startSubstring, i + 1));          startSubstring = -1;        }        else        {          m_processor.error(XPATHErrorResources.ER_EXPECTED_SINGLE_QUOTE,                            null);  //"misquoted literal... expected single quote!");        }        break;      case 0x0A :      case 0x0D :      case ' ' :      case '\t' :        if (startSubstring != -1)        {          isNum = false;          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);          isAttrName = false;          if (-1 != posOfNSSep)          {            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);          }          else          {            addToTokenQueue(pat.substring(startSubstring, i));          }          startSubstring = -1;        }        break;      case '@' :        isAttrName = true;      // fall-through on purpose      case '-' :        if ('-' == c)        {          if (!(isNum || (startSubstring == -1)))          {            break;          }          isNum = false;        }      // fall-through on purpose      case '(' :      case '[' :      case ')' :      case ']' :      case '|' :      case '/' :      case '*' :      case '+' :      case '=' :      case ',' :      case '\\' :  // Unused at the moment      case '^' :  // Unused at the moment      case '!' :  // Unused at the moment      case '$' :      case '<' :      case '>' :        if (startSubstring != -1)        {          isNum = false;          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);          isAttrName = false;          if (-1 != posOfNSSep)          {            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);          }          else          {            addToTokenQueue(pat.substring(startSubstring, i));          }          startSubstring = -1;        }        else if (('/' == c) && isStartOfPat)        {          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);        }        else if ('*' == c)        {          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);          isAttrName = false;        }        if (0 == nesting)        {          if ('|' == c)          {            if (null != targetStrings)            {              recordTokenString(targetStrings);            }            isStartOfPat = true;          }        }        if ((')' == c) || (']' == c))        {          nesting--;        }        else if (('(' == c) || ('[' == c))        {          nesting++;        }        addToTokenQueue(pat.substring(i, i + 1));        break;      case ':' :        if (i>0)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?