ParserForXMLSchema.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:17k
源码类别:

xml/soap/webservice

开发平台:

C/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  2001/09/20 13:11:42  knoaman
  59.  * Regx  + misc. fixes
  60.  *
  61.  * Revision 1.5  2001/06/01 14:15:37  knoaman
  62.  * Add a return value to satisfy compilers that complain about
  63.  * no return value, although that code will not be executed.
  64.  *
  65.  * Revision 1.4  2001/05/11 21:50:56  knoaman
  66.  * Schema updates and fixes.
  67.  *
  68.  * Revision 1.3  2001/05/11 13:26:44  tng
  69.  * Copyright update.
  70.  *
  71.  * Revision 1.2  2001/05/03 18:17:30  knoaman
  72.  * Some design changes:
  73.  * o Changed the TokenFactory from a single static instance, to a
  74.  *    normal class. Each RegularExpression object will have its own
  75.  *    instance of TokenFactory, and that instance will be passed to
  76.  *    other classes that need to use a TokenFactory to create Token
  77.  *    objects (with the exception of RangeTokenMap).
  78.  * o Added a new class RangeTokenMap to map a the different ranges
  79.  *    in a given category to a specific RangeFactory object. In the old
  80.  *    design RangeFactory had dual functionality (act as a Map, and as
  81.  *    a factory for creating RangeToken(s)). The RangeTokenMap will
  82.  *    have its own copy of the TokenFactory. There will be only one
  83.  *    instance of the RangeTokenMap class, and that instance will be
  84.  *    lazily deleted when XPlatformUtils::Terminate is called.
  85.  *
  86.  * Revision 1.1  2001/03/02 19:26:43  knoaman
  87.  * Schema: Regular expression handling part II
  88.  *
  89.  */
  90. // ---------------------------------------------------------------------------
  91. //  Includes
  92. // ---------------------------------------------------------------------------
  93. #include <util/regx/ParserForXMLSchema.hpp>
  94. #include <util/regx/TokenFactory.hpp>
  95. #include <util/regx/RangeToken.hpp>
  96. #include <util/regx/TokenInc.hpp>
  97. #include <util/regx/RegxDefs.hpp>
  98. #include <util/ParseException.hpp>
  99. #include <util/RuntimeException.hpp>
  100. // ---------------------------------------------------------------------------
  101. //  ParserForXMLSchema: Constructors and Destructors
  102. // ---------------------------------------------------------------------------
  103. ParserForXMLSchema::ParserForXMLSchema()
  104.     : RegxParser()
  105. {
  106. }
  107. ParserForXMLSchema::~ParserForXMLSchema() {
  108. }
  109. // ---------------------------------------------------------------------------
  110. //  ParserForXMLSchema: Parsing/Processing methods
  111. // ---------------------------------------------------------------------------
  112. Token* ParserForXMLSchema::processCaret() {
  113.     processNext();
  114.     return getTokenFactory()->createChar(chCaret);
  115. }
  116. Token* ParserForXMLSchema::processDollar() {
  117.     processNext();
  118.     return getTokenFactory()->createChar(chDollarSign);
  119. }
  120. Token* ParserForXMLSchema::processPlus(Token* const tok) {
  121.     processNext();
  122.     return getTokenFactory()->createConcat(tok,
  123.                                getTokenFactory()->createClosure(tok));
  124. }
  125. Token* ParserForXMLSchema::processStar(Token* const tok) {
  126.     processNext();
  127.     return getTokenFactory()->createClosure(tok);
  128. }
  129. Token* ParserForXMLSchema::processQuestion(Token* const tok) {
  130.     processNext();
  131.     TokenFactory* tokFactory = getTokenFactory();
  132.     Token* retTok = tokFactory->createUnion();
  133.     retTok->addChild(tok, tokFactory);
  134.     retTok->addChild(tokFactory->createToken(Token::EMPTY), tokFactory);
  135.     return retTok;
  136. }
  137. Token* ParserForXMLSchema::processParen() {
  138.     processNext();
  139.     Token* retTok = getTokenFactory()->createParenthesis(parseRegx(), 0);
  140.     if (getState() != T_RPAREN) {
  141.         ThrowXML(ParseException, XMLExcepts::Parser_Factor1);
  142.     }
  143.     processNext();
  144.     return retTok;
  145. }
  146. RangeToken* ParserForXMLSchema::parseCharacterClass(const bool useNRange) {
  147.     setParseContext(S_INBRACKETS);
  148.     processNext();
  149.     RangeToken* base = 0;
  150.     RangeToken* tok = 0;
  151.     bool isNRange = false;
  152.     if (getState() == T_CHAR && getCharData() == chCaret) {
  153.         isNRange = true;
  154.         processNext();
  155.         base = getTokenFactory()->createRange();
  156.         base->addRange(0, Token::UTF16_MAX);
  157.         tok = getTokenFactory()->createRange();
  158.     }
  159.     else {
  160.         tok= getTokenFactory()->createRange();
  161.     }
  162.     int type;
  163.     bool firstLoop = true;
  164.     while ( (type = getState()) != T_EOF) {
  165.         // single range | from-to-range | subtraction
  166.         if (type == T_CHAR && getCharData() == chCloseSquare && !firstLoop) {
  167.             if (isNRange) {
  168.                 base->subtractRanges(tok);
  169.                 tok = base;
  170.             }
  171.             break;
  172.         }
  173.         XMLInt32 ch = getCharData();
  174.         bool     end = false;
  175.         if (type == T_BACKSOLIDUS) {
  176.             switch(ch) {
  177.             case chLatin_d:
  178.             case chLatin_D:
  179.             case chLatin_w:
  180.             case chLatin_W:
  181.             case chLatin_s:
  182.             case chLatin_S:
  183.                 {
  184.                     tok->mergeRanges(getTokenForShorthand(ch));
  185.                     end = true;
  186.                 }
  187.                 break;
  188.             case chLatin_i:
  189.             case chLatin_I:
  190.             case chLatin_c:
  191.             case chLatin_C:
  192.                 {
  193.                     ch = processCInCharacterClass(tok, ch);
  194.                     if (ch < 0) {
  195.                         end = true;
  196.                     }
  197.                 }
  198.                 break;
  199.             case chLatin_p:
  200.             case chLatin_P:
  201.                 {
  202.                     int start = getOffset();
  203.                     RangeToken* tok2 = processBacksolidus_pP(ch);
  204.                     if (tok2 == 0) {
  205.                         ThrowXML(ParseException,XMLExcepts::Parser_Atom5);
  206.                     }
  207.                     tok->mergeRanges(tok2);
  208.                     end = true;
  209.                 }
  210.                 break;
  211.             default:
  212.                 ch = decodeEscaped();
  213.             }
  214.         } // end if T_BACKSOLIDUS
  215.         else if (type == T_XMLSCHEMA_CC_SUBTRACTION && !firstLoop) {
  216.             if (isNRange) {
  217.                 base->subtractRanges(tok);
  218.                 tok = base;
  219.             }
  220.             RangeToken* rangeTok = parseCharacterClass(false);
  221.             tok->subtractRanges(rangeTok);
  222.             if (getState() != T_CHAR || getCharData() != chCloseSquare) {
  223.                 ThrowXML(ParseException,XMLExcepts::Parser_CC5);
  224.             }
  225.             break;
  226.         } // end if T_XMLSCHEMA...
  227.         processNext();
  228.         if (!end) {
  229.             if (type == T_CHAR) {
  230.                 if (ch == chOpenSquare)
  231.                     ThrowXML(ParseException,XMLExcepts::Parser_CC6);
  232.                 if (ch == chCloseSquare)
  233.                     ThrowXML(ParseException,XMLExcepts::Parser_CC7);
  234.             }
  235.             if (getState() != T_CHAR || getCharData() != chDash) {
  236.                 tok->addRange(ch, ch);
  237.             }
  238.             else {
  239.                 processNext();
  240.                 if ((type = getState()) == T_EOF)
  241.                     ThrowXML(ParseException,XMLExcepts::Parser_CC2);
  242.                 if (type == T_CHAR && getCharData() == chCloseSquare) {
  243.                     tok->addRange(ch, ch);
  244.                     tok->addRange(chDash, chDash);
  245.                 }
  246.                 else if (type == T_XMLSCHEMA_CC_SUBTRACTION) {
  247.                     tok->addRange(ch, ch);
  248.                     tok->addRange(chDash, chDash);
  249.                 }
  250.                 else {
  251.                     XMLInt32 rangeEnd = getCharData();
  252.                     if (type == T_CHAR) {
  253.                         if (rangeEnd == chOpenSquare)
  254.                             ThrowXML(ParseException,XMLExcepts::Parser_CC6);
  255.                         if (rangeEnd == chCloseSquare)
  256.                             ThrowXML(ParseException,XMLExcepts::Parser_CC7);
  257.                     }
  258.                     if (type == T_BACKSOLIDUS) {
  259.                         rangeEnd = decodeEscaped();
  260.                     }
  261.                     processNext();
  262.                     if (ch > rangeEnd) {
  263.                         XMLCh rangeEndStr[] = { rangeEnd, chNull };
  264.                         XMLCh chStr[] = { ch, chNull };
  265.                         ThrowXML2(ParseException,XMLExcepts::Parser_Ope3, rangeEndStr, chStr);
  266.                     }
  267.                     tok->addRange(ch, rangeEnd);
  268.                 }
  269.             }
  270.         }
  271.         firstLoop = false;
  272.     }
  273.     if (getState() == T_EOF)
  274.         ThrowXML(ParseException,XMLExcepts::Parser_CC2);
  275.     tok->sortRanges();
  276.     tok->compactRanges();
  277.     setParseContext(S_NORMAL);
  278.     processNext();
  279.     return tok;
  280. }
  281. XMLInt32 ParserForXMLSchema::processCInCharacterClass(RangeToken* const tok,
  282.                                                       const XMLInt32 ch)
  283. {
  284.     tok->mergeRanges(getTokenForShorthand(ch));
  285.     return -1;
  286. }
  287. Token* ParserForXMLSchema::processLook(const unsigned short tokType) {
  288.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  289.     return 0; // for compilers that complain about no return value
  290. }
  291. Token* ParserForXMLSchema::processBacksolidus_A() {
  292.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  293.     return 0; // for compilers that complain about no return value
  294. }
  295. Token* ParserForXMLSchema::processBacksolidus_B() {
  296.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  297.     return 0; // for compilers that complain about no return value
  298. }
  299. Token* ParserForXMLSchema::processBacksolidus_b() {
  300.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  301.     return 0; // for compilers that complain about no return value
  302. }
  303. Token* ParserForXMLSchema::processBacksolidus_C() {
  304.     processNext();
  305.     return getTokenForShorthand(chLatin_C);
  306. }
  307. Token* ParserForXMLSchema::processBacksolidus_c() {
  308.     processNext();
  309.     return getTokenForShorthand(chLatin_c);
  310. }
  311. Token* ParserForXMLSchema::processBacksolidus_g() {
  312.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  313.     return 0; // for compilers that complain about no return value
  314. }
  315. Token* ParserForXMLSchema::processBacksolidus_gt() {
  316.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  317.     return 0; // for compilers that complain about no return value
  318. }
  319. Token* ParserForXMLSchema::processBacksolidus_I() {
  320.     processNext();
  321.     return getTokenForShorthand(chLatin_I);
  322. }
  323. Token* ParserForXMLSchema::processBacksolidus_i() {
  324.     processNext();
  325.     return getTokenForShorthand(chLatin_i);
  326. }
  327. Token* ParserForXMLSchema::processBacksolidus_lt() {
  328.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  329.     return 0; // for compilers that complain about no return value
  330. }
  331. Token* ParserForXMLSchema::processBacksolidus_X() {
  332.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  333.     return 0; // for compilers that complain about no return value
  334. }
  335. Token* ParserForXMLSchema::processBacksolidus_Z() {
  336.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  337.     return 0; // for compilers that complain about no return value
  338. }
  339. Token* ParserForXMLSchema::processBacksolidus_z() {
  340.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  341.     return 0; // for compilers that complain about no return value
  342. }
  343. Token* ParserForXMLSchema::processBackReference() {
  344.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  345.     return 0; // for compilers that complain about no return value
  346. }
  347. Token* ParserForXMLSchema::processCondition() {
  348.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  349.     return 0; // for compilers that complain about no return value
  350. }
  351. Token* ParserForXMLSchema::processIndependent() {
  352.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  353.     return 0; // for compilers that complain about no return value
  354. }
  355. Token* ParserForXMLSchema::processModifiers() {
  356.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  357.     return 0; // for compilers that complain about no return value
  358. }
  359. Token* ParserForXMLSchema::processParen2() {
  360.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  361.     return 0; // for compilers that complain about no return value
  362. }
  363. RangeToken* ParserForXMLSchema::parseSetOperations() {
  364.     ThrowXML(RuntimeException, XMLExcepts::Regex_NotSupported);
  365.     return 0; // for compilers that complain about no return value
  366. }
  367. // ---------------------------------------------------------------------------
  368. //  ParserForXMLSchema: Getter methods
  369. // ---------------------------------------------------------------------------
  370. Token* ParserForXMLSchema::getTokenForShorthand(const XMLInt32 ch) {
  371.     switch(ch) {
  372.     case chLatin_d:
  373.         return getTokenFactory()->getRange(fgXMLDigit);
  374.     case chLatin_D:
  375.         return getTokenFactory()->getRange(fgXMLDigit, true);
  376.     case chLatin_w:
  377.         return getTokenFactory()->getRange(fgXMLWord);
  378.     case chLatin_W:
  379.         return getTokenFactory()->getRange(fgXMLWord, true);
  380.     case chLatin_s:
  381.         return getTokenFactory()->getRange(fgXMLSpace);
  382.     case chLatin_S:
  383.         return getTokenFactory()->getRange(fgXMLSpace, true);
  384.     case chLatin_c:
  385.         return getTokenFactory()->getRange(fgXMLNameChar);
  386.     case chLatin_C:
  387.         return getTokenFactory()->getRange(fgXMLNameChar, true);
  388.     case chLatin_i:
  389.         return getTokenFactory()->getRange(fgXMLInitialNameChar);
  390.     case chLatin_I:
  391.         return getTokenFactory()->getRange(fgXMLInitialNameChar, true);
  392.     }
  393.     return 0;
  394. }
  395. // ---------------------------------------------------------------------------
  396. //  ParserForXMLSchema: Helper methods
  397. // ---------------------------------------------------------------------------
  398. bool ParserForXMLSchema::checkQuestion(const int off) {
  399.     return false;
  400. }
  401. XMLInt32 ParserForXMLSchema::decodeEscaped() {
  402.     if (getState() != T_BACKSOLIDUS)
  403.         ThrowXML(ParseException,XMLExcepts::Parser_Next1);;
  404.     XMLInt32 ch = getCharData();
  405.     switch (ch) {
  406.     case chLatin_n:
  407.         ch = chLF;
  408.         break;
  409.     case chLatin_r:
  410.         ch = chCR;
  411.         break;
  412.     case chLatin_t:
  413.         ch = chHTab;
  414.         break;
  415.     case chBackSlash:
  416.     case chPipe:
  417.     case chPeriod:
  418.     case chCaret:
  419.     case chDash:
  420.     case chQuestion:
  421.     case chAsterisk:
  422.     case chPlus:
  423.     case chOpenCurly:
  424.     case chCloseCurly:
  425.     case chOpenParen:
  426.     case chCloseParen:
  427.     case chOpenSquare:
  428.     case chCloseSquare:
  429.         break;
  430.     default:
  431. {        
  432.         XMLCh chString[] = {chBackSlash, ch, chNull};
  433.         chString[1] = ch;
  434.         ThrowXML1(ParseException,XMLExcepts::Parser_Process2, chString);
  435.         }
  436.     }
  437.     return ch;
  438. }
  439. /**
  440.   * End of file ParserForXMLSchema.cpp
  441.   */