1 // $Id: parser.h,v 1.28 2004/03/25 13:32:28 ericb Exp $ -*- c++ -*-
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 
10 #ifndef parser_INCLUDED
11 #define parser_INCLUDED
12 
13 #include "platform.h"
14 #include "lpginput.h"
15 
16 #ifdef HAVE_JIKES_NAMESPACE
17 namespace Jikes { // Open namespace Jikes block
18 #endif
19 
20 
21 class StoragePool;
22 class Ast;
23 class AstListNode;
24 class AstStatement;
25 class AstBlock;
26 class AstName;
27 class AstType;
28 class AstTypeArguments;
29 class AstTypeName;
30 class AstModifiers;
31 class AstPackageDeclaration;
32 class AstCompilationUnit;
33 class AstClassBody;
34 class AstTypeParameters;
35 class AstMethodBody;
36 
37 enum ParseErrorCode
38 {
39     ERROR_CODE,
40     BEFORE_CODE,
41     INSERTION_CODE,
42     INVALID_CODE,
43     SUBSTITUTION_CODE,
44     DELETION_CODE,
45     MERGE_CODE,
46     MISPLACED_CODE,
47     SCOPE_CODE,
48     MANUAL_CODE,
49     SECONDARY_CODE,
50     EOF_CODE
51 };
52 
53 struct PrimaryRepairInfo
54 {
55     ParseErrorCode code;
56 
57     int distance,
58         buffer_position,
59         misspell_index,
60         symbol;
61 };
62 
63 struct SecondaryRepairInfo
64 {
65     ParseErrorCode code;
66     int distance,
67         buffer_position,
68         stack_position,
69         num_deletions,
70         symbol;
71 
72     bool recovery_on_next_stack;
73 };
74 
75 class Parser : public javaprs_table
76 {
77 public:
78 
Parser()79     Parser() : ast_pool(NULL),
80                parse_header_only(false),
81                parse_package_header_only(false),
82                location_stack(NULL),
83                parse_stack(NULL),
84                stack_length(0),
85                stack(NULL),
86                temp_stack(NULL)
87     {
88         InitRuleAction();
89         return;
90     }
91 
~Parser()92     ~Parser()
93     {
94         delete [] stack;
95         delete [] location_stack;
96         delete [] parse_stack;
97         delete [] temp_stack;
98     }
99 
100     AstPackageDeclaration* PackageHeaderParse(LexStream*, StoragePool*);
101     AstCompilationUnit* HeaderParse(LexStream*, StoragePool* = NULL);
102     bool InitializerParse(LexStream*, AstClassBody*);
103     bool BodyParse(LexStream*, AstClassBody*);
104 
105 protected:
106     TokenObject buffer[BUFF_SIZE];
107     TokenObject end_token;
108 
109     Ast* HeaderParse();
110     bool Initializer(AstClassBody*);
111     bool Body(AstClassBody*);
112     AstMethodBody* ParseSegment(TokenObject);
113 
114 #define HEADERS
115 #include "javaact.h"
116 
117     void (Parser::*rule_action[NUM_RULES + 1]) ();
118 
119     void InitRuleAction();
120 
121     //********************************************************************
122     //
123     // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
124     //
125     // the function Token(i) yields the symbol xi, if xi is a terminal
126     // or ti, if xi is a nonterminal that produced a string of the form
127     // xi => ti w.
128     //
129     //********************************************************************
Token(int i)130     inline TokenIndex Token(int i)
131     {
132         return location_stack[state_stack_top + (i - 1)];
133     }
134 
135     //********************************************************************
136     //
137     // Given a rule of the form     A ::= x1 x2 ... xn     n > 0
138     //
139     // the function Sym(i) yields the AST subtree associated with symbol
140     // xi. NOTE that if xi is a terminal, Sym(i) is undefined !
141     //
142     //********************************************************************
Sym(int i)143     inline Ast*& Sym(int i) { return parse_stack[state_stack_top + (i - 1)]; }
144 
145     //********************************************************************
146     //
147     // When a token is shifted, we also construct a null AST for
148     // it.  This is necessary in case we encounter an error and need to
149     // delete AST subtrees from the parse stack - those corresponding to
150     // shifted tokens should also have a valid subtree.
151     //
152     //********************************************************************
TokenAction(TokenObject)153     inline void TokenAction(TokenObject) { Sym(1) = NULL; }
154 
155     LexStream* lex_stream;
156 
157     StoragePool* ast_pool;
158     StoragePool* body_pool;
159     StoragePool* list_node_pool;
160 
161     AstListNode* free_list_nodes;
162     AstListNode* AllocateListNode();
163     void FreeCircularList(AstListNode*);
164 
165     bool parse_header_only,
166          parse_package_header_only;
167 
168     //
169     // LOCATION_STACK is a stack that is "parallel" to
170     // (STATE_)STACK that is used to keep
171     // track of the location of the first token on which an action
172     // was executed in the corresponding state.
173     //
174     Location* location_stack;
175     Ast** parse_stack;
176 
177     enum { STACK_INCREMENT = 256 };
178 
179     int stack_length;
180     int state_stack_top;
181     int* stack;
182 
183     int temp_stack_top;
184     int* temp_stack;
185 
Min(int x,int y)186     static inline int Min(int x, int y) { return x < y ? x : y; }
Max(int x,int y)187     static inline int Max(int x, int y) { return x > y ? x : y; }
188 
189     void AllocateErrorStacks();
190     void ReallocateStacks();
191     void ErrorRepair(TokenObject error_token);
192     void RepairParse(TokenObject);
193     SecondaryRepairInfo ErrorSurgery(int stack[],
194                                      int stack_top,
195                                      int last_index,
196                                      SecondaryRepairInfo repair);
197     int ParseCheck(int stack[], int stack_top, int first_token,
198                    int buffer_position);
199 };
200 
201 #ifdef HAVE_JIKES_NAMESPACE
202 } // Close namespace Jikes block
203 #endif
204 
205 #endif // parser_INCLUDED
206 
207