~ubuntu-branches/ubuntu/jaunty/aspectc++/jaunty

« back to all changes in this revision

Viewing changes to Puma/gen-release/step1/inc/Puma/Syntax.h

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-07-07 14:41:02 UTC
  • mfrom: (1.1.3 upstream) (6.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080707144102-lzml7t07f3sl00r5
Tags: 1.0pre4~svn.20080711-1
* new upstream snapshot.
* include all upstream documentation. Clarifying emails regarding
  licensing has been included into debian/copyright.
* reformat description following recomendations of
  http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Description
  (Closes: #480316)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#ifndef __Syntax_h__
20
20
#define __Syntax_h__
21
21
 
 
22
/** \file
 
23
 *  Basic syntactic analysis component. */
 
24
 
22
25
#include "Puma/Token.h"
23
26
#include "Puma/Builder.h"
24
 
//#include "Puma/Semantic.h"
25
27
#include "Puma/ErrorSink.h"
26
28
#include "Puma/TokenProvider.h"
27
29
 
31
33
class Config;
32
34
class CTree;
33
35
 
 
36
 
 
37
/** \class Syntax Syntax.h Puma/Syntax.h
 
38
 *  Syntactic analysis base class. 
 
39
 *
 
40
 *  Implements the top-down parsing algorithm (recursive descend parser). 
 
41
 *  To be derived to implement parsers for specific grammars. Provides 
 
42
 *  infinite look-ahead. 
 
43
 *
 
44
 *  This class uses a tree builder object (see Builder) to create the 
 
45
 *  syntax tree, and a semantic analysis object (see Semantic) to perform
 
46
 *  required semantic analyses of the parsed code. 
 
47
 *
 
48
 *  The parse process is started by calling Syntax::run() with a token
 
49
 *  provider as argument. Using the token provider this method reads the 
 
50
 *  first core language token from the input source code and tries to parse 
 
51
 *  it by applying the top grammar rule. 
 
52
 *
 
53
 *  \code return parse(&Puma::Syntax::trans_unit) ? builder().Top() : (Puma::CTree*)0; \endcode
 
54
 *
 
55
 *  The top grammar rule has to be provided by reimplementing method 
 
56
 *  Syntax::trans_unit(). It may call sub-rules according to the implemented 
 
57
 *  language-specific grammar. Example:
 
58
 *
 
59
 *  \code 
 
60
 * Puma::CTree *MySyntax::trans_unit() {
 
61
 *   return parse(&MySyntax::block_seq) ? builder().block_seq() : (Puma::CTree*)0;
 
62
 * }
 
63
 *  \endcode
 
64
 *
 
65
 *  For context-sensitive grammars it may be necessary in the rules of 
 
66
 *  the grammar to perform first semantic analyses of the parsed code
 
67
 *  (to differentiate ambigous syntactic constructs, resolve names, 
 
68
 *  detect errors, and so one). Example:
 
69
 *
 
70
 *  \code 
 
71
 * Puma::CTree *MySyntax::block() {
 
72
 *   // '{' instruction instruction ... '}'
 
73
 *   if (parse(TOK_OPEN_CURLY)) {             // parse '{'
 
74
 *     semantic().enter_block();              // enter block scope
 
75
 *     seq(&MySyntax::instruction);           // parse sequence of instructions
 
76
 *     semantic().leave_block();              // leave block scope
 
77
 *     if (parse(TOK_CLOSE_CURLY)) {          // parse '}'
 
78
 *       return builder().block();            // build syntax tree for the block
 
79
 *     }
 
80
 *   }
 
81
 *   return (CTree*)0;                        // rule failed
 
82
 * }
 
83
 *  \endcode
 
84
 *
 
85
 *  If a rule could be parsed successfully the tree builder is used to 
 
86
 *  create a CTree based syntax tree (fragment) for the parsed rule. Failing
 
87
 *  grammar rules shall return NULL. The result of the top grammar rule is 
 
88
 *  the root node of the abstract syntax tree for the whole input source code. */
34
89
class Syntax {
35
90
  Token *_problem_token;
36
91
  bool _have_error;
39
94
  Semantic &_semantic;
40
95
 
41
96
public:
 
97
  /** Token provider for getting the tokens to parse. */
42
98
  TokenProvider *token_provider;
43
99
 
44
100
public: 
 
101
  /** \class State Syntax.h Puma/Syntax.h
 
102
   *  Parser state, the current position in the token stream. */
45
103
  struct State : public TokenProvider::State {
 
104
    /** Constructor. */
46
105
    State () {}
 
106
    /** Constructor. */
47
107
    State (int) {}
 
108
    /** Copy constructor.
 
109
     *  \param s The parser state to copy. */
48
110
    State (const TokenProvider::State &s) : TokenProvider::State (s) {}
49
111
  };
50
112
 
51
113
protected:
52
 
  Syntax (Builder &, Semantic &);
 
114
  /** Constructor.
 
115
   *  \param b The syntax tree builder.
 
116
   *  \param s The semantic analysis object. */ 
 
117
  Syntax (Builder &b, Semantic &s);
 
118
  /** Destructor. */
53
119
  virtual ~Syntax () {}
54
120
 
55
121
public:
56
 
  CTree *run (TokenProvider &);
57
 
  template <class T> CTree *run (TokenProvider &, CTree *(T::*)());
58
 
  virtual void configure (Config &) {}
 
122
  /** Start the parse process.
 
123
   *  \param tp The token provider from where to get the tokens to parse. 
 
124
   *  \return The resulting syntax tree. */
 
125
  CTree *run (TokenProvider &tp);
 
126
  /** Start the parse process at a specific grammar rule.
 
127
   *  \param tp The token provider from where to get the tokens to parse. 
 
128
   *  \param rule The grammar rule where to start. 
 
129
   *  \return The resulting syntax tree. */
 
130
  template <class T> CTree *run (TokenProvider &tp, CTree *(T::*rule)());
 
131
  /** Configure the syntactic analysis object. 
 
132
   *  \param c The configuration object. */
 
133
  virtual void configure (Config &c) {}
 
134
  /** Get the token provider from which the parsed tokens are read. */
59
135
  TokenProvider *provider () const { return token_provider; }
 
136
  /** Get the last token that could not be parsed. */
60
137
  Token *problem () const;
 
138
  /** Check if errors occured during the parse process. */
61
139
  bool error () const;
62
 
  bool look_ahead (int, unsigned = 1);
63
 
  bool look_ahead (int*, unsigned = 1);
 
140
  /** Look-ahead n core language tokens and check if 
 
141
   *  the n-th token has the given type. 
 
142
   *  \param token_type The type of the n-th token. 
 
143
   *  \param n The number of tokens to look-ahead. 
 
144
   *  \return True if the n-th token has the given type. */
 
145
  bool look_ahead (int token_type, unsigned n = 1);
 
146
  /** Look-ahead n core language tokens and check if 
 
147
   *  the n-th token has one of the given types. 
 
148
   *  \param token_types The possible types of the n-th token. 
 
149
   *  \param n The number of tokens to look-ahead. 
 
150
   *  \return True if the n-th token has one of the given types. */
 
151
  bool look_ahead (int* token_types, unsigned n = 1);
 
152
  /** Look-ahead one core language token. 
 
153
   *  \return The type of the next core language token. */
64
154
  inline int look_ahead () const;
 
155
  /** Consume all tokens until the next core language token. */
65
156
  inline bool consume ();
66
157
 
67
158
protected:
68
 
  template <class T> bool parse (CTree *(T::*)());
69
 
  template <class T> bool seq (CTree *(T::*)());
70
 
  template <class T> bool seq (bool (T::*)());
71
 
  template <class T> bool list (CTree *(T::*)(), int, bool = false);
72
 
  template <class T> bool list (CTree *(T::*)(), int*, bool = false);
73
 
  template <class T> bool list (bool (T::*)(), int, bool = false);
74
 
  template <class T> bool list (bool (T::*)(), int*, bool = false);
75
 
  template <class T> bool catch_error (CTree *(T::*)(), const char*, int*, int*);
76
 
  bool parse (int);
77
 
  bool parse (int *);
78
 
  bool parse_token (int);
79
 
  bool opt (bool) const;
 
159
  /** Parse the given grammar rule. Saves the current state of 
 
160
   *  the builder, semantic, and token provider objects.
 
161
   *  \param rule The rule to parse. 
 
162
   *  \return True if parsed successfully. */
 
163
  template <class T> bool parse (CTree *(T::*rule)());
 
164
  /** Parse a sequence of the given grammar rule. 
 
165
   *  \param rule The rule to parse at least once. 
 
166
   *  \return True if parsed successfully. */
 
167
  template <class T> bool seq (CTree *(T::*rule)());
 
168
  /** Parse a sequence of the given grammar rule. 
 
169
   *  \param rule The rule to parse at least once. 
 
170
   *  \return True if parsed successfully. */
 
171
  template <class T> bool seq (bool (T::*rule)());
 
172
  /** Parse a sequence of rule-separator pairs. 
 
173
   *  \param rule The rule to parse at least once. 
 
174
   *  \param separator The separator token.
 
175
   *  \param trailing_separator True if a trailing separator token is allowed.
 
176
   *  \return True if parsed successfully. */
 
177
  template <class T> bool list (CTree *(T::*rule)(), int separator, bool trailing_separator = false);
 
178
  /** Parse a sequence of rule-separator pairs. 
 
179
   *  \param rule The rule to parse at least once. 
 
180
   *  \param separators The separator tokens.
 
181
   *  \param trailing_separator True if a trailing separator token is allowed.
 
182
   *  \return True if parsed successfully. */
 
183
  template <class T> bool list (CTree *(T::*rule)(), int* separators, bool trailing_separator = false);
 
184
  /** Parse a sequence of rule-separator pairs. 
 
185
   *  \param rule The rule to parse at least once. 
 
186
   *  \param separator The separator token.
 
187
   *  \param trailing_separator True if a trailing separator token is allowed.
 
188
   *  \return True if parsed successfully. */
 
189
  template <class T> bool list (bool (T::*rule)(), int separator, bool trailing_separator = false);
 
190
  /** Parse a sequence of rule-separator pairs. 
 
191
   *  \param rule The rule to parse at least once. 
 
192
   *  \param separators The separator tokens.
 
193
   *  \param trailing_separator True if a trailing separator token is allowed.
 
194
   *  \return True if parsed successfully. */
 
195
  template <class T> bool list (bool (T::*rule)(), int* separators, bool trailing_separator = false);
 
196
  /** Parse a grammar rule automatically catching parse errors. 
 
197
   *  \param rule The rule to parse. 
 
198
   *  \param msg The error message to show if the rule fails.
 
199
   *  \param finish_tokens Set of token types that abort parsing the rule.
 
200
   *  \param skip_tokens If the rule fails skip all tokens until a token is read
 
201
   *                     that has one of the types given here. 
 
202
   *  \return False if at EOF or a finish_token is read, true otherwise. */
 
203
  template <class T> bool catch_error (CTree *(T::*rule)(), const char* msg, int* finish_tokens, int* skip_tokens);
 
204
  /** Parse a token with the given type.
 
205
   *  \param token_type The token type. 
 
206
   *  \return True a corresponding token was parsed. */
 
207
  bool parse (int token_type);
 
208
  /** Parse a token with one of the given types.
 
209
   *  \param token_types The token types. 
 
210
   *  \return True a corresponding token was parsed. */
 
211
  bool parse (int *token_types);
 
212
  /** Parse a token with the given type.
 
213
   *  \param token_type The token type. 
 
214
   *  \return True a corresponding token was parsed. */
 
215
  bool parse_token (int token_type);
 
216
  /** Optional rule parsing. Always succeeds regardless
 
217
   *  of the argument.
 
218
   *  \param dummy Dummy parameter, is not evaluated.
 
219
   *  \return True. */
 
220
  bool opt (bool dummy) const;
80
221
 
81
222
protected:
 
223
  /** Get the syntax tree builder. */
82
224
  Builder &builder () const;
 
225
  /** Get the semantic analysis object. */
83
226
  Semantic &semantic () const;
84
227
 
85
228
protected:
86
 
  // initial parse rule
 
229
  /** Top parse rule to be reimplemented for a specific grammar. 
 
230
   *  \return The root node of the syntax tree, or NULL. */
87
231
  virtual CTree *trans_unit ();
88
232
 
89
 
  // handle a compiler directive token
 
233
  /** Handle a compiler directive token. The default handling is
 
234
   *  to skip the compiler directive. */
90
235
  virtual void handle_directive ();
91
236
 
92
237
protected:
 
238
  /** Save the current parser state. Calls save_state() on the 
 
239
   *  builder, semantic, and token provider objects.
 
240
   *  \return The current parser state. */
93
241
  State save_state ();
 
242
  /** Forget the saved parser state. */
94
243
  void forget_state ();
 
244
  /** Restore the saved parser state. Triggers restoring the 
 
245
   *  syntax and semantic trees to the saved state. */
95
246
  void restore_state ();
96
 
  void restore_state (State);
97
 
  void set_state (State);
98
 
 
99
 
  bool accept (CTree *, State);
100
 
 
 
247
  /** Restore the saved parser state to the given state. 
 
248
   *  Triggers restoring the syntax and semantic trees.
 
249
   *  \param state The state to which to restore. */
 
250
  void restore_state (State state);
 
251
  /** Overwrite the parser state with the given state. 
 
252
   *  \param state The new parser state. */
 
253
  void set_state (State state);
 
254
 
 
255
  /** Accept the given syntax tree node. If the node is NULL
 
256
   *  then the parser state is restored to the given state.
 
257
   *  Otherwise all saved states are discarded. 
 
258
   *  \param tree Tree to accept. 
 
259
   *  \param state The saved state. */
 
260
  bool accept (CTree *tree, State state);
 
261
 
 
262
  /** Skip all non-core language tokens until the next 
 
263
   *  core-language token is read. 
 
264
   *  \return The next core-language token. */
101
265
  Token *locate_token ();
 
266
  /** Skip the current token. */
102
267
  void skip ();
103
 
  void skip_block (int, int);
 
268
  /** Skip all tokens between start and end, including
 
269
   *  start and end token.
 
270
   *  \param start The start token type.
 
271
   *  \param end The end token type. */
 
272
  void skip_block (int start, int end);
 
273
  /** Skip all tokens between '{' and '}', including
 
274
   *  '{' and '}'. */
104
275
  void skip_curly_block ();
 
276
  /** Skip all tokens between '(' and ')', including
 
277
   *  '(' and ')'. */
105
278
  void skip_round_block ();
106
 
  void parse_block (int, int);
 
279
  /** Parse all tokens between start and end, including
 
280
   *  start and end token.
 
281
   *  \param start The start token type.
 
282
   *  \param end The end token type. */
 
283
  void parse_block (int start, int end);
 
284
  /** Parse all tokens between '{' and '}', including
 
285
   *  '{' and '}'. */
107
286
  void parse_curly_block ();
 
287
  /** Parse all tokens between '(' and ')', including
 
288
   *  '(' and ')'. */
108
289
  void parse_round_block ();
109
 
  bool skip (int, bool = true);
110
 
  bool skip (int *, bool = true);
111
 
  bool is_in (int, int *) const;
 
290
  /** Skip all tokens until a token with the given type is read.
 
291
   *  \param stop_token The type of the token to stop.
 
292
   *  \param inclusive If true, the stop token is skipped too. 
 
293
   *  \return False if the stop token is not found, true otherwise. */
 
294
  bool skip (int stop_token, bool inclusive = true);
 
295
  /** Skip all tokens until a token with one of the given types is read.
 
296
   *  \param stop_tokens The types of the token to stop.
 
297
   *  \param inclusive If true, the stop token is skipped too. 
 
298
   *  \return False if the stop token is not found, true otherwise. */
 
299
  bool skip (int *stop_tokens, bool inclusive = true);
 
300
  /** Check if the given token type is in the set of given token types.
 
301
   *  \param token_type The token type to check.
 
302
   *  \param token_types The set of token types. */
 
303
  bool is_in (int token_type, int *token_types) const;
112
304
};
113
305
 
114
306
inline Syntax::Syntax (Builder &b, Semantic &s) :