ParserForXMLSchema.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:18k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: ParserForXMLSchema.cpp,v $
  58.  * Revision 1.6  2003/05/15 18:42:54  knoaman
  59.  * Partial implementation of the configurable memory manager.
  60.  *
  61.  * Revision 1.5  2003/03/18 19:38:28  knoaman
  62.  * Schema Errata E2-18 + misc. regex fixes.
  63.  *
  64.  * Revision 1.4  2003/01/13 19:02:23  knoaman
  65.  * [Bug 14390] C++ Indentifier collision with Python.
  66.  *
  67.  * Revision 1.3  2002/11/04 15:17:00  tng
  68.  * C++ Namespace Support.
  69.  *
  70.  * Revision 1.2  2002/03/18 19:29:53  knoaman
  71.  * Change constant names to eliminate possible conflict with user defined ones.
  72.  *
  73.  * Revision 1.1.1.1  2002/02/01 22:22:29  peiyongz
  74.  * sane_include
  75.  *
  76.  * Revision 1.6  2001/09/20 13:11:42  knoaman
  77.  * Regx  + misc. fixes
  78.  *
  79.  * Revision 1.5  2001/06/01 14:15:37  knoaman
  80.  * Add a return value to satisfy compilers that complain about
  81.  * no return value, although that code will not be executed.
  82.  *
  83.  * Revision 1.4  2001/05/11 21:50:56  knoaman
  84.  * Schema updates and fixes.
  85.  *
  86.  * Revision 1.3  2001/05/11 13:26:44  tng
  87.  * Copyright update.
  88.  *
  89.  * Revision 1.2  2001/05/03 18:17:30  knoaman
  90.  * Some design changes:
  91.  * o Changed the TokenFactory from a single static instance, to a
  92.  *    normal class. Each RegularExpression object will have its own
  93.  *    instance of TokenFactory, and that instance will be passed to
  94.  *    other classes that need to use a TokenFactory to create Token
  95.  *    objects (with the exception of RangeTokenMap).
  96.  * o Added a new class RangeTokenMap to map a the different ranges
  97.  *    in a given category to a specific RangeFactory object. In the old
  98.  *    design RangeFactory had dual functionality (act as a Map, and as
  99.  *    a factory for creating RangeToken(s)). The RangeTokenMap will
  100.  *    have its own copy of the TokenFactory. There will be only one
  101.  *    instance of the RangeTokenMap class, and that instance will be
  102.  *    lazily deleted when XPlatformUtils::Terminate is called.
  103.  *
  104.  * Revision 1.1  2001/03/02 19:26:43  knoaman
  105.  * Schema: Regular expression handling part II
  106.  *
  107.  */
  108. // ---------------------------------------------------------------------------
  109. //  Includes
  110. // ---------------------------------------------------------------------------
  111. #include <xercesc/util/regx/ParserForXMLSchema.hpp>
  112. #include <xercesc/util/regx/TokenFactory.hpp>
  113. #include <xercesc/util/regx/RangeToken.hpp>
  114. #include <xercesc/util/regx/TokenInc.hpp>
  115. #include <xercesc/util/regx/RegxDefs.hpp>
  116. #include <xercesc/util/ParseException.hpp>
  117. #include <xercesc/util/RuntimeException.hpp>
  118. #include <xercesc/util/PlatformUtils.hpp>
  119. XERCES_CPP_NAMESPACE_BEGIN
  120. // ---------------------------------------------------------------------------
  121. //  ParserForXMLSchema: Constructors and Destructors
  122. // ---------------------------------------------------------------------------
  123. ParserForXMLSchema::ParserForXMLSchema(MemoryManager* const manager)
  124.     : RegxParser(manager)
  125. {
  126. }
  127. ParserForXMLSchema::~ParserForXMLSchema() {
  128. }
  129. // ---------------------------------------------------------------------------
  130. //  ParserForXMLSchema: Parsing/Processing methods
  131. // ---------------------------------------------------------------------------
  132. Token* ParserForXMLSchema::processCaret() {
  133.     processNext();
  134.     return getTokenFactory()->createChar(chCaret);
  135. }
  136. Token* ParserForXMLSchema::processDollar() {
  137.     processNext();
  138.     return getTokenFactory()->createChar(chDollarSign);
  139. }
  140. Token* ParserForXMLSchema::processPlus(Token* const tok) {
  141.     processNext();
  142.     return getTokenFactory()->createConcat(tok,
  143.                                getTokenFactory()->createClosure(tok));
  144. }
  145. Token* ParserForXMLSchema::processStar(Token* const tok) {
  146.     processNext();
  147.     return getTokenFactory()->createClosure(tok);
  148. }
  149. Token* ParserForXMLSchema::processQuestion(Token* const tok) {
  150.     processNext();
  151.     TokenFactory* tokFactory = getTokenFactory();
  152.     Token* retTok = tokFactory->createUnion();
  153.     retTok->addChild(tok, tokFactory);
  154.     retTok->addChild(tokFactory->createToken(Token::T_EMPTY), tokFactory);
  155.     return retTok;
  156. }
  157. Token* ParserForXMLSchema::processParen() {
  158.     processNext();
  159.     Token* retTok = getTokenFactory()->createParenthesis(parseRegx(true), 0);
  160.     if (getState() != REGX_T_RPAREN) {
  161.         ThrowXML(ParseException, XMLExcepts::Parser_Factor1);
  162.     }
  163.     processNext();
  164.     return retTok;
  165. }
  166. RangeToken* ParserForXMLSchema::parseCharacterClass(const bool useNRange) {
  167.     setParseContext(S_INBRACKETS);
  168.     processNext();
  169.     RangeToken* base = 0;
  170.     RangeToken* tok = 0;
  171.     bool isNRange = false;
  172.     if (getState() == REGX_T_CHAR && getCharData() == chCaret) {
  173.         isNRange = true;
  174.         processNext();
  175.         base = getTokenFactory()->createRange();
  176.         base->addRange(0, Token::UTF16_MAX);
  177.         tok = getTokenFactory()->createRange();
  178.     }
  179.     else {
  180.         tok= getTokenFactory()->createRange();
  181.     }
  182.     int type;
  183.     bool firstLoop = true;
  184.     while ( (type = getState()) != REGX_T_EOF) {
  185.         // single range | from-to-range | subtraction
  186.         if (type == REGX_T_CHAR && getCharData() == chCloseSquare && !firstLoop) {
  187.             if (isNRange) {
  188.                 base->subtractRanges(tok);
  189.                 tok = base;
  190.             }
  191.             break;
  192.         }
  193.         XMLInt32 ch = getCharData();
  194.         bool     end = false;
  195.         if (type == REGX_T_BACKSOLIDUS) {
  196.             switch(ch) {
  197.             case chLatin_d:
  198.             case chLatin_D:
  199.             case chLatin_w:
  200.             case chLatin_W:
  201.             case chLatin_s:
  202.             case chLatin_S:
  203.                 {
  204.                     tok->mergeRanges(getTokenForShorthand(ch));
  205.                     end = true;
  206.                 }
  207.                 break;
  208.             case chLatin_i:
  209.             case chLatin_I:
  210.             case chLatin_c:
  211.             case chLatin_C:
  212.                 {
  213.                     ch = processCInCharacterClass(tok, ch);
  214.                     if (ch < 0) {
  215.                         end = true;
  216.                     }
  217.                 }
  218.                 break;
  219.             case chLatin_p:
  220.             case chLatin_P:
  221.                 {
  222.                     int start = getOffset();
  223.                     RangeToken* tok2 = processBacksolidus_pP(ch);
  224.                     if (tok2 == 0) {
  225.                         ThrowXML(ParseException,XMLExcepts::Parser_Atom5);
  226.                     }
  227.                     tok->mergeRanges(tok2);
  228.                     end = true;
  229.                 }
  230.                 break;
  231.             default:
  232.                 ch = decodeEscaped();
  233.             }
  234.         } // end if REGX_T_BACKSOLIDUS
  235.         else if (type == REGX_T_XMLSCHEMA_CC_SUBTRACTION && !firstLoop) {
  236.             if (isNRange) {
  237.                 base->subtractRanges(tok);
  238.                 tok = base;
  239.             }
  240.             RangeToken* rangeTok = parseCharacterClass(false);
  241.             tok->subtractRanges(rangeTok);
  242.             if (getState() != REGX_T_CHAR || getCharData() != chCloseSquare) {
  243.                 ThrowXML(ParseException,XMLExcepts::Parser_CC5);
  244.             }
  245.             break;
  246.         } // end if REGX_T_XMLSCHEMA...
  247.         processNext();
  248.         if (!end) {
  249.             if (type == REGX_T_CHAR
  250.                 && (ch == chOpenSquare
  251.                     || ch == chCloseSquare
  252.                     || ch == chDash)) {
  253.                 // '[', ']', '-' not allowed and should be esacaped
  254.                 XMLCh chStr[] = { ch, chNull };
  255.                 ThrowXML2(ParseException,XMLExcepts::Parser_CC6, chStr, chStr);
  256.             }
  257.             if (getState() != REGX_T_CHAR || getCharData() != chDash) {
  258.                 tok->addRange(ch, ch);
  259.             }
  260.             else {
  261.                 processNext();
  262.                 if ((type = getState()) == REGX_T_EOF)
  263.                     ThrowXML(ParseException,XMLExcepts::Parser_CC2);
  264.                 if ((type == REGX_T_CHAR && getCharData() == chCloseSquare)
  265.                     || type == REGX_T_XMLSCHEMA_CC_SUBTRACTION) {
  266.                     static const XMLCh dashStr[] = { chDash, chNull};
  267.                     ThrowXML2(ParseException, XMLExcepts::Parser_CC6, dashStr, dashStr);
  268.                 }
  269.                 else {
  270.                     XMLInt32 rangeEnd = getCharData();
  271.                     XMLCh rangeEndStr[] = { rangeEnd, chNull };
  272.                     if (type == REGX_T_CHAR) {
  273.                         if (rangeEnd == chOpenSquare
  274.                             || rangeEnd == chCloseSquare
  275.                             || rangeEnd == chDash)
  276.                             // '[', ']', '-' not allowed and should be esacaped
  277.                             ThrowXML2(ParseException, XMLExcepts::Parser_CC6, rangeEndStr, rangeEndStr);
  278.                     }
  279.                     else if (type == REGX_T_BACKSOLIDUS) {
  280.                         rangeEnd = decodeEscaped();
  281.                     }
  282.                     processNext();
  283.                     if (ch > rangeEnd) {
  284.                         XMLCh chStr[] = { ch, chNull };
  285.                         ThrowXML2(ParseException,XMLExcepts::Parser_Ope3, rangeEndStr, chStr);
  286.                     }
  287.                     tok->addRange(ch, rangeEnd);
  288.                 }
  289.             }
  290.         }
  291.         firstLoop = false;
  292.     }
  293.     if (getState() == REGX_T_EOF)
  294.         ThrowXML(ParseException,XMLExcepts::Parser_CC2);
  295.     tok->sortRanges();
  296.     tok->compactRanges();
  297.     setParseContext(S_NORMAL);
  298.     processNext();
  299.     return tok;
  300. }
  301. XMLInt32 ParserForXMLSchema::processCInCharacterClass(RangeToken* const tok,
  302.                                                       const XMLInt32 ch)
  303. {
  304.     tok->mergeRanges(getTokenForShorthand(ch));
  305.     return -1;
  306. }
  307. Token* ParserForXMLSchema::processLook(const unsigned short tokType) {
  308.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  309.     return 0; // for compilers that complain about no return value
  310. }
  311. Token* ParserForXMLSchema::processBacksolidus_A() {
  312.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  313.     return 0; // for compilers that complain about no return value
  314. }
  315. Token* ParserForXMLSchema::processBacksolidus_B() {
  316.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  317.     return 0; // for compilers that complain about no return value
  318. }
  319. Token* ParserForXMLSchema::processBacksolidus_b() {
  320.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  321.     return 0; // for compilers that complain about no return value
  322. }
  323. Token* ParserForXMLSchema::processBacksolidus_C() {
  324.     processNext();
  325.     return getTokenForShorthand(chLatin_C);
  326. }
  327. Token* ParserForXMLSchema::processBacksolidus_c() {
  328.     processNext();
  329.     return getTokenForShorthand(chLatin_c);
  330. }
  331. Token* ParserForXMLSchema::processBacksolidus_g() {
  332.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  333.     return 0; // for compilers that complain about no return value
  334. }
  335. Token* ParserForXMLSchema::processBacksolidus_gt() {
  336.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  337.     return 0; // for compilers that complain about no return value
  338. }
  339. Token* ParserForXMLSchema::processBacksolidus_I() {
  340.     processNext();
  341.     return getTokenForShorthand(chLatin_I);
  342. }
  343. Token* ParserForXMLSchema::processBacksolidus_i() {
  344.     processNext();
  345.     return getTokenForShorthand(chLatin_i);
  346. }
  347. Token* ParserForXMLSchema::processBacksolidus_lt() {
  348.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  349.     return 0; // for compilers that complain about no return value
  350. }
  351. Token* ParserForXMLSchema::processBacksolidus_X() {
  352.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  353.     return 0; // for compilers that complain about no return value
  354. }
  355. Token* ParserForXMLSchema::processBacksolidus_Z() {
  356.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  357.     return 0; // for compilers that complain about no return value
  358. }
  359. Token* ParserForXMLSchema::processBacksolidus_z() {
  360.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  361.     return 0; // for compilers that complain about no return value
  362. }
  363. Token* ParserForXMLSchema::processBackReference() {
  364.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  365.     return 0; // for compilers that complain about no return value
  366. }
  367. Token* ParserForXMLSchema::processCondition() {
  368.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  369.     return 0; // for compilers that complain about no return value
  370. }
  371. Token* ParserForXMLSchema::processIndependent() {
  372.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  373.     return 0; // for compilers that complain about no return value
  374. }
  375. Token* ParserForXMLSchema::processModifiers() {
  376.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  377.     return 0; // for compilers that complain about no return value
  378. }
  379. Token* ParserForXMLSchema::processParen2() {
  380.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  381.     return 0; // for compilers that complain about no return value
  382. }
  383. RangeToken* ParserForXMLSchema::parseSetOperations() {
  384.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  385.     return 0; // for compilers that complain about no return value
  386. }
  387. // ---------------------------------------------------------------------------
  388. //  ParserForXMLSchema: Getter methods
  389. // ---------------------------------------------------------------------------
  390. Token* ParserForXMLSchema::getTokenForShorthand(const XMLInt32 ch) {
  391.     switch(ch) {
  392.     case chLatin_d:
  393.         return getTokenFactory()->getRange(fgXMLDigit);
  394.     case chLatin_D:
  395.         return getTokenFactory()->getRange(fgXMLDigit, true);
  396.     case chLatin_w:
  397.         return getTokenFactory()->getRange(fgXMLWord);
  398.     case chLatin_W:
  399.         return getTokenFactory()->getRange(fgXMLWord, true);
  400.     case chLatin_s:
  401.         return getTokenFactory()->getRange(fgXMLSpace);
  402.     case chLatin_S:
  403.         return getTokenFactory()->getRange(fgXMLSpace, true);
  404.     case chLatin_c:
  405.         return getTokenFactory()->getRange(fgXMLNameChar);
  406.     case chLatin_C:
  407.         return getTokenFactory()->getRange(fgXMLNameChar, true);
  408.     case chLatin_i:
  409.         return getTokenFactory()->getRange(fgXMLInitialNameChar);
  410.     case chLatin_I:
  411.         return getTokenFactory()->getRange(fgXMLInitialNameChar, true);
  412.     }
  413.     return 0;
  414. }
  415. // ---------------------------------------------------------------------------
  416. //  ParserForXMLSchema: Helper methods
  417. // ---------------------------------------------------------------------------
  418. bool ParserForXMLSchema::checkQuestion(const int off) {
  419.     return false;
  420. }
  421. XMLInt32 ParserForXMLSchema::decodeEscaped() {
  422.     if (getState() != REGX_T_BACKSOLIDUS)
  423.         ThrowXML(ParseException,XMLExcepts::Parser_Next1);;
  424.     XMLInt32 ch = getCharData();
  425.     switch (ch) {
  426.     case chLatin_n:
  427.         ch = chLF;
  428.         break;
  429.     case chLatin_r:
  430.         ch = chCR;
  431.         break;
  432.     case chLatin_t:
  433.         ch = chHTab;
  434.         break;
  435.     case chBackSlash:
  436.     case chPipe:
  437.     case chPeriod:
  438.     case chCaret:
  439.     case chDash:
  440.     case chQuestion:
  441.     case chAsterisk:
  442.     case chPlus:
  443.     case chOpenCurly:
  444.     case chCloseCurly:
  445.     case chOpenParen:
  446.     case chCloseParen:
  447.     case chOpenSquare:
  448.     case chCloseSquare:
  449.         break;
  450.     default:
  451. {
  452.         XMLCh chString[] = {chBackSlash, ch, chNull};
  453.         chString[1] = ch;
  454.         ThrowXML1(ParseException,XMLExcepts::Parser_Process2, chString);
  455.         }
  456.     }
  457.     return ch;
  458. }
  459. XERCES_CPP_NAMESPACE_END
  460. /**
  461.   * End of file ParserForXMLSchema.cpp
  462.   */