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

编译器/解释器

开发平台:

Others

  1. package antlr;
  2. /* ANTLR Translator Generator
  3.  * Project led by Terence Parr at http://www.jGuru.com
  4.  * Software rights: http://www.antlr.org/RIGHTS.html
  5.  *
  6.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/Parser.java#1 $
  7.  */
  8. import antlr.collections.impl.BitSet;
  9. import antlr.collections.AST;
  10. import antlr.collections.impl.ASTArray;
  11. /**A generic ANTLR parser (LL(k) for k>=1) containing a bunch of
  12.  * utility routines useful at any lookahead depth.  We distinguish between
  13.  * the LL(1) and LL(k) parsers because of efficiency.  This may not be
  14.  * necessary in the near future.
  15.  *
  16.  * Each parser object contains the state of the parse including a lookahead
  17.  * cache (the form of which is determined by the subclass), whether or
  18.  * not the parser is in guess mode, where tokens come from, etc...
  19.  *
  20.  * <p>
  21.  * During <b>guess</b> mode, the current lookahead token(s) and token type(s)
  22.  * cache must be saved because the token stream may not have been informed
  23.  * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block.
  24.  * Guessing is started by:
  25.  * <ol>
  26.  * <li>saving the lookahead cache.
  27.  * <li>marking the current position in the TokenBuffer.
  28.  * <li>increasing the guessing level.
  29.  * </ol>
  30.  *
  31.  * After guessing, the parser state is restored by:
  32.  * <ol>
  33.  * <li>restoring the lookahead cache.
  34.  * <li>rewinding the TokenBuffer.
  35.  * <li>decreasing the guessing level.
  36.  * </ol>
  37.  *
  38.  * @see antlr.Token
  39.  * @see antlr.TokenBuffer
  40.  * @see antlr.Tokenizer
  41.  * @see antlr.LL1Parser
  42.  * @see antlr.LLkParser
  43.  */
  44. import java.io.IOException;
  45. import antlr.debug.MessageListener;
  46. import antlr.debug.ParserListener;
  47. import antlr.debug.ParserMatchListener;
  48. import antlr.debug.ParserTokenListener;
  49. import antlr.debug.SemanticPredicateListener;
  50. import antlr.debug.SyntacticPredicateListener;
  51. import antlr.debug.TraceListener;
  52. public abstract class Parser {
  53.     protected ParserSharedInputState inputState;
  54. /** Nesting level of registered handlers */
  55. // protected int exceptionLevel = 0;
  56.     /** Table of token type to token names */
  57.     protected String[] tokenNames;
  58.     /** AST return value for a rule is squirreled away here */
  59.     protected AST returnAST;
  60.     /** AST support code; parser and treeparser delegate to this object */
  61.     protected ASTFactory astFactory = new ASTFactory();
  62.     private boolean ignoreInvalidDebugCalls = false;
  63.     public Parser() {
  64. inputState = new ParserSharedInputState();
  65.     }
  66.     public Parser(ParserSharedInputState state) {
  67. inputState = state;
  68.     }
  69.     public void addMessageListener(MessageListener l) {
  70. if (!ignoreInvalidDebugCalls)
  71.     throw new IllegalArgumentException("addMessageListener() is only valid if parser built for debugging");
  72.     }
  73.     public void addParserListener(ParserListener l) {
  74. if (!ignoreInvalidDebugCalls)
  75.     throw new IllegalArgumentException("addParserListener() is only valid if parser built for debugging");
  76.     }
  77.     public void addParserMatchListener(ParserMatchListener l) {
  78. if (!ignoreInvalidDebugCalls)
  79.     throw new IllegalArgumentException("addParserMatchListener() is only valid if parser built for debugging");
  80.     }
  81.     public void addParserTokenListener(ParserTokenListener l) {
  82. if (!ignoreInvalidDebugCalls)
  83.     throw new IllegalArgumentException("addParserTokenListener() is only valid if parser built for debugging");
  84.     }
  85.     public void addSemanticPredicateListener(SemanticPredicateListener l) {
  86. if (!ignoreInvalidDebugCalls)
  87.     throw new IllegalArgumentException("addSemanticPredicateListener() is only valid if parser built for debugging");
  88.     }
  89.     public void addSyntacticPredicateListener(SyntacticPredicateListener l) {
  90. if (!ignoreInvalidDebugCalls)
  91.     throw new IllegalArgumentException("addSyntacticPredicateListener() is only valid if parser built for debugging");
  92.     }
  93.     public void addTraceListener(TraceListener l) {
  94. if (!ignoreInvalidDebugCalls)
  95.     throw new IllegalArgumentException("addTraceListener() is only valid if parser built for debugging");
  96.     }
  97.     /**Get another token object from the token stream */
  98.     public abstract void consume() throws TokenStreamException;
  99.     /** Consume tokens until one matches the given token */
  100.     public void consumeUntil(int tokenType) throws TokenStreamException {
  101. while (LA(1) != Token.EOF_TYPE && LA(1) != tokenType)
  102.     {
  103. consume();
  104.     }
  105.     }
  106.     /** Consume tokens until one matches the given token set */
  107.     public void consumeUntil(BitSet set) throws TokenStreamException {
  108. while (LA(1) != Token.EOF_TYPE && !set.member(LA(1))) {
  109.     consume();
  110. }
  111.     }
  112.     protected void defaultDebuggingSetup(TokenStream lexer, TokenBuffer tokBuf) {
  113. // by default, do nothing -- we're not debugging
  114.     }
  115.     /** Get the AST return value squirreled away in the parser */
  116.     public AST getAST() {
  117. return returnAST;
  118.     }
  119.     public ASTFactory getASTFactory() {
  120. return astFactory;
  121.     }
  122.     public String getFilename() {return inputState.filename;}
  123.     public ParserSharedInputState getInputState() {
  124. return inputState;
  125.     }
  126.     public void getInputState(ParserSharedInputState state) {
  127. inputState = state;
  128.     }
  129.     public String getTokenName(int num) {
  130. return tokenNames[num];
  131.     }
  132.     public String[] getTokenNames() {
  133. return tokenNames;
  134.     }
  135.     public boolean isDebugMode() {return false;}
  136.     /** Return the token type of the ith token of lookahead where i=1
  137.  * is the current token being examined by the parser (i.e., it
  138.  * has not been matched yet).
  139.  */
  140.     public abstract int LA(int i) throws TokenStreamException;
  141.     /**Return the ith token of lookahead */
  142.     public abstract Token LT(int i) throws TokenStreamException;
  143.     // Forwarded to TokenBuffer
  144.     public int mark() {
  145. return inputState.input.mark();
  146.     }
  147.     /**Make sure current lookahead symbol matches token type <tt>t</tt>.
  148.  * Throw an exception upon mismatch, which is catch by either the
  149.  * error handler or by the syntactic predicate.
  150.  */
  151.     public void match(int t) throws MismatchedTokenException, TokenStreamException {
  152. if ( LA(1)!=t )
  153.     throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
  154. else
  155.     // mark token as consumed -- fetch next token deferred until LA/LT
  156.     consume();
  157.     }
  158.     /**Make sure current lookahead symbol matches the given set
  159.  * Throw an exception upon mismatch, which is catch by either the
  160.  * error handler or by the syntactic predicate.
  161.  */
  162.     public void match(BitSet b) throws MismatchedTokenException, TokenStreamException {
  163. if ( !b.member(LA(1)) )
  164.     throw new MismatchedTokenException(tokenNames, LT(1), b, false, getFilename());
  165. else
  166.     // mark token as consumed -- fetch next token deferred until LA/LT
  167.     consume();
  168.     }
  169.     public void matchNot(int t) throws MismatchedTokenException, TokenStreamException {
  170. if ( LA(1)==t )
  171.     // Throws inverted-sense exception
  172.     throw new MismatchedTokenException(tokenNames, LT(1), t, true, getFilename());
  173. else
  174.     // mark token as consumed -- fetch next token deferred until LA/LT
  175.     consume();
  176.     }
  177.     public static void panic() {
  178. System.err.println("Parser: panic");
  179. System.exit(1);
  180.     }
  181.     public void removeMessageListener(MessageListener l) {
  182. if (!ignoreInvalidDebugCalls)
  183.     throw new RuntimeException("removeMessageListener() is only valid if parser built for debugging");
  184.     }
  185.     public void removeParserListener(ParserListener l) {
  186. if (!ignoreInvalidDebugCalls)
  187.     throw new RuntimeException("removeParserListener() is only valid if parser built for debugging");
  188.     }
  189.     public void removeParserMatchListener(ParserMatchListener l) {
  190. if (!ignoreInvalidDebugCalls)
  191.     throw new RuntimeException("removeParserMatchListener() is only valid if parser built for debugging");
  192.     }
  193.     public void removeParserTokenListener(ParserTokenListener l) {
  194. if (!ignoreInvalidDebugCalls)
  195.     throw new RuntimeException("removeParserTokenListener() is only valid if parser built for debugging");
  196.     }
  197.     public void removeSemanticPredicateListener(SemanticPredicateListener l) {
  198. if (!ignoreInvalidDebugCalls)
  199.     throw new IllegalArgumentException("removeSemanticPredicateListener() is only valid if parser built for debugging");
  200.     }
  201.     public void removeSyntacticPredicateListener(SyntacticPredicateListener l) {
  202. if (!ignoreInvalidDebugCalls)
  203.     throw new IllegalArgumentException("removeSyntacticPredicateListener() is only valid if parser built for debugging");
  204.     }
  205.     public void removeTraceListener(TraceListener l) {
  206. if (!ignoreInvalidDebugCalls)
  207.     throw new RuntimeException("removeTraceListener() is only valid if parser built for debugging");
  208.     }
  209.     /** Parser error-reporting function can be overridden in subclass */
  210.     public void reportError(RecognitionException ex) {
  211. System.err.println(ex);
  212.     }
  213.     /** Parser error-reporting function can be overridden in subclass */
  214.     public void reportError(String s) {
  215. if ( getFilename()==null ) {
  216.     System.err.println("error: " + s);
  217. }
  218. else {
  219.     System.err.println(getFilename()+": error: " + s);
  220. }
  221.     }
  222.     /** Parser warning-reporting function can be overridden in subclass */
  223.     public void reportWarning(String s) {
  224. if ( getFilename()==null ) {
  225.     System.err.println("warning: "+s);
  226. }
  227. else {
  228.     System.err.println(getFilename()+": warning: " + s);
  229. }
  230.     }
  231.     public void rewind(int pos) {
  232. inputState.input.rewind(pos);
  233.     }
  234.     /** Specify an object with support code (shared by
  235.  *  Parser and TreeParser.  Normally, the programmer
  236.  *  does not play with this, using setASTNodeType instead.
  237.  */
  238.     public void setASTFactory(ASTFactory f) {
  239. astFactory = f;
  240.     }
  241.     public void setASTNodeClass(String cl) {
  242. astFactory.setASTNodeType(cl);
  243.     }
  244.     /** Specify the type of node to create during tree building; use setASTNodeClass now
  245.  *  to be consistent with Token Object Type accessor.
  246.  */
  247.     public void setASTNodeType (String nodeType) {
  248. setASTNodeClass(nodeType);
  249.     }
  250.     public void setDebugMode(boolean debugMode) {
  251. if (!ignoreInvalidDebugCalls)
  252.     throw new RuntimeException("setDebugMode() only valid if parser built for debugging");
  253.     }
  254.     public void setFilename(String f) {inputState.filename=f;}
  255.     public void setIgnoreInvalidDebugCalls(boolean value) {
  256. ignoreInvalidDebugCalls = value;
  257.     }
  258.     /** Set or change the input token buffer */
  259.     public void setTokenBuffer(TokenBuffer t) { inputState.input = t; }
  260.     public void traceIn(String rname) throws TokenStreamException {
  261. System.out.println("enter "+rname+"; LA(1)=="+LT(1).getText()+
  262.    ((inputState.guessing>0)?" [guessing]":""));
  263.     }
  264.     public void traceOut(String rname) throws TokenStreamException {
  265. System.out.println("exit "+rname+"; LA(1)=="+LT(1).getText()+
  266.    ((inputState.guessing>0)?" [guessing]":""));
  267.     }
  268. }