CharScanner.cpp
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:9k
源码类别:

编译器/解释器

开发平台:

Others

  1. /**
  2.  * <b>SOFTWARE RIGHTS</b>
  3.  * <p>
  4.  * ANTLR 2.6.0 MageLang Insitute, 1998
  5.  * <p>
  6.  * We reserve no legal rights to the ANTLR--it is fully in the
  7.  * public domain. An individual or company may do whatever
  8.  * they wish with source code distributed with ANTLR or the
  9.  * code generated by ANTLR, including the incorporation of
  10.  * ANTLR, or its output, into commerical software.
  11.  * <p>
  12.  * We encourage users to develop software with ANTLR. However,
  13.  * we do ask that credit is given to us for developing
  14.  * ANTLR. By "credit", we mean that if you use ANTLR or
  15.  * incorporate any source code into one of your programs
  16.  * (commercial product, research project, or otherwise) that
  17.  * you acknowledge this fact somewhere in the documentation,
  18.  * research report, etc... If you like ANTLR and have
  19.  * developed a nice tool with the output, please mention that
  20.  * you developed it using ANTLR. In addition, we ask that the
  21.  * headers remain intact in our source code. As long as these
  22.  * guidelines are kept, we expect to continue enhancing this
  23.  * system and expect to make other tools available as they are
  24.  * completed.
  25.  * <p>
  26.  * The ANTLR gang:
  27.  * @version ANTLR 2.6.0 MageLang Insitute, 1998
  28.  * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
  29.  * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
  30.  * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
  31.  */
  32. #include "antlr/CharScanner.hpp"
  33. #include "antlr/CommonToken.hpp"
  34. #include "antlr/MismatchedCharException.hpp"
  35. #include "antlr/TokenStream.hpp"
  36. #include <map>
  37. #ifdef HAS_NOT_CCTYPE_H
  38. #include <ctype.h>
  39. #else
  40. #include <cctype>
  41. #endif
  42. #include <iostream>
  43. #ifdef HAS_NOT_CSTRING_H
  44. #include <string>
  45. #else
  46. #include <cstring>
  47. #endif
  48. ANTLR_BEGIN_NAMESPACE(antlr)
  49. CharScannerLiteralsLess::CharScannerLiteralsLess(const CharScanner* theScanner)
  50. : scanner(theScanner)
  51. {}
  52. bool CharScannerLiteralsLess::operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const
  53. {
  54. if (scanner->getCaseSensitiveLiterals()) {
  55. return ANTLR_USE_NAMESPACE(std)less<ANTLR_USE_NAMESPACE(std)string>()(x,y);
  56. } else {
  57. #ifdef NO_STRCASECMP
  58. return (stricmp(x.c_str(),y.c_str())<0);
  59. #else
  60. return (strcasecmp(x.c_str(),y.c_str())<0);
  61. #endif
  62. }
  63. }
  64. CharScanner::CharScanner(InputBuffer& cb)
  65. : saveConsumedInput(true) //, caseSensitiveLiterals(true)
  66. , literals(CharScannerLiteralsLess(this))
  67. , inputState(new LexerInputState(cb))
  68. , commitToPath(false)
  69. {
  70. setTokenObjectFactory(&CommonToken::factory);
  71. }
  72. CharScanner::CharScanner(InputBuffer* cb)
  73. : saveConsumedInput(true) //, caseSensitiveLiterals(true)
  74. , literals(CharScannerLiteralsLess(this))
  75. , inputState(new LexerInputState(cb))
  76. , commitToPath(false)
  77. {
  78. setTokenObjectFactory(&CommonToken::factory);
  79. }
  80. CharScanner::CharScanner(const LexerSharedInputState& state)
  81. : saveConsumedInput(true) //, caseSensitiveLiterals(true)
  82. , literals(CharScannerLiteralsLess(this))
  83. , inputState(state)
  84. , commitToPath(false)
  85. {
  86. setTokenObjectFactory(&CommonToken::factory);
  87. }
  88. CharScanner::~CharScanner()
  89. {
  90. }
  91. void CharScanner::append(char c)
  92. {
  93. if (saveConsumedInput)
  94. text+=c;
  95. }
  96. void CharScanner::append(const ANTLR_USE_NAMESPACE(std)string& s)
  97. {
  98. if (saveConsumedInput)
  99. text+=s;
  100. }
  101. void CharScanner::commit()
  102. {
  103. inputState->getInput().commit();
  104. }
  105. void CharScanner::consume()
  106. {
  107. if (inputState->guessing == 0) {
  108. if (caseSensitive) {
  109. append(LA(1));
  110. } else {
  111. // use input.LA(), not LA(), to get original case
  112. // CharScanner.LA() would toLower it.
  113. append(inputState->getInput().LA(1));
  114. }
  115. }
  116. inputState->getInput().consume();
  117. }
  118. /** Consume chars until one matches the given char */
  119. void CharScanner::consumeUntil(int c)
  120. {
  121. while (LA(1) != EOF_CHAR && LA(1) != c)
  122. {
  123. consume();
  124. }
  125. }
  126. /** Consume chars until one matches the given set */
  127. void CharScanner::consumeUntil(const BitSet& set)
  128. {
  129. while (LA(1) != EOF_CHAR && !set.member(LA(1))) {
  130. consume();
  131. }
  132. }
  133. bool CharScanner::getCaseSensitive() const
  134. { return caseSensitive; }
  135. //bool CharScanner::getCaseSensitiveLiterals() const
  136. //{ return caseSensitiveLiterals; }
  137. int CharScanner::getColumn() const
  138. { return inputState->column; }
  139. bool CharScanner::getCommitToPath() const
  140. { return commitToPath; }
  141. const ANTLR_USE_NAMESPACE(std)string& CharScanner::getFilename() const
  142. { return inputState->filename; }
  143. InputBuffer& CharScanner::getInputBuffer()
  144. { return inputState->getInput(); }
  145. LexerSharedInputState CharScanner::getInputState()
  146. { return inputState; }
  147. int CharScanner::getLine() const
  148. { return inputState->line; }
  149. // return a copy of the current text buffer
  150. const ANTLR_USE_NAMESPACE(std)string& CharScanner::getText() const
  151. { return text; }
  152. RefToken CharScanner::getTokenObject() const
  153. { return _returnToken; }
  154. int CharScanner::LA(int i)
  155. {
  156. if ( caseSensitive ) {
  157. return inputState->getInput().LA(i);
  158. } else {
  159. return toLower(inputState->getInput().LA(i));
  160. }
  161. }
  162. RefToken CharScanner::makeToken(int t)
  163. {
  164. RefToken tok=tokenFactory();
  165. tok->setType(t);
  166. tok->setLine(inputState->line);
  167. return tok;
  168. }
  169. int CharScanner::mark()
  170. {
  171. return inputState->getInput().mark();
  172. }
  173. void CharScanner::match(int c)
  174. {
  175. if ( LA(1) != c ) {
  176. throw MismatchedCharException(LA(1),c,false,this);
  177. }
  178. consume();
  179. }
  180. void CharScanner::match(const BitSet& b)
  181. {
  182. if (!b.member(LA(1))) {
  183. throw MismatchedCharException(LA(1),b,false,this);
  184. }
  185. consume();
  186. }
  187. void CharScanner::match(const ANTLR_USE_NAMESPACE(std)string& s)
  188. {
  189. int len = s.length();
  190. for (int i=0; i<len; i++) {
  191. if ( LA(1) != s[i] ) {
  192. throw MismatchedCharException(LA(1),s[i],false,this);
  193. }
  194. consume();
  195. }
  196. }
  197. void CharScanner::matchNot(int c)
  198. {
  199. if ( LA(1) == c ) {
  200. throw MismatchedCharException(LA(1),c,true,this);
  201. }
  202. consume();
  203. }
  204. void CharScanner::matchRange(int c1, int c2)
  205. {
  206. if (LA(1)<c1 || LA(1)>c2) {
  207. throw MismatchedCharException(LA(1),c1,c2,false,this);
  208. }
  209. consume();
  210. }
  211. void CharScanner::newline()
  212. { ++inputState->line; }
  213. void CharScanner::panic()
  214. {
  215. ANTLR_USE_NAMESPACE(std)cerr << "CharScanner: panic" << ANTLR_USE_NAMESPACE(std)endl;
  216. exit(1);
  217. }
  218. void CharScanner::panic(const ANTLR_USE_NAMESPACE(std)string& s)
  219. {
  220. ANTLR_USE_NAMESPACE(std)cerr << "CharScanner: panic: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  221. exit(1);
  222. }
  223. /** Report exception errors caught in nextToken() */
  224. void CharScanner::reportError(const RecognitionException& ex)
  225. {
  226. ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl;
  227. }
  228. /** Parser error-reporting function can be overridden in subclass */
  229. void CharScanner::reportError(const ANTLR_USE_NAMESPACE(std)string& s)
  230. {
  231. if (getFilename() == "")
  232. ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  233. else
  234. ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  235. }
  236. /** Parser warning-reporting function can be overridden in subclass */
  237. void CharScanner::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s)
  238. {
  239. if (getFilename() == "")
  240. ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  241. else
  242. ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  243. }
  244. void CharScanner::resetText()
  245. { text=""; }
  246. void CharScanner::rewind(int pos)
  247. {
  248. inputState->getInput().rewind(pos);
  249. }
  250. void CharScanner::setCaseSensitive(bool t)
  251. {
  252. caseSensitive = t;
  253. }
  254. void CharScanner::setCommitToPath(bool commit)
  255. {
  256. commitToPath = commit;
  257. }
  258. void CharScanner::setFilename(const ANTLR_USE_NAMESPACE(std)string& f)
  259. { inputState->filename=f; }
  260. void CharScanner::setInputState(LexerSharedInputState state)
  261. { inputState = state; }
  262. void CharScanner::setLine(int l)
  263. { inputState->line=l; }
  264. void CharScanner::setText(const ANTLR_USE_NAMESPACE(std)string& s)
  265. { text=s; }
  266. void CharScanner::setTokenObjectFactory(factory_type factory)
  267. { tokenFactory=factory; }
  268. // Test the token text against the literals table
  269. // Override this method to perform a different literals test
  270. int CharScanner::testLiteralsTable(int ttype) const
  271. {
  272. ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(text);
  273. if (i != literals.end())
  274. ttype = (*i).second;
  275. return ttype;
  276. }
  277. // Test the text passed in against the literals table
  278. // Override this method to perform a different literals test
  279. // This is used primarily when you want to test a portion of
  280. // a token.
  281. int CharScanner::testLiteralsTable(const ANTLR_USE_NAMESPACE(std)string& text_, int ttype) const
  282. {
  283. ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(text_);
  284. if (i != literals.end())
  285. ttype = (*i).second;
  286. return ttype;
  287. }
  288. // Override this method to get more specific case handling
  289. char CharScanner::toLower(char c) const
  290. {
  291. return tolower(c);
  292. }
  293. void CharScanner::traceIn(const ANTLR_USE_NAMESPACE(std)string& rname)
  294. {
  295. ANTLR_USE_NAMESPACE(std)cout << "enter lexer " << rname.c_str() << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
  296. }
  297. void CharScanner::traceOut(const ANTLR_USE_NAMESPACE(std)string& rname)
  298. {
  299. ANTLR_USE_NAMESPACE(std)cout << "exit lexer " << rname.c_str() << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
  300. }
  301. void CharScanner::uponEOF()
  302. {
  303. }
  304. #ifndef NO_STATIC_CONSTS
  305. const int CharScanner::NO_CHAR;
  306. const int CharScanner::EOF_CHAR;
  307. #endif
  308. ANTLR_END_NAMESPACE