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

  1. // $Id: Parser.java,v 1.4 1999/11/04 14:02:18 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, 1999, 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 exprprs implements exprsym
  9. {
  10.     final static int STACK_INCREMENT = 128;
  11.  
  12.     LexStream lex_stream;
  13.  
  14.     exprhdr actions = new exprhdr(this);
  15.  
  16.     int state_stack_top,
  17.         stack[],
  18.         location_stack[];
  19.     Ast 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(Ast ast) is a function that allows us to assign an AST
  41.     // tree to SYM(1).
  42.     //
  43.     final Ast SYM(int i) { return parse_stack[state_stack_top + (i - 1)]; }
  44.     final void setSYM1(Ast ast) { parse_stack[state_stack_top] = ast; }
  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.     Parser(LexStream lex_stream)
  54.     {
  55.         this.lex_stream = lex_stream;
  56.     }
  57.  
  58.     void reallocate_stacks()
  59.     {
  60.         int old_stack[] = stack; 
  61.         stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
  62.         if (old_stack != null)
  63.             System.arraycopy(old_stack, 0, stack, 0, old_stack.length);
  64.  
  65.         old_stack = location_stack; 
  66.         location_stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
  67.         if (old_stack != null)
  68.             System.arraycopy(old_stack, 0, location_stack, 0, old_stack.length);
  69.  
  70.         Ast old_parse_stack[] = parse_stack; 
  71.         parse_stack = new Ast[(old_parse_stack == null ? 0 : old_parse_stack.length) + STACK_INCREMENT];
  72.         if (old_parse_stack != null)
  73.             System.arraycopy(old_parse_stack, 0, parse_stack, 0, old_parse_stack.length);
  74.  
  75.         return;
  76.     }
  77.  
  78.     Ast parse()
  79.     {
  80.         lex_stream.Reset();
  81.         int curtok = lex_stream.Gettoken(),
  82.             act = START_STATE,
  83.             current_kind = lex_stream.Kind(curtok);
  84.  
  85.     /*****************************************************************/
  86.     /* Start parsing.                                                */
  87.     /*****************************************************************/
  88.         state_stack_top = -1;
  89.  
  90.         ProcessTerminals: for (;;)
  91.         {
  92.             if (++state_stack_top >= (stack == null ? 0 : stack.length))
  93.                 reallocate_stacks();
  94.  
  95.             stack[state_stack_top] = act;
  96.  
  97.             location_stack[state_stack_top] = curtok;
  98.  
  99.             act = t_action(act, current_kind, lex_stream);
  100.  
  101.             if (act <= NUM_RULES)
  102.                 state_stack_top--; // make reduction look like a shift-reduce
  103.             else if (act > ERROR_ACTION)
  104.             {
  105.                 token_action(curtok);
  106.                 curtok = lex_stream.Gettoken();
  107.                 current_kind = lex_stream.Kind(curtok);
  108.  
  109.                 act -= ERROR_ACTION;
  110.             }
  111.             else if (act < ACCEPT_ACTION)
  112.             {
  113.                 token_action(curtok);
  114.                 curtok = lex_stream.Gettoken();
  115.                 current_kind = lex_stream.Kind(curtok);
  116.  
  117.                 continue ProcessTerminals;
  118.             }
  119.             else break ProcessTerminals;
  120.  
  121.             ProcessNonTerminals: do
  122.             {
  123.                 state_stack_top -= (rhs[act] - 1);
  124.                 actions.rule_action[act].action();
  125.                 act = nt_action(stack[state_stack_top], lhs[act]);
  126.             } while(act <= NUM_RULES);
  127.         }
  128.  
  129.         if (act == ERROR_ACTION)
  130.         {
  131.             //
  132.             // Recover or Scream or Whatever !!!
  133.             //
  134.             System.out.println("Error detected on token " + curtok);
  135.             return null;
  136.         }
  137.  
  138.         return parse_stack[0];
  139.     }
  140. }
  141.