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 (145 lines) | stat: -rw-r--r-- 4,709 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
141
142
143
144
145
// $Id: Parser.java,v 1.3 1999/11/04 14:02:16 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, 1998, International Business Machines Corporation
// and others.  All Rights Reserved.
// You must accept the terms of that agreement to use this software.
class Parser extends bnfprs implements bnfsym
{
    final static int STACK_INCREMENT = 128;

    LexStream lex_stream;

    bnfhdr actions = new bnfhdr(this);

    int state_stack_top,
        stack[],
        location_stack[];
    int 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(int INFO) is a function that allows us to assign an info
    // to SYM(1).
    //
    final int SYM(int i) { return parse_stack[state_stack_top + (i - 1)]; }
    final void setSYM1(int info) { parse_stack[state_stack_top] = info; }

    //
    // 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)
    {
        setSYM1(0);
        System.out.println("Shifting token " + lex_stream.Name(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);

        int old_parse_stack[] = parse_stack; 
        parse_stack = new int[(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;
    }
 
    void 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;
        }

        System.out.println("Input parsed successfully");
        return;
    }
}