Parser.cpp
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:6k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
  2. // Copyright 1996 by Jarle Aase. All rights reserved.
  3. // See the "War Software Series Licende Agreement" for details concerning 
  4. // use and distribution.
  5. // ---
  6. // This source code, executables and programs containing source code or
  7. // binaries or proprietetary technology from the War Software Series are
  8. // NOT alloed used, viewed or tested by any governmental agencies in
  9. // any countries. This includes the government, departments, police, 
  10. // military etc.
  11. // ---
  12. // This file is intended for use with Tab space = 2
  13. // Created and maintained in MSVC Developer Studio
  14. // ---
  15. // NAME : Parser.cpp
  16. // PURPOSE : Parsing of single line commands
  17. // PROGRAM : 
  18. // DATE : Sept. 26 1996
  19. // AUTHOR : Jarle Aase
  20. // ---
  21. // REVISION HISTORY
  22. // 
  23. #include "stdafx.h"
  24. #include "WarSoftware.h"
  25. #include "..IncludeParser.h"
  26. enum // Token ID's
  27. {
  28. TOK_QUIT = TOK_START_TAB, TOK_HELP
  29. };
  30. // Command tokens
  31. static STokenTab BaseTokens[] =
  32. {
  33. {TOK_QUIT, "QUIT" },
  34. {TOK_HELP, "HELP" },
  35. {TOK_INVALID, "" }
  36. };
  37. enum // Commands recognized on this level
  38. {
  39. CMD_QUIT = CMD_START_TREE, CMD_HELP
  40. };
  41. // Command tree
  42. static SCommandTree BaseCmds[] =
  43. {
  44. {TOK_QUIT, CMD_QUIT, 0, 0, NULL, ' ', LEX_WANT_CMD, NULL},
  45. {TOK_HELP, CMD_HELP, 0, 0, NULL, ' ', LEX_WANT_CMD, NULL},
  46. {TOK_INVALID, CMD_INVALID, 0, NULL, 0, 0}
  47. };
  48. CCommandParser::CCommandParser()
  49. {
  50. m_Commands = (SCommandTree *) BaseTokens;
  51. m_Tokens = (STokenTab *) BaseTokens;
  52. }
  53. int CCommandParser::ParseCmd(LPCSTR CmdLine, CCmdArgs& Args, int Level)
  54. {
  55. int CmdID = yyParse(CmdLine, m_Commands, m_Tokens, Args);
  56. //if (CmdID < CMD_START_TREE)
  57. //{
  58. // int TryCmdID = BaseClass::ParseCmd()
  59. // return max(TryCmdID,CmdID);
  60. //}
  61. return CmdID;
  62. }
  63. int CCommandParser::yyParse(LPCSTR CmdLine, SCommandTree *CmdPtr, STokenTab *LexTab, CCmdArgs& Args)
  64. {
  65. int CmdID = CMD_PARSE_ERROR, TokenID, LexEOT = ' ', LexWant = LEX_WANT_CMD;
  66. LPCSTR LexCmdLine = CmdLine;
  67. // Initialize
  68. int level = 0;
  69. LPCSTR CmdSave = LexCmdLine;
  70. again:
  71. while((TokenID = yyLex(&LexCmdLine, LexTab, LexEOT, LexWant, Args)) != TOK_END_OF_TOKENS)
  72. {
  73. if (!CmdPtr->NextLevel && (LexWant != LEX_WANT_CMD))
  74. {
  75. if ((LexWant & 0xfff)  == TokenID)
  76. break;
  77. if ((CmdPtr->CommandID != TOK_INVALID) && ((CmdPtr)->TokenID == (++CmdPtr)->TokenID))
  78. {
  79. LexEOT = CmdPtr->LexTokenDelim;
  80. LexWant = CmdPtr->LexWhatWeWant;
  81. CmdID = CmdPtr->CommandID;
  82. LexCmdLine = CmdSave;
  83. goto again;
  84. }
  85. return CMD_UNKNOWN_PARAMETER;
  86. }
  87. if (level)
  88. {
  89. if (!CmdPtr->NextLevel)
  90. return CMD_UNKNOWN_PARAMETER;
  91. CmdPtr = CmdPtr->NextLevel;
  92. }
  93. for(;LexWant == LEX_WANT_CMD;)
  94. {
  95. if (CmdPtr->TokenID == TokenID)
  96. break;
  97. ++CmdPtr;
  98. if (CmdPtr->TokenID == TOK_INVALID)
  99. return level ? CMD_UNKNOWN_PARAMETER : CMD_UNKNOWN_COMMAND;
  100. }
  101. LexEOT = CmdPtr->LexTokenDelim;
  102. LexWant = CmdPtr->LexWhatWeWant;
  103. CmdID = CmdPtr->CommandID;
  104. ++level;
  105. CmdSave = LexCmdLine;
  106. if (CmdPtr->Flags & CMDF_PARAMETER)
  107. {
  108. if (!*LexCmdLine)
  109. return CMD_MISSING_PARAMETER;
  110. }
  111. if (CmdPtr->Flags & CMDF_NOPARAM)
  112. {
  113. if (*LexCmdLine)
  114. return CMD_UNKNOWN_PARAMETER;
  115. }
  116. if (CmdPtr->Flags & CMDF_NOT_IMPLEMENTED)
  117. return CMD_NOT_IMPLEMENTED;
  118. }
  119. return CmdID;
  120. }
  121. int CCommandParser::yyLex(LPCSTR *CmdLine, STokenTab *LexTab, int LexEOT, int Want, CCmdArgs& Args)
  122. {
  123. LPCSTR TokenStart = *CmdLine;
  124. LPCSTR Token = *CmdLine;
  125. int Len = 0, Digits = 0;
  126. char buf[16]; // To store numerical values in args
  127. int LexEOTsave = LexEOT;
  128. BOOL ParseQuotes = FALSE;
  129. BOOL IsParsingQuotes = FALSE;
  130. if (Want & LEX_PARSE_QUOTES)
  131. {
  132. Want &= ~LEX_PARSE_QUOTES;
  133. ParseQuotes = TRUE;
  134. }
  135. // Find the token (like strtok())
  136. while(*Token && (*Token != LexEOT))
  137. {
  138. if (Want == LEX_WANT_STRING)
  139. {
  140. if (ParseQuotes && (*Token == '"'))
  141. {
  142. if (!Len)
  143. {
  144. // Intro " ..
  145. LexEOT = 0;
  146. IsParsingQuotes = TRUE;
  147. }
  148. else if (IsParsingQuotes)
  149. {
  150. // Trailing " ..
  151. ++Token;
  152. ++Len;
  153. LexEOT = LexEOTsave;
  154. break;
  155. }
  156. }
  157. }
  158. if (((Token == *CmdLine) && (*Token == '-')) || isdigit(*Token))
  159. ++Digits;
  160. ++Len;
  161. ++Token;
  162. }
  163. // Skip to next token
  164. while(*Token && (*Token == LexEOT))
  165. Token++;
  166. // Set the restart marker to next token
  167. *CmdLine = Token;
  168. if (!Len)
  169. return TOK_END_OF_TOKENS;
  170. // Now, let's look at what we've got...
  171. switch(Want)
  172. {
  173. case LEX_WANT_CMD:
  174. while(LexTab->TokenID != TOK_INVALID)
  175. {
  176. if ((strlen(LexTab->Token) == (size_t)Len) && !strnicmp(LexTab->Token, TokenStart, Len))
  177. break;
  178. ++LexTab;
  179. }
  180. Args.AddArg(TokenStart, Len);
  181. return LexTab->TokenID;
  182. break;
  183. case LEX_WANT_STRING:
  184. // We have something, so let's just say it's a string...
  185. if (IsParsingQuotes)
  186. Args.AddArg(TokenStart + 1, Len - 2);
  187. else
  188. Args.AddArg(TokenStart, Len);
  189. return TOK_STRING;
  190. break;
  191. case LEX_WANT_BOOL:
  192. if (!strnicmp("TRUE", TokenStart, 4))
  193. {
  194. Args.AddArg(itoa(1,buf,10), Len);
  195. return TOK_BOOL;
  196. }
  197. if (!strnicmp("FALSE", TokenStart, 5))
  198. {
  199. Args.AddArg(itoa(0,buf,10), Len);
  200. return TOK_BOOL;
  201. }
  202. break;
  203. case LEX_WANT_INT:
  204. if (Digits == Len)
  205. {
  206. Args.AddArg(TokenStart, Len);
  207. return TOK_INT;
  208. }
  209. //return TOK_STRING;
  210. break;
  211. case LEX_WANT_CHAR:
  212. if (Len == 1)
  213. {
  214. Args.AddArg(TokenStart,1);
  215. return TOK_CHAR;
  216. }
  217. }
  218. return TOK_INVALID;
  219. }