111
|
1 // parse.h -- Go frontend parser. -*- C++ -*-
|
|
2
|
|
3 // Copyright 2009 The Go Authors. All rights reserved.
|
|
4 // Use of this source code is governed by a BSD-style
|
|
5 // license that can be found in the LICENSE file.
|
|
6
|
|
7 #ifndef GO_PARSE_H
|
|
8 #define GO_PARSE_H
|
|
9
|
|
10 class Lex;
|
|
11 class Gogo;
|
|
12 class Named_object;
|
|
13 class Type;
|
|
14 class Typed_identifier;
|
|
15 class Typed_identifier_list;
|
|
16 class Channel_type;
|
|
17 class Function_type;
|
|
18 class Block;
|
|
19 class Expression;
|
|
20 class Expression_list;
|
|
21 class Struct_field_list;
|
|
22 class Case_clauses;
|
|
23 class Type_case_clauses;
|
|
24 class Select_clauses;
|
|
25 class Statement;
|
|
26 class Label;
|
|
27
|
|
28 // Parse the program.
|
|
29
|
|
30 class Parse
|
|
31 {
|
|
32 public:
|
|
33 Parse(Lex*, Gogo*);
|
|
34
|
|
35 // Parse a program.
|
|
36 void
|
|
37 program();
|
|
38
|
|
39 private:
|
|
40 // Precedence values.
|
|
41 enum Precedence
|
|
42 {
|
|
43 PRECEDENCE_INVALID = -1,
|
|
44 PRECEDENCE_NORMAL = 0,
|
|
45 PRECEDENCE_OROR,
|
|
46 PRECEDENCE_ANDAND,
|
|
47 PRECEDENCE_RELOP,
|
|
48 PRECEDENCE_ADDOP,
|
|
49 PRECEDENCE_MULOP
|
|
50 };
|
|
51
|
|
52 // We use this when parsing the range clause of a for statement.
|
|
53 struct Range_clause
|
|
54 {
|
|
55 // Set to true if we found a range clause.
|
|
56 bool found;
|
|
57 // The index expression.
|
|
58 Expression* index;
|
|
59 // The value expression.
|
|
60 Expression* value;
|
|
61 // The range expression.
|
|
62 Expression* range;
|
|
63
|
|
64 Range_clause()
|
|
65 : found(false), index(NULL), value(NULL), range(NULL)
|
|
66 { }
|
|
67 };
|
|
68
|
|
69 // We use this when parsing the statement at the start of a switch,
|
|
70 // in order to recognize type switches.
|
|
71 struct Type_switch
|
|
72 {
|
|
73 // Set to true if we find a type switch.
|
|
74 bool found;
|
|
75 // The variable name.
|
|
76 std::string name;
|
|
77 // The location of the variable.
|
|
78 Location location;
|
|
79 // The expression.
|
|
80 Expression* expr;
|
|
81
|
|
82 Type_switch()
|
|
83 : found(false), name(), location(Linemap::unknown_location()),
|
|
84 expr(NULL)
|
|
85 { }
|
|
86 };
|
|
87
|
|
88 // A variable defined in an enclosing function referenced by the
|
|
89 // current function.
|
|
90 class Enclosing_var
|
|
91 {
|
|
92 public:
|
|
93 Enclosing_var(Named_object* var, Named_object* in_function,
|
|
94 unsigned int index)
|
|
95 : var_(var), in_function_(in_function), index_(index)
|
|
96 { }
|
|
97
|
|
98 // We put these in a vector, so we need a default constructor.
|
|
99 Enclosing_var()
|
|
100 : var_(NULL), in_function_(NULL), index_(-1U)
|
|
101 { }
|
|
102
|
|
103 Named_object*
|
|
104 var() const
|
|
105 { return this->var_; }
|
|
106
|
|
107 Named_object*
|
|
108 in_function() const
|
|
109 { return this->in_function_; }
|
|
110
|
|
111 unsigned int
|
|
112 index() const
|
|
113 { return this->index_; }
|
|
114
|
|
115 private:
|
|
116 // The variable which is being referred to.
|
|
117 Named_object* var_;
|
|
118 // The function where the variable is defined.
|
|
119 Named_object* in_function_;
|
|
120 // The index of the field in this function's closure struct for
|
|
121 // this variable.
|
|
122 unsigned int index_;
|
|
123 };
|
|
124
|
|
125 // We store Enclosing_var entries in a set, so we need a comparator.
|
|
126 struct Enclosing_var_comparison
|
|
127 {
|
|
128 bool
|
131
|
129 operator()(const Enclosing_var&, const Enclosing_var&) const;
|
111
|
130 };
|
|
131
|
|
132 // A set of Enclosing_var entries.
|
|
133 typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
|
|
134
|
|
135 // Used to detect duplicate parameter/result names.
|
|
136 typedef std::map<std::string, const Typed_identifier*> Names;
|
|
137
|
|
138 // Peek at the current token from the lexer.
|
|
139 const Token*
|
|
140 peek_token();
|
|
141
|
|
142 // Consume the current token, return the next one.
|
|
143 const Token*
|
|
144 advance_token();
|
|
145
|
|
146 // Push a token back on the input stream.
|
|
147 void
|
|
148 unget_token(const Token&);
|
|
149
|
|
150 // The location of the current token.
|
|
151 Location
|
|
152 location();
|
|
153
|
|
154 // For break and continue we keep a stack of statements with
|
|
155 // associated labels (if any). The top of the stack is used for a
|
|
156 // break or continue statement with no label.
|
|
157 typedef std::vector<std::pair<Statement*, Label*> > Bc_stack;
|
|
158
|
|
159 // Parser nonterminals.
|
|
160 void identifier_list(Typed_identifier_list*);
|
|
161 Expression_list* expression_list(Expression*, bool may_be_sink,
|
|
162 bool may_be_composite_lit);
|
|
163 bool qualified_ident(std::string*, Named_object**);
|
|
164 Type* type();
|
|
165 bool type_may_start_here();
|
|
166 Type* type_name(bool issue_error);
|
|
167 Type* array_type(bool may_use_ellipsis);
|
|
168 Type* map_type();
|
|
169 Type* struct_type();
|
|
170 void field_decl(Struct_field_list*);
|
|
171 Type* pointer_type();
|
|
172 Type* channel_type();
|
|
173 void check_signature_names(const Typed_identifier_list*, Names*);
|
|
174 Function_type* signature(Typed_identifier*, Location);
|
|
175 bool parameters(Typed_identifier_list**, bool* is_varargs);
|
|
176 Typed_identifier_list* parameter_list(bool* is_varargs);
|
|
177 void parameter_decl(bool, Typed_identifier_list*, bool*, bool*, bool*);
|
|
178 bool result(Typed_identifier_list**);
|
|
179 Location block();
|
|
180 Type* interface_type(bool record);
|
|
181 void method_spec(Typed_identifier_list*);
|
|
182 void declaration();
|
|
183 bool declaration_may_start_here();
|
|
184 void decl(void (Parse::*)(void*, unsigned int), void*, unsigned int pragmas);
|
|
185 void list(void (Parse::*)(void*, unsigned int), void*, bool);
|
|
186 void const_decl();
|
131
|
187 void const_spec(int, Type**, Expression_list**);
|
111
|
188 void type_decl(unsigned int pragmas);
|
|
189 void type_spec(void*, unsigned int pragmas);
|
|
190 void var_decl();
|
|
191 void var_spec(void*, unsigned int pragmas);
|
|
192 void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
|
|
193 bool is_coloneq, Location);
|
|
194 bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
|
|
195 bool is_coloneq, Location);
|
|
196 bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
|
|
197 bool is_coloneq, Location);
|
|
198 bool init_vars_from_receive(const Typed_identifier_list*, Type*,
|
|
199 Expression*, bool is_coloneq, Location);
|
|
200 bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
|
|
201 Expression*, bool is_coloneq,
|
|
202 Location);
|
|
203 Named_object* init_var(const Typed_identifier&, Type*, Expression*,
|
|
204 bool is_coloneq, bool type_from_init, bool* is_new,
|
|
205 Expression_list* vars, Expression_list* vals);
|
|
206 Named_object* create_dummy_global(Type*, Expression*, Location);
|
|
207 void finish_init_vars(Expression_list* vars, Expression_list* vals,
|
|
208 Location);
|
|
209 void simple_var_decl_or_assignment(const std::string&, Location,
|
|
210 bool may_be_composite_lit,
|
|
211 Range_clause*, Type_switch*);
|
|
212 void function_decl(unsigned int pragmas);
|
|
213 Typed_identifier* receiver();
|
|
214 Expression* operand(bool may_be_sink, bool *is_parenthesized);
|
|
215 Expression* enclosing_var_reference(Named_object*, Named_object*,
|
|
216 bool may_be_sink, Location);
|
|
217 Expression* composite_lit(Type*, int depth, Location);
|
|
218 Expression* function_lit();
|
|
219 Expression* create_closure(Named_object* function, Enclosing_vars*,
|
|
220 Location);
|
|
221 Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
|
|
222 bool* is_type_switch, bool* is_parenthesized);
|
|
223 Expression* selector(Expression*, bool* is_type_switch);
|
|
224 Expression* index(Expression*);
|
|
225 Expression* call(Expression*);
|
|
226 Expression* expression(Precedence, bool may_be_sink,
|
|
227 bool may_be_composite_lit, bool* is_type_switch,
|
|
228 bool *is_parenthesized);
|
|
229 bool expression_may_start_here();
|
|
230 Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
|
|
231 bool* is_type_switch, bool* is_parenthesized);
|
|
232 Type* reassociate_chan_direction(Channel_type*, Location);
|
|
233 Expression* qualified_expr(Expression*, Location);
|
145
|
234 Expression* id_to_expression(const std::string&, Location, bool, bool);
|
111
|
235 void statement(Label*);
|
|
236 bool statement_may_start_here();
|
|
237 void labeled_stmt(const std::string&, Location);
|
|
238 Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
|
|
239 bool simple_stat_may_start_here();
|
|
240 void statement_list();
|
|
241 bool statement_list_may_start_here();
|
|
242 void expression_stat(Expression*);
|
|
243 void send_stmt(Expression*, bool may_be_composite_lit);
|
|
244 void inc_dec_stat(Expression*);
|
|
245 void assignment(Expression*, bool may_be_composite_lit, Range_clause*);
|
|
246 void tuple_assignment(Expression_list*, bool may_be_composite_lit,
|
|
247 Range_clause*);
|
|
248 void send();
|
|
249 void go_or_defer_stat();
|
|
250 void return_stat();
|
|
251 void if_stat();
|
|
252 void switch_stat(Label*);
|
|
253 Statement* expr_switch_body(Label*, Expression*, Location);
|
|
254 void expr_case_clause(Case_clauses*, bool* saw_default);
|
|
255 Expression_list* expr_switch_case(bool*);
|
|
256 Statement* type_switch_body(Label*, const Type_switch&, Location);
|
|
257 void type_case_clause(const std::string&, Expression*, Type_case_clauses*,
|
|
258 bool* saw_default, std::vector<Named_object*>*);
|
|
259 void type_switch_case(std::vector<Type*>*, bool*);
|
|
260 void select_stat(Label*);
|
|
261 void comm_clause(Select_clauses*, bool* saw_default);
|
|
262 bool comm_case(bool*, Expression**, Expression**, Expression**,
|
|
263 std::string*, std::string*, bool*);
|
|
264 bool send_or_recv_stmt(bool*, Expression**, Expression**, Expression**,
|
|
265 std::string*, std::string*);
|
|
266 void for_stat(Label*);
|
|
267 void for_clause(Expression**, Block**);
|
|
268 void range_clause_decl(const Typed_identifier_list*, Range_clause*);
|
|
269 void range_clause_expr(const Expression_list*, Range_clause*);
|
|
270 void push_break_statement(Statement*, Label*);
|
|
271 void push_continue_statement(Statement*, Label*);
|
|
272 void pop_break_statement();
|
|
273 void pop_continue_statement();
|
|
274 Statement* find_bc_statement(const Bc_stack*, const std::string&);
|
|
275 void break_stat();
|
|
276 void continue_stat();
|
|
277 void goto_stat();
|
|
278 void package_clause();
|
|
279 void import_decl();
|
|
280 void import_spec(void*, unsigned int pragmas);
|
|
281
|
|
282 // Skip past an error looking for a semicolon or OP. Return true if
|
|
283 // all is well, false if we found EOF.
|
|
284 bool
|
|
285 skip_past_error(Operator op);
|
|
286
|
|
287 // Verify that an expression is not a sink, and return either the
|
|
288 // expression or an error.
|
|
289 Expression*
|
|
290 verify_not_sink(Expression*);
|
|
291
|
|
292 // Return the statement associated with a label in a Bc_stack, or
|
|
293 // NULL.
|
|
294 Statement*
|
|
295 find_bc_statement(const Bc_stack*, const std::string&) const;
|
|
296
|
|
297 // Mark a variable as used.
|
|
298 void
|
|
299 mark_var_used(Named_object*);
|
|
300
|
|
301 // The lexer output we are parsing.
|
|
302 Lex* lex_;
|
|
303 // The current token.
|
|
304 Token token_;
|
|
305 // A token pushed back on the input stream.
|
|
306 Token unget_token_;
|
|
307 // Whether unget_token_ is valid.
|
|
308 bool unget_token_valid_;
|
|
309 // Whether the function we are parsing had errors in the signature.
|
|
310 bool is_erroneous_function_;
|
|
311 // The code we are generating.
|
|
312 Gogo* gogo_;
|
|
313 // A stack of statements for which break may be used.
|
|
314 Bc_stack* break_stack_;
|
|
315 // A stack of statements for which continue may be used.
|
|
316 Bc_stack* continue_stack_;
|
|
317 // References from the local function to variables defined in
|
|
318 // enclosing functions.
|
|
319 Enclosing_vars enclosing_vars_;
|
|
320 };
|
|
321
|
|
322
|
|
323 #endif // !defined(GO_PARSE_H)
|