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

编译器/解释器

开发平台:

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/Parser.hpp"
  33. #include "antlr/BitSet.hpp"
  34. #include "antlr/TokenBuffer.hpp"
  35. #include "antlr/MismatchedTokenException.hpp"
  36. //#include "antlr/ASTFactory.hpp"
  37. #include <iostream>
  38. ANTLR_BEGIN_NAMESPACE(antlr)
  39. /**A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
  40.  * utility routines useful at any lookahead depth.  We distinguish between
  41.  * the LL(1) and LL(k) parsers because of efficiency.  This may not be
  42.  * necessary in the near future.
  43.  *
  44.  * Each parser object contains the state of the parse including a lookahead
  45.  * cache (the form of which is determined by the subclass), whether or
  46.  * not the parser is in guess mode, where tokens come from, etc...
  47.  *
  48.  * <p>
  49.  * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
  50.  * cache must be saved because the token stream may not have been informed
  51.  * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
  52.  * Guessing is started by:
  53.  * <ol>
  54.  * <li>saving the lookahead cache.
  55.  * <li>marking the current position in the TokenBuffer.
  56.  * <li>increasing the guessing level.
  57.  * </ol>
  58.  *
  59.  * After guessing, the parser state is restored by:
  60.  * <ol>
  61.  * <li>restoring the lookahead cache.
  62.  * <li>rewinding the TokenBuffer.
  63.  * <li>decreasing the guessing level.
  64.  * </ol>
  65.  *
  66.  * @see antlr.Token
  67.  * @see antlr.TokenBuffer
  68.  * @see antlr.TokenStream
  69.  * @see antlr.LL1Parser
  70.  * @see antlr.LLkParser
  71.  */
  72. bool DEBUG_PARSER=false;
  73. Parser::Parser(TokenBuffer& input)
  74. : inputState(new ParserInputState(input))
  75. {
  76. }
  77. Parser::Parser(TokenBuffer* input)
  78. : inputState(new ParserInputState(input))
  79. {
  80. }
  81. Parser::Parser(const ParserSharedInputState& state)
  82. : inputState(state)
  83. {
  84. }
  85. Parser::~Parser()
  86. {
  87. }
  88. void Parser::setTokenNames(const char** tokenNames_)
  89. {
  90. while (*tokenNames_) {
  91. tokenNames.push_back(*(tokenNames_++));
  92. }
  93. }
  94. /** Consume tokens until one matches the given token */
  95. void Parser::consumeUntil(int tokenType)
  96. {
  97. while (LA(1) != Token::EOF_TYPE && LA(1) != tokenType)
  98. consume();
  99. }
  100. /** Consume tokens until one matches the given token set */
  101. void Parser::consumeUntil(const BitSet& set)
  102. {
  103. while (LA(1) != Token::EOF_TYPE && !set.member(LA(1)))
  104. consume();
  105. }
  106. /** Get the AST return value squirreled away in the parser */
  107. RefAST Parser::getAST()
  108. {
  109. return returnAST;
  110. }
  111. ASTFactory& Parser::getASTFactory()
  112. {
  113. return astFactory;
  114. }
  115. ANTLR_USE_NAMESPACE(std)string Parser::getFilename() const
  116. {
  117. return inputState->filename;
  118. }
  119. ParserSharedInputState Parser::getInputState() const
  120. {
  121. return inputState;
  122. }
  123. ANTLR_USE_NAMESPACE(std)string Parser::getTokenName(int num) const
  124. {
  125. return tokenNames[num];
  126. }
  127. ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> Parser::getTokenNames() const
  128. {
  129. return tokenNames;
  130. }
  131. // Forwarded to TokenBuffer
  132. int Parser::mark()
  133. {
  134. return inputState->getInput().mark();
  135. }
  136. /**Make sure current lookahead symbol matches token type <tt>t</tt>.
  137.  * Throw an exception upon mismatch, which is catch by either the
  138.  * error handler or by the syntactic predicate.
  139.  */
  140. void Parser::match(int t)
  141. {
  142. if ( DEBUG_PARSER )
  143. ANTLR_USE_NAMESPACE(std)cout << "enter match(" << t << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
  144. if ( LA(1)!=t ) {
  145. if ( DEBUG_PARSER )
  146. ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << "!=" << t << ANTLR_USE_NAMESPACE(std)endl;
  147. throw MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
  148. } else {
  149. // mark token as consumed -- fetch next token deferred until LA/LT
  150. consume();
  151. }
  152. }
  153. /**Make sure current lookahead symbol matches the given set
  154.  * Throw an exception upon mismatch, which is catch by either the
  155.  * error handler or by the syntactic predicate.
  156.  */
  157. void Parser::match(const BitSet& b)
  158. {
  159. if ( DEBUG_PARSER )
  160. ANTLR_USE_NAMESPACE(std)cout << "enter match(" << "bitset" /*b.toString()*/
  161.   << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl;
  162. if ( !b.member(LA(1)) ) {
  163. if ( DEBUG_PARSER )
  164. ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << " not member of "
  165.   << "bitset" /*b.toString()*/ << ANTLR_USE_NAMESPACE(std)endl;
  166. throw MismatchedTokenException(tokenNames, LT(1), b, false, getFilename());
  167. } else {
  168. // mark token as consumed -- fetch next token deferred until LA/LT
  169. consume();
  170. }
  171. }
  172. void Parser::matchNot(int t)
  173. {
  174. if ( LA(1)==t ) {
  175. // Throws inverted-sense exception
  176. throw MismatchedTokenException(tokenNames, LT(1), t, true, getFilename());
  177. } else {
  178. // mark token as consumed -- fetch next token deferred until LA/LT
  179. consume();
  180. }
  181. }
  182. void Parser::panic()
  183. {
  184. ANTLR_USE_NAMESPACE(std)cerr << "Parser: panic" << ANTLR_USE_NAMESPACE(std)endl;
  185. exit(1);
  186. }
  187. /** Parser error-reporting function can be overridden in subclass */
  188. void Parser::reportError(const RecognitionException& ex)
  189. {
  190. ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl;
  191. }
  192. /** Parser error-reporting function can be overridden in subclass */
  193. void Parser::reportError(const ANTLR_USE_NAMESPACE(std)string& s)
  194. {
  195. if ( getFilename()=="" )
  196. ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  197. else
  198. ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  199. }
  200. /** Parser warning-reporting function can be overridden in subclass */
  201. void Parser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s)
  202. {
  203. if ( getFilename()=="" )
  204. ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  205. else
  206. ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl;
  207. }
  208. void Parser::rewind(int pos)
  209. {
  210. inputState->getInput().rewind(pos);
  211. }
  212. /** Set the object used to generate ASTs */
  213. // void setASTFactory(ASTFactory astFactory_);
  214. /** Specify the type of node to create during tree building */
  215. void Parser::setASTNodeFactory(ASTFactory::factory_type factory)
  216. {
  217. astFactory.setASTNodeFactory(factory);
  218. }
  219. void Parser::setFilename(const ANTLR_USE_NAMESPACE(std)string& f)
  220. {
  221. inputState->filename = f;
  222. }
  223. void Parser::setInputState(ParserSharedInputState state)
  224. {
  225. inputState = state;
  226. }
  227. /** Set or change the input token buffer */
  228. // void setTokenBuffer(TokenBuffer<Token>* t);
  229. void Parser::traceIn(const ANTLR_USE_NAMESPACE(std)string& rname)
  230. {
  231. ANTLR_USE_NAMESPACE(std)cout << "enter " << rname.c_str() << "; LA(1)==" << LT(1)->getText().c_str() <<
  232. ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl;
  233. }
  234. void Parser::traceOut(const ANTLR_USE_NAMESPACE(std)string& rname)
  235. {
  236. ANTLR_USE_NAMESPACE(std)cout << "exit " << rname.c_str() << "; LA(1)==" << LT(1)->getText().c_str() <<
  237. ((inputState->guessing>0)?" [guessing]":"") << ANTLR_USE_NAMESPACE(std)endl;
  238. }
  239. ANTLR_END_NAMESPACE