home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / jikepg12.zip / jikespg / examples / bnf / Parser.java < prev    next >
Encoding:
Text File  |  1999-11-04  |  4.7 KB  |  146 lines

  1. // $Id: Parser.java,v 1.3 1999/11/04 14:02:16 shields Exp $
  2. // This software is subject to the terms of the IBM Jikes Compiler
  3. // License Agreement available at the following URL:
  4. // http://www.ibm.com/research/jikes.
  5. // Copyright (C) 1996, 1998, International Business Machines Corporation
  6. // and others.  All Rights Reserved.
  7. // You must accept the terms of that agreement to use this software.
  8. class Parser extends bnfprs implements bnfsym
  9. {
  10.     final static int STACK_INCREMENT = 128;
  11.  
  12.     LexStream lex_stream;
  13.  
  14.     bnfhdr actions = new bnfhdr(this);
  15.  
  16.     int state_stack_top,
  17.         stack[],
  18.         location_stack[];
  19.     int parse_stack[];
  20.  
  21.     //
  22.     // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
  23.     //
  24.     // the function TOKEN(i) yields the symbol xi, if xi is a terminal
  25.     // or ti, if xi is a nonterminal that produced a string of the form
  26.     // xi => ti w.
  27.     //
  28.     final int TOKEN(int i)
  29.     {
  30.         return location_stack[state_stack_top + (i - 1)];
  31.     }
  32.  
  33.     //
  34.     // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
  35.     //
  36.     // The function SYM(i) yields the AST subtree associated with symbol
  37.     // xi. NOTE that if xi is a terminal, SYM(i) is undefined ! (However,
  38.     // see token_action below.)
  39.     //
  40.     // setSYM1(int INFO) is a function that allows us to assign an info
  41.     // to SYM(1).
  42.     //
  43.     final int SYM(int i) { return parse_stack[state_stack_top + (i - 1)]; }
  44.     final void setSYM1(int info) { parse_stack[state_stack_top] = info; }
  45.  
  46.     //
  47.     // When a token is shifted, we may wish to perform an action on 
  48.     // it. One possibility is to invoke "setSYM(null)" to associate
  49.     // a null subtree with this terminal symbol.
  50.     //
  51.     void token_action(int tok)
  52.     {
  53.         setSYM1(0);
  54.         System.out.println("Shifting token " + lex_stream.Name(tok));
  55.     }
  56.  
  57.     Parser(LexStream lex_stream)
  58.     {
  59.         this.lex_stream = lex_stream;
  60.     }
  61.  
  62.     void reallocate_stacks()
  63.     {
  64.         int old_stack[] = stack; 
  65.         stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
  66.         if (old_stack != null)
  67.             System.arraycopy(old_stack, 0, stack, 0, old_stack.length);
  68.  
  69.         old_stack = location_stack; 
  70.         location_stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
  71.         if (old_stack != null)
  72.             System.arraycopy(old_stack, 0, location_stack, 0, old_stack.length);
  73.  
  74.         int old_parse_stack[] = parse_stack; 
  75.         parse_stack = new int[(old_parse_stack == null ? 0 : old_parse_stack.length) + STACK_INCREMENT];
  76.         if (old_parse_stack != null)
  77.             System.arraycopy(old_parse_stack, 0, parse_stack, 0, old_parse_stack.length);
  78.  
  79.         return;
  80.     }
  81.  
  82.     void parse()
  83.     {
  84.         lex_stream.Reset();
  85.         int curtok = lex_stream.Gettoken(),
  86.             act = START_STATE,
  87.             current_kind = lex_stream.Kind(curtok);
  88.  
  89.     /*****************************************************************/
  90.     /* Start parsing.                                                */
  91.     /*****************************************************************/
  92.         state_stack_top = -1;
  93.  
  94.         ProcessTerminals: for (;;)
  95.         {
  96.             if (++state_stack_top >= (stack == null ? 0 : stack.length))
  97.                 reallocate_stacks();
  98.  
  99.             stack[state_stack_top] = act;
  100.  
  101.             location_stack[state_stack_top] = curtok;
  102.  
  103.             act = t_action(act, current_kind, lex_stream);
  104.  
  105.             if (act <= NUM_RULES)
  106.                 state_stack_top--; // make reduction look like a shift-reduce
  107.             else if (act > ERROR_ACTION)
  108.             {
  109.                 token_action(curtok);
  110.                 curtok = lex_stream.Gettoken();
  111.                 current_kind = lex_stream.Kind(curtok);
  112.  
  113.                 act -= ERROR_ACTION;
  114.             }
  115.             else if (act < ACCEPT_ACTION)
  116.             {
  117.                 token_action(curtok);
  118.                 curtok = lex_stream.Gettoken();
  119.                 current_kind = lex_stream.Kind(curtok);
  120.  
  121.                 continue ProcessTerminals;
  122.             }
  123.             else break ProcessTerminals;
  124.  
  125.             ProcessNonTerminals: do
  126.             {
  127.                 state_stack_top -= (rhs[act] - 1);
  128.                 actions.rule_action[act].action();
  129.                 act = nt_action(stack[state_stack_top], lhs[act]);
  130.             } while(act <= NUM_RULES);
  131.         }
  132.  
  133.         if (act == ERROR_ACTION)
  134.         {
  135.             //
  136.             // Recover or Scream or Whatever !!!
  137.             //
  138.             System.out.println("Error detected on token " + curtok);
  139.             return;
  140.         }
  141.  
  142.         System.out.println("Input parsed successfully");
  143.         return;
  144.     }
  145. }
  146.