File: Parser.java

package info (click to toggle)
jikespg 1.3-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, jessie, jessie-kfreebsd, stretch
  • size: 1,736 kB
  • ctags: 1,478
  • sloc: ansic: 18,070; java: 586; makefile: 182
file content (140 lines) | stat: -rw-r--r-- 4,577 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// $Id: Parser.java,v 1.4 1999/11/04 14:02:18 shields Exp $
// This software is subject to the terms of the IBM Jikes Compiler
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1999, International Business Machines Corporation
// and others.  All Rights Reserved.
// You must accept the terms of that agreement to use this software.
class Parser extends exprprs implements exprsym
{
    final static int STACK_INCREMENT = 128;

    LexStream lex_stream;

    exprhdr actions = new exprhdr(this);

    int state_stack_top,
        stack[],
        location_stack[];
    Ast parse_stack[];

    //
    // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
    //
    // the function TOKEN(i) yields the symbol xi, if xi is a terminal
    // or ti, if xi is a nonterminal that produced a string of the form
    // xi => ti w.
    //
    final int TOKEN(int i)
    {
        return location_stack[state_stack_top + (i - 1)];
    }

    //
    // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
    //
    // The function SYM(i) yields the AST subtree associated with symbol
    // xi. NOTE that if xi is a terminal, SYM(i) is undefined ! (However,
    // see token_action below.)
    //
    // setSYM1(Ast ast) is a function that allows us to assign an AST
    // tree to SYM(1).
    //
    final Ast SYM(int i) { return parse_stack[state_stack_top + (i - 1)]; }
    final void setSYM1(Ast ast) { parse_stack[state_stack_top] = ast; }

    //
    // When a token is shifted, we may wish to perform an action on 
    // it. One possibility is to invoke "setSYM(null)" to associate
    // a null subtree with this terminal symbol.
    //
    void token_action(int tok) {}

    Parser(LexStream lex_stream)
    {
        this.lex_stream = lex_stream;
    }

    void reallocate_stacks()
    {
        int old_stack[] = stack; 
        stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
        if (old_stack != null)
            System.arraycopy(old_stack, 0, stack, 0, old_stack.length);

        old_stack = location_stack; 
        location_stack = new int[(old_stack == null ? 0 : old_stack.length) + STACK_INCREMENT];
        if (old_stack != null)
            System.arraycopy(old_stack, 0, location_stack, 0, old_stack.length);

        Ast old_parse_stack[] = parse_stack; 
        parse_stack = new Ast[(old_parse_stack == null ? 0 : old_parse_stack.length) + STACK_INCREMENT];
        if (old_parse_stack != null)
            System.arraycopy(old_parse_stack, 0, parse_stack, 0, old_parse_stack.length);

        return;
    }
 
    Ast parse()
    {
        lex_stream.Reset();
        int curtok = lex_stream.Gettoken(),
            act = START_STATE,
            current_kind = lex_stream.Kind(curtok);
 
    /*****************************************************************/
    /* Start parsing.                                                */
    /*****************************************************************/
        state_stack_top = -1;

        ProcessTerminals: for (;;)
        {
            if (++state_stack_top >= (stack == null ? 0 : stack.length))
                reallocate_stacks();
 
            stack[state_stack_top] = act;

            location_stack[state_stack_top] = curtok;

            act = t_action(act, current_kind, lex_stream);
 
            if (act <= NUM_RULES)
                state_stack_top--; // make reduction look like a shift-reduce
            else if (act > ERROR_ACTION)
            {
                token_action(curtok);
                curtok = lex_stream.Gettoken();
                current_kind = lex_stream.Kind(curtok);

                act -= ERROR_ACTION;
            }
            else if (act < ACCEPT_ACTION)
            {
                token_action(curtok);
                curtok = lex_stream.Gettoken();
                current_kind = lex_stream.Kind(curtok);

                continue ProcessTerminals;
            }
            else break ProcessTerminals;

            ProcessNonTerminals: do
            {
                state_stack_top -= (rhs[act] - 1);
                actions.rule_action[act].action();
                act = nt_action(stack[state_stack_top], lhs[act]);
            } while(act <= NUM_RULES);
        }

        if (act == ERROR_ACTION)
        {
            //
            // Recover or Scream or Whatever !!!
            //
            System.out.println("Error detected on token " + curtok);
            return null;
        }

        return parse_stack[0];
    }
}