File: Synopsis/Parser.hh
  1//
  2// Copyright (C) 1997 Shigeru Chiba
  3// Copyright (C) 2000 Stefan Seefeld
  4// All rights reserved.
  5// Licensed to the public under the terms of the GNU LGPL (>= 2),
  6// see the file COPYING for details.
  7//
  8#ifndef Synopsis_Parser_hh_
  9#define Synopsis_Parser_hh_
 10
 11#include <Synopsis/PTree.hh>
 12#include <Synopsis/SymbolFactory.hh>
 13#include <vector>
 14
 15namespace Synopsis
 16{
 17
 18class Lexer;
 19struct Token;
 20
 21//. C++ Parser
 22//.
 23//. This parser is a LL(k) parser with ad hoc rules such as
 24//. backtracking.
 25//.
 26//. <name>() is the grammer rule for a non-terminal <name>.
 27//. opt_<name>() is the grammer rule for an optional non-terminal <name>.
 28//. is_<name>() looks ahead and returns true if the next symbol is <name>.
 29class Parser
 30{
 31public:
 32  //. RuleSet defines non-standard optional rules that can be chosen at runtime.
 33  enum RuleSet { CXX = 0x01, GCC = 0x02, MSVC = 0x04};
 34
 35  //. Error is used to cache parse errors encountered during the execution
 36  //. of the parse method.
 37  class Error
 38  {
 39  public:
 40    virtual ~Error() {}
 41    virtual void write(std::ostream &) const = 0;
 42  };
 43  typedef std::vector<Error *> ErrorList;
 44
 45  Parser(Lexer &lexer, SymbolFactory &symbols, int ruleset = CXX|GCC);
 46  ~Parser();
 47
 48  ErrorList const &errors() const { return my_errors;}
 49
 50  //. Return the origin of the given pointer
 51  //. (filename and line number)
 52  unsigned long origin(const char *, std::string &) const;
 53
 54  PTree::Node *parse();
 55
 56private:
 57  enum DeclKind { kDeclarator, kArgDeclarator, kCastDeclarator };
 58  enum TemplateDeclKind { tdk_unknown, tdk_decl, tdk_instantiation, 
 59			  tdk_specialization, num_tdks };
 60
 61  struct ScopeGuard;
 62  friend struct ScopeGuard;
 63
 64  //. A StatusGuard manages a tentative parse.
 65  //. All actions invoked after its instantiation
 66  //. will be rolled back in the destructor unless
 67  //. 'commit' has been called before.
 68  class StatusGuard
 69  {
 70  public:
 71    StatusGuard(Parser &);
 72    ~StatusGuard();
 73    void commit() { my_committed = true;}
 74
 75  private:
 76    Lexer &                      my_lexer;
 77    char const *                 my_token_mark;
 78    ErrorList                    my_errors;
 79    Parser::ErrorList::size_type my_error_mark;
 80    bool                         my_committed;
 81  };
 82  friend class StatusGuard;
 83
 84
 85  bool mark_error();
 86  template <typename T>
 87  bool declare(T *);
 88  void show_message_head(const char*);
 89
 90  bool definition(PTree::Node *&);
 91  bool null_declaration(PTree::Node *&);
 92  bool typedef_(PTree::Typedef *&);
 93  bool type_specifier(PTree::Node *&, bool, PTree::Encoding&);
 94  bool is_type_specifier();
 95  bool metaclass_decl(PTree::Node *&);
 96  bool meta_arguments(PTree::Node *&);
 97  bool linkage_spec(PTree::Node *&);
 98  bool namespace_spec(PTree::NamespaceSpec *&);
 99  bool namespace_alias(PTree::NamespaceAlias *&);
100  bool using_directive(PTree::UsingDirective *&);
101  bool using_declaration(PTree::UsingDeclaration *&);
102  bool linkage_body(PTree::Node *&);
103  bool template_decl(PTree::Node *&);
104  bool template_decl2(PTree::TemplateDecl *&, TemplateDeclKind &kind);
105
106  //. template-parameter-list:
107  //.
108  //. - template-parameter
109  //. - template-parameter-list `,` template-parameter
110  bool template_parameter_list(PTree::List *&);
111
112  //. template-parameter:
113  //.
114  //. - type-parameter
115  //. - parameter-declaration
116  bool template_parameter(PTree::Node *&);
117
118  //. type-parameter:
119  //.
120  //. - class identifier [opt]
121  //. - class identifier [opt] `=` type-id
122  //. - typename identifier [opt]
123  //. - typename identifier [opt] `=` type-id
124  //. - template  `<` template-parameter-list `>` class identifier [opt]
125  //. - template  `<` template-parameter-list `>` class identifier [opt] `=` id-expression
126  bool type_parameter(PTree::Node *&);
127  
128  //. GNU extension:
129  //. extern-template-decl:
130  //.
131  //. - extern template declaration
132  bool extern_template_decl(PTree::Node *&);
133
134  bool declaration(PTree::Declaration *&);
135  bool integral_declaration(PTree::Declaration *&, PTree::Encoding&, PTree::Node *, PTree::Node *, PTree::Node *);
136  bool const_declaration(PTree::Declaration *&, PTree::Encoding&, PTree::Node *, PTree::Node *);
137  bool other_declaration(PTree::Declaration *&, PTree::Encoding&, PTree::Node *, PTree::Node *, PTree::Node *);
138
139  //. condition:
140  //.
141  //. - expression
142  //. - type-specifier-seq declarator `=` assignment-expression
143  bool condition(PTree::Node *&);
144
145  bool is_constructor_decl();
146  bool is_ptr_to_member(int);
147  bool opt_member_spec(PTree::Node *&);
148
149  //. storage-spec:
150  //.
151  //. - empty
152  //. - static
153  //. - extern
154  //. - auto
155  //. - register
156  //. - mutable
157  bool opt_storage_spec(PTree::Node *&);
158
159  //. cv-qualifier:
160  //.
161  //. - empty
162  //. - const
163  //. - volatile
164  bool opt_cv_qualifier(PTree::Node *&);
165  bool opt_integral_type_or_class_spec(PTree::Node *&, PTree::Encoding&);
166  bool constructor_decl(PTree::Node *&, PTree::Encoding&);
167  bool opt_throw_decl(PTree::Node *&);
168  
169  //. [gram.dcl.decl]
170  bool init_declarator_list(PTree::Node *&, PTree::Encoding&, bool, bool = false);
171  bool init_declarator(PTree::Node *&, PTree::Encoding&, bool, bool);
172  bool declarator(PTree::Node *&, DeclKind, bool,
173		  PTree::Encoding&, PTree::Encoding&, bool,
174		  bool = false);
175  bool declarator2(PTree::Node *&, DeclKind, bool,
176		   PTree::Encoding&, PTree::Encoding&, bool,
177		   bool, PTree::Node **);
178  bool opt_ptr_operator(PTree::Node *&, PTree::Encoding&);
179  bool member_initializers(PTree::Node *&);
180  bool member_init(PTree::Node *&);
181  
182  bool name(PTree::Node *&, PTree::Encoding&);
183  bool operator_name(PTree::Node *&, PTree::Encoding&);
184  bool cast_operator_name(PTree::Node *&, PTree::Encoding&);
185  bool ptr_to_member(PTree::Node *&, PTree::Encoding&);
186  bool template_args(PTree::Node *&, PTree::Encoding&);
187  
188  bool parameter_declaration_list_or_init(PTree::Node *&, bool&,
189					  PTree::Encoding&, bool);
190  bool parameter_declaration_list(PTree::Node *&, PTree::Encoding&);
191
192  //. parameter-declaration:
193  //.
194  //. - decl-specifier-seq declarator
195  //. - decl-specifier-seq declarator `=` assignment-expression
196  //. - decl-specifier-seq abstract-declarator [opt]
197  //. - decl-specifier-seq abstract-declarator [opt] `=` assignment-expression
198  bool parameter_declaration(PTree::ParameterDeclaration *&, PTree::Encoding&);
199  
200  bool function_arguments(PTree::Node *&);
201  bool designation(PTree::Node *&);
202  bool initialize_expr(PTree::Node *&);
203  
204  bool enum_spec(PTree::EnumSpec *&, PTree::Encoding&);
205  bool enum_body(PTree::Node *&);
206  bool class_spec(PTree::ClassSpec *&, PTree::Encoding&);
207
208  //. base-clause:
209  //.
210  //. - `:` base-specifier-list
211  //.
212  //. base-specifier-list:
213  //.
214  //. - base-specifier
215  //. - base-specifier-list `,` base-specifier
216  //.
217  //. base-specifier:
218  //.
219  //. - virtual access-specifier [opt] `::` [opt] nested-name-specifier [opt] class-name
220  //. - access-specifier virtual [opt] `::` [opt] nested-name-specifier [opt] class-name
221  bool base_clause(PTree::Node *&);
222  bool class_body(PTree::ClassBody *&);
223  bool class_member(PTree::Node *&);
224  bool access_decl(PTree::Node *&);
225  bool user_access_spec(PTree::Node *&);
226  
227  //. expression:
228  //.
229  //. - assignment-expression
230  //. - expression `,` assignment-expression
231  bool expression(PTree::Node *&);
232
233  //. assignment-expression:
234  //.
235  //. - conditional-expression
236  //. - logical-or-expression assignment-operator assignment-expression
237  //. - throw-expression
238  bool assign_expr(PTree::Node *&);
239
240  //. conditional-expression:
241  //.
242  //. - logical-or-expression
243  //. - logical-or-expression `?` expression `:` assignment-expression
244  bool conditional_expr(PTree::Node *&);
245
246  //. logical-or-expression:
247  //.
248  //. - logical-and-expression
249  //. - logical-or-expression `||` logical-and-expression
250  bool logical_or_expr(PTree::Node *&);
251
252  //. logical-and-expression:
253  //.
254  //. - inclusive-or-expression
255  //. - logical-and-expr `&&` inclusive-or-expression
256  bool logical_and_expr(PTree::Node *&);
257
258  //. inclusive-or-expression:
259  //.
260  //. - exclusive-or-expression
261  //. - inclusive-or-expression `|` exclusive-or-expression
262  bool inclusive_or_expr(PTree::Node *&);
263
264  //. exclusive-or-expression:
265  //.
266  //. - and-expression
267  //. - exclusive-or-expression `^` and-expression
268  bool exclusive_or_expr(PTree::Node *&);
269
270  //. and-expression:
271  //.
272  //. - equality-expression
273  //. - and-expression `&` equality-expression
274  bool and_expr(PTree::Node *&);
275
276  //. equality-expression:
277  //.
278  //. - relational-expression
279  //. - equality-expression `==` relational-expression
280  //. - equality-expression `!=` relational-expression
281  bool equality_expr(PTree::Node *&);
282
283  //. relational-expression:
284  //.
285  //. - shift-expression
286  //. - relational-expression `<` shift-expression
287  //. - relational-expression `>` shift-expression
288  //. - relational-expression `<=` shift-expression
289  //. - relational-expression `>=` shift-expression
290  bool relational_expr(PTree::Node *&);
291
292  //. shift-expression:
293  //.
294  //. - additive-expression
295  //. - shift-expression `<<` additive-expression
296  //. - shift-expression `>>` additive-expression
297  bool shift_expr(PTree::Node *&);
298
299  //. additive-expression:
300  //.
301  //. - multiplicative-expression
302  //. - additive-expression `+` multiplicative-expression
303  //. - additive-expression `-` multiplicative-expression
304  bool additive_expr(PTree::Node *&);
305
306  //. multiplicative-expression:
307  //.
308  //. - pm-expression
309  //. - multiplicative-expression `*` pm-expression
310  //. - multiplicative-expression `/` pm-expression
311  //. - multiplicative-expression `%` pm-expression
312  bool multiplicative_expr(PTree::Node *&);
313
314  //. pm-expression:
315  //.
316  //. - cast-expression
317  //. - pm-expression `.*` cast-expression
318  //. - pm-expression `->*` cast-expression
319  bool pm_expr(PTree::Node *&);
320
321  //. cast-expression:
322  //.
323  //. - unary-expression
324  //. - `(` type-id `)` cast-expression
325  bool cast_expr(PTree::Node *&);
326
327  //. type-id:
328  //.
329  //. - type-specifier-seq abstract-declarator [opt]
330  bool type_id(PTree::Node *&);
331  bool type_id(PTree::Node *&, PTree::Encoding&);
332
333  //. unary-expression:
334  //.
335  //. - postfix-expression
336  //. - `++` cast-expression
337  //. - `--` cast-expression
338  //. - unary-operator cast-expression
339  //. - `sizeof` unary-expression
340  //. - `sizeof` `(` unary-expression `)`
341  //. - new-expression
342  //. - delete-expression
343  //.
344  //. unary-operator:
345  //.
346  //. - `*`
347  //. - `&`
348  //. - `+`
349  //. - `-`
350  //. - `!`
351  //. - `~`
352  bool unary_expr(PTree::Node *&);
353
354  //. throw-expression:
355  //.
356  //. - `throw` assignment-expression
357  bool throw_expr(PTree::Node *&);
358
359  //. sizeof-expression:
360  //.
361  //. - `sizeof` unary-expression
362  //. - `sizeof` `(` type-id `)`
363  bool sizeof_expr(PTree::Node *&);
364
365  bool offsetof_expr(PTree::Node *&);
366
367  //. typeid-expression:
368  //.
369  //. - typeid `(` type-id `)`
370  //. - typeid `(` expression `)`
371  bool typeid_expr(PTree::Node *&);
372  bool is_allocate_expr(Token::Type);
373  bool allocate_expr(PTree::Node *&);
374  bool userdef_keyword(PTree::Node *&);
375  bool allocate_type(PTree::Node *&);
376  bool new_declarator(PTree::Declarator *&, PTree::Encoding&);
377  bool allocate_initializer(PTree::Node *&);
378  bool postfix_expr(PTree::Node *&);
379  bool primary_expr(PTree::Node *&);
380  bool typeof_expr(PTree::Node *&);
381  bool userdef_statement(PTree::Node *&);
382  bool var_name(PTree::Node *&);
383  bool var_name_core(PTree::Node *&, PTree::Encoding&);
384  bool is_template_args();
385  
386  //. function-body:
387  //.
388  //. - compound-statement
389  bool function_body(PTree::Block *&);
390
391  //. compound-statement:
392  //.
393  //. - `{` statement [opt] `}`
394  bool compound_statement(PTree::Block *&, bool create_scope = false);
395  bool statement(PTree::Node *&);
396
397  //. if-statement:
398  //.
399  //. - `if` `(` condition `)` statement
400  //. - `if` `(` condition `)` statement else statement
401  bool if_statement(PTree::Node *&);
402
403  //. switch-statement:
404  //.
405  //. - `switch` `(` condition `)` statement
406  bool switch_statement(PTree::Node *&);
407
408  //. while-statement:
409  //.
410  //. - `while` `(` condition `)` statement
411  bool while_statement(PTree::Node *&);
412
413  //. do-statement:
414  //.
415  //. - `do` statement `while` `(` condition `)` `;`
416  bool do_statement(PTree::Node *&);
417  bool for_statement(PTree::Node *&);
418
419  //. try-block:
420  //.
421  //. - `try` compound-statement handler-seq
422  //.
423  //. handler-seq:
424  //.
425  //. - handler handler-seq [opt]
426  //.
427  //. handler:
428  //.
429  //. - `catch` `(` exception-declaration `)` compound-statement
430  //.
431  //. exception-declaration:
432  //.
433  //. - type-specifier-seq declarator
434  //. - type-specifier-seq abstract-declarator
435  //. - type-specifier-seq
436  //. - `...`
437  bool try_block(PTree::Node *&);
438  
439  bool expr_statement(PTree::Node *&);
440  bool declaration_statement(PTree::Declaration *&);
441  bool integral_decl_statement(PTree::Declaration *&, PTree::Encoding&, PTree::Node *, PTree::Node *, PTree::Node *);
442  bool other_decl_statement(PTree::Declaration *&, PTree::Encoding&, PTree::Node *, PTree::Node *);
443
444  bool maybe_typename_or_class_template(Token&);
445  void skip_to(Token::Type token);
446  
447private:
448  bool more_var_name();
449
450  Lexer &         my_lexer;
451  int             my_ruleset;
452  SymbolFactory & my_symbols;
453  //. Record whether the current scope is valid.
454  //. This allows the parser to continue parsing even after
455  //. it was unable to enter a scope (such as in a function definition
456  //. with a qualified name that wasn't declared before).
457  bool            my_scope_is_valid;
458  ErrorList       my_errors;
459  PTree::Node *   my_comments;
460  //. If true, `>` is interpreted as ther greater-than operator.
461  //. If false, it marks the end of a template-id or template-parameter-list.
462  bool            my_gt_is_operator;
463  bool            my_in_template_decl;
464};
465
466}
467
468#endif