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

词法分析

开发平台:

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: TokenFactory.cpp,v $
  58.  * Revision 1.8  2003/05/18 14:02:06  knoaman
  59.  * Memory manager implementation: pass per instance manager.
  60.  *
  61.  * Revision 1.7  2003/05/16 21:37:00  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.6  2003/05/16 00:03:10  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.5  2003/03/04 21:11:12  knoaman
  68.  * [Bug 17516] Thread safety problems in ../util/ and ../util/regx.
  69.  *
  70.  * Revision 1.4  2002/12/24 17:59:07  tng
  71.  * Build with ICU 2.4
  72.  *
  73.  * Revision 1.3  2002/11/04 15:17:00  tng
  74.  * C++ Namespace Support.
  75.  *
  76.  * Revision 1.2  2002/03/18 19:29:53  knoaman
  77.  * Change constant names to eliminate possible conflict with user defined ones.
  78.  *
  79.  * Revision 1.1.1.1  2002/02/01 22:22:31  peiyongz
  80.  * sane_include
  81.  *
  82.  * Revision 1.5  2001/06/07 20:55:39  tng
  83.  * Fix no newline at the end warning.  By Pei Yong Zhang.
  84.  *
  85.  * Revision 1.4  2001/05/11 13:26:51  tng
  86.  * Copyright update.
  87.  *
  88.  * Revision 1.3  2001/05/03 18:17:52  knoaman
  89.  * Some design changes:
  90.  * o Changed the TokenFactory from a single static instance, to a
  91.  *    normal class. Each RegularExpression object will have its own
  92.  *    instance of TokenFactory, and that instance will be passed to
  93.  *    other classes that need to use a TokenFactory to create Token
  94.  *    objects (with the exception of RangeTokenMap).
  95.  * o Added a new class RangeTokenMap to map a the different ranges
  96.  *    in a given category to a specific RangeFactory object. In the old
  97.  *    design RangeFactory had dual functionality (act as a Map, and as
  98.  *    a factory for creating RangeToken(s)). The RangeTokenMap will
  99.  *    have its own copy of the TokenFactory. There will be only one
  100.  *    instance of the RangeTokenMap class, and that instance will be
  101.  *    lazily deleted when XPlatformUtils::Terminate is called.
  102.  *
  103.  * Revision 1.2  2001/03/22 13:23:34  knoaman
  104.  * Minor modifications to eliminate compiler warnings.
  105.  *
  106.  * Revision 1.1  2001/03/02 19:23:00  knoaman
  107.  * Schema: Regular expression handling part I
  108.  *
  109.  */
  110. // ---------------------------------------------------------------------------
  111. //  Includes
  112. // ---------------------------------------------------------------------------
  113. #include <xercesc/util/regx/TokenFactory.hpp>
  114. #include <xercesc/util/regx/TokenInc.hpp>
  115. #include <xercesc/util/regx/XMLRangeFactory.hpp>
  116. #include <xercesc/util/regx/ASCIIRangeFactory.hpp>
  117. #include <xercesc/util/regx/UnicodeRangeFactory.hpp>
  118. #include <xercesc/util/regx/BlockRangeFactory.hpp>
  119. #include <xercesc/util/regx/RangeTokenMap.hpp>
  120. #include <xercesc/util/regx/RegxDefs.hpp>
  121. XERCES_CPP_NAMESPACE_BEGIN
  122. bool TokenFactory::fRangeInitialized = false;
  123. // ---------------------------------------------------------------------------
  124. //  TokenFactory: Constructors and Destructor
  125. // ---------------------------------------------------------------------------
  126. TokenFactory::TokenFactory(MemoryManager* const manager) :
  127.     fTokens(new (manager) RefVectorOf<Token> (16, true, manager))
  128.     , fEmpty(0)
  129.     , fLineBegin(0)
  130.     , fLineBegin2(0)
  131.     , fLineEnd(0)
  132.     , fStringBegin(0)
  133.     , fStringEnd(0)
  134.     , fStringEnd2(0)
  135.     , fWordEdge(0)
  136.     , fNotWordEdge(0)
  137.     , fWordEnd(0)
  138.     , fWordBegin(0)
  139.     , fDot(0)
  140.     , fCombiningChar(0)
  141.     , fGrapheme(0)
  142.     , fMemoryManager(manager)
  143. {
  144. }
  145. TokenFactory::~TokenFactory() {
  146. delete fTokens;
  147. fTokens = 0;
  148. }
  149. // ---------------------------------------------------------------------------
  150. //  TokenFactory - Factory methods
  151. // ---------------------------------------------------------------------------
  152. Token* TokenFactory::createToken(const unsigned short tokType) {
  153. if (tokType == Token::T_EMPTY && fEmpty != 0)
  154. return fEmpty;
  155. Token* tmpTok = new (fMemoryManager) Token(tokType);
  156. if (tokType == Token::T_EMPTY) {
  157. fEmpty = tmpTok;
  158.     }
  159. fTokens->addElement(tmpTok);
  160. return tmpTok;
  161. }
  162. ParenToken* TokenFactory::createLook(const unsigned short tokType,
  163.  Token* const token) {
  164. ParenToken* tmpTok = new (fMemoryManager) ParenToken(tokType, token, 0);
  165. fTokens->addElement(tmpTok);
  166. return tmpTok;
  167. }
  168. ParenToken* TokenFactory::createParenthesis(Token* const token,
  169. const int noGroups) {
  170. ParenToken* tmpTok = new (fMemoryManager) ParenToken(Token::T_PAREN, token, noGroups);
  171. fTokens->addElement(tmpTok);
  172. return tmpTok;
  173. }
  174. ClosureToken* TokenFactory::createClosure(Token* const token,
  175.   bool isNonGreedy) {
  176. ClosureToken* tmpTok = isNonGreedy ? new (fMemoryManager) ClosureToken(Token::T_NONGREEDYCLOSURE, token)
  177.    : new (fMemoryManager) ClosureToken(Token::T_CLOSURE, token);
  178. fTokens->addElement(tmpTok);
  179. return tmpTok;
  180. }
  181. ConcatToken* TokenFactory::createConcat(Token* const token1,
  182.                                         Token* const token2) {
  183.     ConcatToken* tmpTok = new (fMemoryManager) ConcatToken(token1, token2);
  184.     fTokens->addElement(tmpTok);
  185.     return tmpTok;
  186. }
  187. UnionToken* TokenFactory::createUnion(const bool isConcat) {
  188. UnionToken* tmpTok = isConcat ? new (fMemoryManager) UnionToken(Token::T_CONCAT)
  189.   : new (fMemoryManager) UnionToken(Token::T_UNION);
  190. fTokens->addElement(tmpTok);
  191. return tmpTok;
  192. }
  193. RangeToken* TokenFactory::createRange(const bool isNegRange){
  194. RangeToken* tmpTok = isNegRange ? new (fMemoryManager) RangeToken(Token::T_NRANGE, fMemoryManager)
  195.    : new (fMemoryManager) RangeToken(Token::T_RANGE, fMemoryManager);
  196. fTokens->addElement(tmpTok);
  197. return tmpTok;
  198. return 0;
  199. }
  200. CharToken* TokenFactory::createChar(const XMLUInt32 ch, const bool isAnchor) {
  201. CharToken* tmpTok = isAnchor ? new (fMemoryManager) CharToken(Token::T_ANCHOR, ch)
  202. : new (fMemoryManager) CharToken(Token::T_CHAR, ch);
  203. fTokens->addElement(tmpTok);
  204. return tmpTok;
  205. }
  206. StringToken* TokenFactory::createBackReference(const int noRefs) {
  207. StringToken* tmpTok = new (fMemoryManager) StringToken(Token::T_BACKREFERENCE, 0, noRefs, fMemoryManager);
  208. fTokens->addElement(tmpTok);
  209. return tmpTok;
  210. }
  211. StringToken* TokenFactory::createString(const XMLCh* const literal) {
  212. StringToken* tmpTok = new (fMemoryManager) StringToken(Token::T_STRING, literal, 0, fMemoryManager);
  213. fTokens->addElement(tmpTok);
  214. return tmpTok;
  215. }
  216. ModifierToken* TokenFactory::createModifierGroup(Token* const child,
  217.                                                  const int add,
  218.                                                  const int mask) {
  219. ModifierToken* tmpTok = new (fMemoryManager) ModifierToken(child, add, mask);
  220. fTokens->addElement(tmpTok);
  221. return tmpTok;
  222. }
  223. ConditionToken* TokenFactory::createCondition(const int refNo,
  224.                                               Token* const condition,
  225.                                               Token* const yesFlow,
  226.                                               Token* const noFlow) {
  227. ConditionToken* tmpTok = new (fMemoryManager) ConditionToken(refNo, condition, yesFlow,
  228.                                                 noFlow);
  229. fTokens->addElement(tmpTok);
  230. return tmpTok;
  231. }
  232. // ---------------------------------------------------------------------------
  233. //  TokenFactory - Getter methods
  234. // ---------------------------------------------------------------------------
  235. RangeToken* TokenFactory::getRange(const XMLCh* const keyword,
  236.                                    const bool complement) {
  237.     if (!fRangeInitialized) {
  238. initializeRegistry();
  239. }
  240. return RangeTokenMap::instance()->getRange(keyword, complement);
  241. }
  242. Token* TokenFactory::getLineBegin() {
  243. if (fLineBegin == 0)
  244.         fLineBegin = createChar(chCaret, true);
  245.     return fLineBegin;
  246. }
  247. Token* TokenFactory::getLineBegin2() {
  248. if (fLineBegin2 == 0)
  249.         fLineBegin2 = createChar(chAt, true);
  250.     return fLineBegin2;
  251. }
  252. Token* TokenFactory::getLineEnd() {
  253. if (fLineEnd == 0)
  254.         fLineEnd = createChar(chDollarSign, true);
  255.     return fLineEnd;
  256. }
  257. Token* TokenFactory::getStringBegin() {
  258. if (fStringBegin == 0)
  259.         fStringBegin = createChar(chLatin_A, true);
  260.     return fStringBegin;
  261. }
  262. Token* TokenFactory::getStringEnd() {
  263. if (fStringEnd == 0)
  264.         fStringEnd = createChar(chLatin_z, true);
  265.     return fStringEnd;
  266. }
  267. Token* TokenFactory::getStringEnd2() {
  268. if (fStringEnd2 == 0)
  269.         fStringEnd2 = createChar(chLatin_Z, true);
  270.     return fStringEnd2;
  271. }
  272. Token* TokenFactory::getWordEdge() {
  273. if (fWordEdge == 0)
  274.         fWordEdge = createChar(chLatin_b, true);
  275.     return fWordEdge;
  276. }
  277. Token* TokenFactory::getNotWordEdge(){
  278. if (fNotWordEdge == 0)
  279.         fNotWordEdge = createChar(chLatin_B, true);
  280.     return fNotWordEdge;
  281. }
  282. Token* TokenFactory::getWordBegin() {
  283. if (fWordBegin == 0)
  284.         fWordBegin = createChar(chOpenAngle, true);
  285.     return fWordBegin;
  286. }
  287. Token* TokenFactory::getWordEnd() {
  288. if (fWordEnd == 0)
  289.         fWordEnd = createChar(chCloseAngle, true);
  290.     return fWordEnd;
  291. }
  292. Token* TokenFactory::getDot() {
  293. if (fDot == 0)
  294.         fDot = createToken(Token::T_DOT);
  295.     return fDot;
  296. }
  297. Token* TokenFactory::getCombiningCharacterSequence() {
  298. if (fCombiningChar == 0) {
  299. Token* foo = createClosure(getRange(fgUniMark)); // pM*
  300. foo = createConcat(getRange(fgUniMark, true), foo); // PM + pM*
  301. fCombiningChar = foo;
  302. }
  303. return fCombiningChar;
  304. }
  305. //    static final String viramaString =
  306. Token* TokenFactory::getGraphemePattern() {
  307. if (fGrapheme == 0) {
  308.         Token* base_char = createRange();  // [{ASSIGNED}]-[{M},{C}]
  309.         base_char->mergeRanges(getRange(fgUniAssigned));
  310.         base_char->subtractRanges(getRange(fgUniMark));
  311.         base_char->subtractRanges(getRange(fgUniControl));
  312.         Token* virama = createRange();
  313. virama->addRange(0x094D, 0x094D);
  314. virama->addRange(0x09CD, 0x09CD);
  315. virama->addRange(0x0A4D, 0x0A4D);
  316. virama->addRange(0x0ACD, 0x0ACD);
  317. virama->addRange(0x0B4D, 0x0B4D);
  318. virama->addRange(0x0BCD, 0x0BCD);
  319. virama->addRange(0x0C4D, 0x0C4D);
  320. virama->addRange(0x0CCD, 0x0CCD);
  321. virama->addRange(0x0D4D, 0x0D4D);
  322. virama->addRange(0x0E3A, 0x0E3A);
  323. virama->addRange(0x0F84, 0x0F84);
  324.         Token* combiner_wo_virama = createRange();
  325.         combiner_wo_virama->mergeRanges(getRange(fgUniMark));
  326.         combiner_wo_virama->addRange(0x1160, 0x11FF); // hangul_medial and hangul_final
  327.         combiner_wo_virama->addRange(0xFF9F, 0xFF9F); // extras
  328.         Token* left = TokenFactory::createUnion();       // base_char?
  329.         left->addChild(base_char, this);
  330.         left->addChild(createToken(Token::T_EMPTY), this);
  331.         Token* foo = createUnion();
  332.         foo->addChild(TokenFactory::createConcat(virama,getRange(fgUniLetter)), this);
  333.         foo->addChild(combiner_wo_virama, this);
  334.         foo = createClosure(foo);
  335.         foo = createConcat(left, foo);
  336.         fGrapheme = foo;
  337. }
  338. return fGrapheme;
  339. }
  340. // ---------------------------------------------------------------------------
  341. //  TokenFactory - Helper methods
  342. // ---------------------------------------------------------------------------
  343. void TokenFactory::initializeRegistry() {
  344.     if (fRangeInitialized)
  345.         return;
  346.     // Use a faux scope to synchronize while we do this
  347.     {
  348.         XMLMutexLock lockInit(&fMutex);
  349.         if (!fRangeInitialized) {
  350.             RangeTokenMap::instance()->initializeRegistry();
  351.             // Add categories
  352.             RangeTokenMap::instance()->addCategory(fgXMLCategory);
  353.             RangeTokenMap::instance()->addCategory(fgASCIICategory);
  354.             RangeTokenMap::instance()->addCategory(fgUnicodeCategory);
  355.             RangeTokenMap::instance()->addCategory(fgBlockCategory);
  356.          // Add xml range factory
  357.             RangeFactory* rangeFact = new XMLRangeFactory();
  358.             RangeTokenMap::instance()->addRangeMap(fgXMLCategory, rangeFact);
  359.             rangeFact->initializeKeywordMap();
  360.             // Add ascii range factory
  361.             rangeFact = new ASCIIRangeFactory();
  362.             RangeTokenMap::instance()->addRangeMap(fgASCIICategory, rangeFact);
  363.             rangeFact->initializeKeywordMap();
  364.             // Add unicode range factory
  365.             rangeFact = new UnicodeRangeFactory();
  366.             RangeTokenMap::instance()->addRangeMap(fgUnicodeCategory, rangeFact);
  367.             rangeFact->initializeKeywordMap();
  368.             // Add block range factory
  369.             rangeFact = new BlockRangeFactory();
  370.             RangeTokenMap::instance()->addRangeMap(fgBlockCategory, rangeFact);
  371.             rangeFact->initializeKeywordMap();
  372.             fRangeInitialized = true;
  373.         }
  374.     }
  375. }
  376. /*
  377. #if defined (XML_USE_ICU_TRANSCODER)
  378.    #include <unicode/uchar.h>
  379. #endif
  380. #include <stdio.h>
  381. void TokenFactory::printUnicode() {
  382. #if defined (XML_USE_ICU_TRANSCODER)
  383.     //
  384.     //  Write it out to a temp file to be read back into this source later.
  385.     //
  386. printf("Printingn");
  387. //sprintf(msg, "Printingn");
  388.     FILE* outFl = fopen("table.out", "wt+");
  389.     fprintf(outFl, "const XMLByte fgUniCharsTable[0x10000] =n{    ");
  390.     for (unsigned int index = 0; index <= 0xFFFF; index += 16)
  391.     {
  392.         fprintf(outFl
  393.                 , "    , 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02Xn"
  394.                 , (unsigned int)u_charType(index)
  395.                 , (unsigned int)u_charType(index+1)
  396.                 , (unsigned int)u_charType(index+2)
  397.                 , (unsigned int)u_charType(index+3)
  398.                 , (unsigned int)u_charType(index+4)
  399.                 , (unsigned int)u_charType(index+5)
  400.                 , (unsigned int)u_charType(index+6)
  401.                 , (unsigned int)u_charType(index+7)
  402. , (unsigned int)u_charType(index+8)
  403.                 , (unsigned int)u_charType(index+9)
  404.                 , (unsigned int)u_charType(index+10)
  405.                 , (unsigned int)u_charType(index+11)
  406. , (unsigned int)u_charType(index+12)
  407.                 , (unsigned int)u_charType(index+13)
  408.                 , (unsigned int)u_charType(index+14)
  409.                 , (unsigned int)u_charType(index+15));
  410.     }
  411.     fprintf(outFl, "};n");
  412.     fclose(outFl);
  413. #endif
  414. }
  415. */
  416. XERCES_CPP_NAMESPACE_END
  417. /**
  418.   * End of file TokenFactory.cpp
  419.   */