lexer.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: lexer.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:43:15  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: lexer.cpp,v 1000.2 2004/06/01 19:43:15 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   ASN.1 lexer
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: lexer.cpp,v $
  41. * Revision 1000.2  2004/06/01 19:43:15  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  43. *
  44. * Revision 1.18  2004/05/17 21:03:14  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.17  2004/02/25 19:45:20  gouriano
  48. * Made it possible to define DEFAULT for data members of type REAL
  49. *
  50. * Revision 1.16  2003/05/22 20:10:25  gouriano
  51. * added UTF8 strings
  52. *
  53. * Revision 1.15  2003/01/31 03:38:41  lavr
  54. * Heed int->bool performance warnings
  55. *
  56. * Revision 1.14  2002/09/26 16:57:31  vasilche
  57. * Added flag for compatibility with asntool
  58. *
  59. * Revision 1.13  2001/06/11 14:35:02  grichenk
  60. * Added support for numeric tags in ASN.1 specifications and data streams.
  61. *
  62. * Revision 1.12  2001/05/17 15:07:12  lavr
  63. * Typos corrected
  64. *
  65. * Revision 1.11  2000/12/15 15:38:51  vasilche
  66. * Added support of Int8 and long double.
  67. * Added support of BigInt ASN.1 extension - mapped to Int8.
  68. * Enum values now have type Int4 instead of long.
  69. *
  70. * Revision 1.10  2000/11/15 20:34:54  vasilche
  71. * Added user comments to ENUMERATED types.
  72. * Added storing of user comments to ASN.1 module definition.
  73. *
  74. * Revision 1.9  2000/11/14 21:41:25  vasilche
  75. * Added preserving of ASN.1 definition comments.
  76. *
  77. * Revision 1.8  2000/08/25 15:59:22  vasilche
  78. * Renamed directory tool -> datatool.
  79. *
  80. * Revision 1.7  2000/04/07 19:26:27  vasilche
  81. * Added namespace support to datatool.
  82. * By default with argument -oR datatool will generate objects in namespace
  83. * NCBI_NS_NCBI::objects (aka ncbi::objects).
  84. * Datatool's classes also moved to NCBI namespace.
  85. *
  86. * Revision 1.6  2000/02/01 21:48:00  vasilche
  87. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  88. * Removed CMemberInfo subclasses.
  89. * Added support for DEFAULT/OPTIONAL members.
  90. * Changed class generation.
  91. * Moved datatool headers to include/internal/serial/tool.
  92. *
  93. * Revision 1.5  1999/11/15 19:36:16  vasilche
  94. * Fixed warnings on GCC
  95. *
  96. * ===========================================================================
  97. */
  98. #include <ncbi_pch.hpp>
  99. #include <serial/datatool/lexer.hpp>
  100. #include <serial/datatool/tokens.hpp>
  101. BEGIN_NCBI_SCOPE
  102. inline bool IsAlNum(char c)
  103. {
  104.     return isalnum(c) ? true : false;
  105. }
  106. inline bool IsDigit(char c)
  107. {
  108.     return isdigit(c) ? true : false;
  109. }
  110. ASNLexer::ASNLexer(CNcbiIstream& in)
  111.     : AbstractLexer(in)
  112. {
  113. }
  114. ASNLexer::~ASNLexer(void)
  115. {
  116. }
  117. TToken ASNLexer::LookupToken(void)
  118. {
  119.     char c = Char();
  120.     switch ( c ) {
  121.     case ':':
  122.         if ( Char(1) == ':' && Char(2) == '=' ) {
  123.             StartToken();
  124.             AddChars(3);
  125.             return T_DEFINE;
  126.         }
  127.         return T_SYMBOL;
  128.     case '-':
  129.     case '+':
  130.         if ( IsDigit(Char(1)) ) {
  131.             StartToken();
  132.             AddChar();
  133.             return LookupNumber();
  134.         }
  135.         return T_SYMBOL;
  136.     case '"':
  137.         StartToken();
  138.         AddChar();
  139.         StartString();
  140.         LookupString();
  141.         return T_STRING;
  142.     case ''':
  143.         StartToken();
  144.         AddChar();
  145.         return LookupBinHexString();
  146.     case '[':
  147.         StartToken();
  148.         AddChar();
  149.         LookupTag();
  150.         return T_TAG;
  151.     default:
  152.         if ( IsDigit(c) ) {
  153.             StartToken();
  154.             AddChar();
  155.             return LookupNumber();
  156.         }
  157.         else if ( c >= 'a' && c <= 'z' ) {
  158.             StartToken();
  159.             AddChar();
  160.             LookupIdentifier();
  161.             return T_IDENTIFIER;
  162.         }
  163.         else if ( c >= 'A' && c <= 'Z' ) {
  164.             StartToken();
  165.             AddChar();
  166.             LookupIdentifier();
  167.             return LookupKeyword();
  168.         }
  169.         return T_SYMBOL;
  170.     }
  171. }
  172. void ASNLexer::LookupComments(void)
  173. {
  174.     while ( true ) {
  175.         char c = Char();
  176.         switch ( c ) {
  177.         case ' ':
  178.         case 't':
  179.         case 'r':
  180.             SkipChar();
  181.             break;
  182.         case 'n':
  183.             SkipChar();
  184.             NextLine();
  185.             break;
  186.         case '-':
  187.             if ( Char(1) == '-' ) {
  188.                 // comments
  189.                 SkipChars(2);
  190.                 SkipComment();
  191.                 break;
  192.             }
  193.             return;
  194.         default:
  195.             return;
  196.         }
  197.     }
  198. }
  199. void ASNLexer::SkipComment(void)
  200. {
  201.     CComment& comment = AddComment();
  202.     while ( true ) {
  203.         // wait for end of comments
  204.         char c = Char();
  205.         switch ( c ) {
  206.         case 'n':
  207.             SkipChar();
  208.             NextLine();
  209.             return;
  210.         case 0:
  211.             if ( Eof() )
  212.                 return;
  213.             break;
  214.         case '-':
  215.             if ( Char(1) == '-' ) {
  216.                 SkipChars(2);
  217.                 return;
  218.             }
  219.             break;
  220.         }
  221.         comment.AddChar(c);
  222.         SkipChar();
  223.     }
  224. }
  225. void ASNLexer::LookupString(void)
  226. {
  227.     while ( true ) {
  228.         char c = Char();
  229.         switch ( c ) {
  230.         case 'r':
  231.         case 'n':
  232.             LexerWarning("unclosed string");
  233.             return;
  234.         case 0:
  235.             if ( Eof() ) {
  236.                 LexerWarning("unclosed string");
  237.                 return;
  238.             }
  239.             LexerWarning("illegal character in string: \0");
  240.             AddStringChar(c);
  241.             AddChar();
  242.             break;
  243.         case '"':
  244.             if ( Char(1) != '"' ) {
  245.                 AddChar();
  246.                 return;
  247.             }
  248.             AddChars(2);
  249.             break;
  250.         default:
  251.             if ( c < ' ' && c > '' ) {
  252.                 LexerWarning("illegal character in string: \...");
  253.             }
  254.             else {
  255.                 AddStringChar(c);
  256.             }
  257.             AddChar();
  258.             break;
  259.         }
  260.     }
  261. }
  262. TToken ASNLexer::LookupBinHexString(void)
  263. {
  264.     TToken token = T_BINARY_STRING;
  265.     while ( true ) {
  266.         char c = Char();
  267.         switch ( c ) {
  268.         case 'r':
  269.         case 'n':
  270.             LexerWarning("unclosed bit string");
  271.             return token;
  272.         case 0:
  273.             if ( Eof() ) {
  274.                 LexerWarning("unclosed bit string");
  275.                 return token;
  276.             }
  277.             AddChar();
  278.             LexerWarning("illegal character in bit string");
  279.             break;
  280.         case '0':
  281.         case '1':
  282.             AddChar();
  283.             break;
  284.         case '2': case '3': case '4': case '5': case '6': case '7': case '8':
  285.         case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  286.             AddChar();
  287.             token = T_HEXADECIMAL_STRING;
  288.             break;
  289.         case ''':
  290.             switch ( Char(1) ) {
  291.             case 'B':
  292.                 AddChars(2);
  293.                 if ( token != T_BINARY_STRING )
  294.                     LexerWarning("binary string contains hexadecimal digits");
  295.                 return T_BINARY_STRING;
  296.             case 'H':
  297.                 AddChars(2);
  298.                 return T_HEXADECIMAL_STRING;
  299.             default:
  300.                 AddChar();
  301.                 LexerWarning("unknown type of bit string");
  302.                 return token;
  303.             }
  304.         default:
  305.             AddChar();
  306.             LexerWarning("illegal character in bit string");
  307.             break;
  308.         }
  309.     }
  310. }
  311. void ASNLexer::LookupIdentifier(void)
  312. {
  313.     while ( true ) {
  314.         char c = Char();
  315.         if ( IsAlNum(c) )
  316.             AddChar();
  317.         else if ( c == '-' ) {
  318.             if ( IsAlNum(Char(1)) )
  319.                 AddChars(2);
  320.             else {
  321.                 if ( AllowIDsEndingWithMinus() )
  322.                     AddChar();
  323.                 return;
  324.             }
  325.         }
  326.         else
  327.             return;
  328.     }
  329. }
  330. TToken ASNLexer::LookupNumber(void)
  331. {
  332.     while ( IsDigit(Char()) ) {
  333.         AddChar();
  334.     }
  335.     char c = Char();
  336.     if (c == '.' || c == 'e' || c == 'E' || c == '-' || c == '+') {
  337.         AddChar();
  338.         LookupNumber();
  339.         return T_DOUBLE;
  340.     }
  341.     return T_NUMBER;
  342. }
  343. void ASNLexer::LookupTag(void)
  344. {
  345.     while ( true ) {
  346.         char c = Char();
  347.         switch ( c ) {
  348.         case 'r':
  349.         case 'n':
  350.             LexerWarning("unclosed tag");
  351.             return;
  352.         case 0:
  353.             if ( Eof() ) {
  354.                 LexerWarning("unclosed tag");
  355.                 return;
  356.             }
  357.             AddChar();
  358.             LexerWarning("illegal character in tag");
  359.             break;
  360.         case ']':
  361.             AddChar();
  362.             return;
  363.         case '0': case '1': case '2': case '3': case '4':
  364.         case '5': case '6': case '7': case '8': case '9':
  365.         // case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  366.             AddChar();
  367.             break;
  368.         default:
  369.             AddChar();
  370.             LexerWarning("illegal character in tag");
  371.             break;
  372.         }
  373.     }
  374. }
  375. #define CHECK(keyword, t, length) 
  376.     if ( memcmp(token, keyword, length) == 0 ) return t
  377. TToken ASNLexer::LookupKeyword(void)
  378. {
  379.     const char* token = CurrentTokenStart();
  380.     switch ( CurrentTokenLength() ) {
  381.     case 2:
  382.         CHECK("OF", K_OF, 2);
  383.         break;
  384.     case 3:
  385.         CHECK("SET", K_SET, 3);
  386.         CHECK("BIT", K_BIT, 3);
  387.         CHECK("END", K_END, 3);
  388.         break;
  389.     case 4:
  390.         CHECK("TRUE", K_TRUE, 4);
  391.         CHECK("NULL", K_NULL, 4);
  392.         CHECK("REAL", K_REAL, 4);
  393.         CHECK("FROM", K_FROM, 4);
  394.         break;
  395.     case 5:
  396.         CHECK("OCTET", K_OCTET, 5);
  397.         CHECK("BEGIN", K_BEGIN, 5);
  398.         CHECK("FALSE", K_FALSE, 5);
  399.         break;
  400.     case 6:
  401.         CHECK("CHOICE", K_CHOICE, 6);
  402.         CHECK("STRING", K_STRING, 6);
  403.         CHECK("BigInt", K_BIGINT, 6);
  404.         break;
  405.     case 7:
  406.         CHECK("INTEGER", K_INTEGER, 7);
  407.         CHECK("BOOLEAN", K_BOOLEAN, 7);
  408.         CHECK("DEFAULT", K_DEFAULT, 7);
  409.         CHECK("IMPORTS", K_IMPORTS, 7);
  410.         CHECK("EXPORTS", K_EXPORTS, 7);
  411.         break;
  412.     case 8:
  413.         CHECK("SEQUENCE", K_SEQUENCE, 8);
  414.         CHECK("OPTIONAL", K_OPTIONAL, 8);
  415.         break;
  416.     case 10:
  417.         CHECK("ENUMERATED", K_ENUMERATED, 10);
  418.         CHECK("UTF8String", K_UTF8String, 10);
  419.         break;
  420.     case 11:
  421.         CHECK("StringStore", K_StringStore, 11);
  422.         CHECK("DEFINITIONS", K_DEFINITIONS, 11);
  423.         break;
  424.     case 13:
  425.         CHECK("VisibleString", K_VisibleString, 13);
  426.         break;
  427.     }
  428.     return T_TYPE_REFERENCE;
  429. }
  430. void ASNLexer::StartString(void)
  431. {
  432.     _ASSERT(TokenStarted());
  433.     m_StringValue.erase();
  434. }
  435. void ASNLexer::AddStringChar(char c)
  436. {
  437.     _ASSERT(TokenStarted());
  438.     m_StringValue += c;
  439. }
  440. END_NCBI_SCOPE