/[mpak]/mpak/include/mpak/spec/parser.tcc
ViewVC logotype

Diff of /mpak/include/mpak/spec/parser.tcc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by pbgavin, Mon Jul 28 18:20:26 2003 UTC revision 1.2 by pbgavin, Fri Aug 1 01:34:27 2003 UTC
# Line 18  Line 18 
18  // along with this program; if not, write to the Free Software  // along with this program; if not, write to the Free Software
19  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20    
21    // This is a basic nonrecursive, table driven, top-down parser.
22    //
23    // Nonterminals:
24    // ============
25    // STRING:        a string, either delimited by '"' and '"', or '[' and ']'
26    // COMMAND_BEGIN: '%'
27    // BLOCK_BEGIN:   '{'
28    // BLOCK_END:     '}'
29    // IDENTIFIER:    [A-Za-z_][A-Za-z0-9_]*
30    // EQUALS:        '='
31    // SEMICOLON:     ';'
32    // ENDL:          '\n'
33    // EOF:           end-of-file
34    //
35    //
36    // Productions:
37    // ===========
38    // 1.  start          -> statement_list EOF
39    // 2.  statement_list -> statement statement_list
40    // 3.                  | EMPTY
41    // 4.  statement      -> command statement_end
42    // 5.                  | assignment statement_end
43    // 6.                  | statement_end
44    // 7.  statement_end  -> SEMICOLON
45    // 8.                  | ENDL
46    // 9.  command        -> COMMAND_BEGIN IDENTIFIER argument_list
47    // 10. argument_list  -> argument argument_list
48    // 11.                 | EMPTY
49    // 12. argument       -> STRING
50    // 13.                 | block
51    // 14. block          -> BLOCK_BEGIN statement_list BLOCK_END
52    // 15. assignment     -> IDENTIFIER EQUALS STRING
53    //
54    //
55    // SYMBOL          FIRST           FOLLOW
56    // ======          =====           ======
57    // start:          IDENTIFIER      EOF
58    //                 COMMAND_BEGIN
59    //                 SEMICOLON
60    //                 ENDL
61    //                 EMPTY
62    //
63    // statement_list: COMMAND_BEGIN   BLOCK_END
64    //                 IDENTIFIER      EOF
65    //                 SEMICOLON
66    //                 ENDL
67    //                 EMPTY
68    //
69    // statement:      COMMAND_BEGIN   SEMICOLON
70    //                 IDENTIFIER      ENDL
71    //                 SEMICOLON
72    //                 ENDL
73    //
74    // statement_end:  SEMICOLON       COMMAND_BEGIN
75    //                 ENDL            IDENTIFIER
76    //                                 SEMICOLON
77    //                                 ENDL
78    //                                 BLOCK_END
79    //                                 EOF
80    //
81    // command:        COMMAND_BEGIN   SEMICOLON
82    //                                 ENDL
83    //
84    // argument_list:  STRING          SEMICOLON
85    //                 BLOCK_BEGIN     ENDL
86    //                 EMPTY
87    //
88    // argument:       STRING          STRING
89    //                 BLOCK_BEGIN     BLOCK_BEGIN
90    //                                 SEMICOLON
91    //                                 ENDL
92    //
93    // block:          BLOCK_BEGIN     STRING
94    //                                 BLOCK_BEGIN
95    //                                 SEMICOLON
96    //                                 ENDL
97    //                                 BLOCK_END
98    //
99    // assignment:     IDENTIFIER      SEMICOLON
100    //                                 ENDL
101    //                                 BLOCK_END
102    //
103    // Parse Table:
104    // ===========
105    // (Data are the productions to be used.)
106    //
107    //                 COMMAND_BEGIN   IDENTIFIER      STRING          BLOCK_BEGIN     BLOCK_END       EQUALS          SEMICOLON       ENDL            EOF
108    // start:          1               1               -               -               -               -               1               1               1
109    // statement_list: 2               2               -               -               3               -               2               2               3
110    // statement:      4               5               -               -               -               -               6               6               -
111    // statement_end:  -               -               -               -               -               -               7               8               -
112    // command:        9               -               -               -               -               -               -               -               -
113    // argument_list:  -               -               10              10              -               -               11              11              -
114    // argument:       -               -               12              13              -               -               -               -               -
115    // block:          -               -               -               14              -               -               -               -               -
116    // assignment:     -               15              -               -               -               -               -               -               -
117    //
118    
119  #ifndef __MPAK__PARSER_TCC__  #ifndef __MPAK__PARSER_TCC__
120  #define __MPAK__PARSER_TCC__  #define __MPAK__PARSER_TCC__
121    
122  #include <config.h>  #include <config.h>
123    
124  #include <list>  #include <stdexcept>
125    #include <stack>
126    
127  #include <ecstacy/util/macros.hh>  #include <ecstacy/util/macros.hh>
128    
# Line 31  namespace mpak Line 130  namespace mpak
130  {  {
131      namespace spec      namespace spec
132      {      {
133          template<typename char_type_, typename traits_type_ = std::char_traits<_char_type> >          template<typename char_type_, typename traits_type_>
134          basic_parser<char_type_, traits_type_>::~basic_parser (void)          typename basic_parser<char_type_,traits_type_>::parse_tree
135              ECSTACY_THROW_SPEC (())          basic_parser<char_type_, traits_type_>::do_parse_ (basic_parser<char_type_,traits_type_>::lexer_type &lexer)
136          {              ECSTACY_THROW_SPEC ((basic_parser<char_type_, traits_type_>::failure))
         }  
           
         template<typename char_type_, typename traits_type_ = std::char_traits<_char_type> >  
         void  
         basic_parser<char_type_, traits_type_>::parse (void)  
             ECSTACY_THROW_SPEC ((basic_parser::failure))  
137          {          {
138                std::stack<symbol> symbol_stack;
139                symbol_stack.push (symbol (token_type (token_type::type_eof)));
140                symbol_stack.push (symbol (symbol::type_start));
141                token_type token (lexer.next_token ());
142                
143                do {
144                    symbol top = symbol_stack.top ();
145                    
146                    switch (top.type) {
147                    case symbol::type_token:
148                        if (top.token.type == token.type) {
149                            symbol_stack.pop ();
150                            token = lexer.next_token ();
151                        } else {
152                            ecstacy::util::throw_exception (failure ("unrecognized token"));
153                        }
154                        break;
155                        
156                    case symbol::type_start:
157                        switch (token.type) {
158                        case token_type::type_command_begin:
159                        case token_type::type_identifier:
160                        case token_type::type_semicolon:
161                        case token_type::type_endl:
162                        case token_type::type_eof:
163                            // start -> statement_list
164                            symbol_stack.pop ();
165                            symbol_stack.push (symbol::type_statement_list);
166                            break;
167                        default:
168                            ecstacy::util::throw_exception (failure ("unrecognized token"));
169                        }
170                        break;
171                        
172                    case symbol::type_statement_list:
173                        switch (token.type) {
174                        case token_type::type_command_begin:
175                        case token_type::type_identifier:
176                        case token_type::type_semicolon:
177                        case token_type::type_endl:
178                            // statement_list -> statement statement_list
179                            symbol_stack.pop ();
180                            symbol_stack.push (symbol (symbol::type_statement_list));
181                            symbol_stack.push (symbol (symbol::type_statement));
182                            break;
183                        case token_type::type_block_end:
184                        case token_type::type_eof:
185                            // statement_list -> EMPTY
186                            symbol_stack.pop ();
187                            break;
188                        default:
189                            ecstacy::util::throw_exception (failure ("unrecognized token"));
190                        }
191                        break;
192                        
193                    case symbol::type_statement:
194                        switch (token.type) {
195                        case token_type::type_command_begin:
196                            // statement -> command statement_end
197                            symbol_stack.pop ();
198                            symbol_stack.push (symbol (symbol::type_statement_end));
199                            symbol_stack.push (symbol (symbol::type_command));
200                            break;
201                        case token_type::type_identifier:
202                            // statement -> assignment statement_end
203                            symbol_stack.pop ();
204                            symbol_stack.push (symbol (symbol::type_statement_end));
205                            symbol_stack.push (symbol (symbol::type_assignment));
206                            break;
207                        case token_type::type_semicolon:
208                        case token_type::type_endl:
209                            // statement -> statement_end
210                            symbol_stack.pop ();
211                            symbol_stack.push (symbol (symbol::type_statement_end));
212                            break;
213                        default:
214                            ecstacy::util::throw_exception (failure ("unrecognized token"));
215                        }
216                        break;
217                        
218                    case symbol::type_statement_end:
219                        switch (token.type) {
220                        case token_type::type_semicolon:
221                            // statement_end -> SEMICOLON
222                            symbol_stack.pop ();
223                            symbol_stack.push (symbol (token_type (token_type::type_semicolon)));
224                            break;
225                        case token_type::type_endl:
226                            // statement_end -> ENDL
227                            symbol_stack.pop ();
228                            symbol_stack.push (symbol (token_type (token_type::type_endl)));
229                            break;
230                        default:
231                            ecstacy::util::throw_exception (failure ("unrecognized token"));
232                        }
233                        
234                    case symbol::type_command:
235                        switch (token.type) {
236                        case token_type::type_command_begin:
237                            // command -> COMMAND_BEGIN IDENTIFIER argument_list
238                            symbol_stack.pop ();
239                            symbol_stack.push (symbol (symbol::type_argument_list));
240                            symbol_stack.push (symbol (token_type (token_type::type_identifier)));
241                            symbol_stack.push (symbol (token_type (token_type::type_command_begin)));
242                            break;
243                        default:
244                            ecstacy::util::throw_exception (failure ("unrecognized token"));
245                        }
246                        break;
247                        
248                    case symbol::type_argument_list:
249                        switch (token.type) {
250                        case token_type::type_string:
251                        case token_type::type_block_begin:
252                            // argument_list -> argument argument_list
253                            symbol_stack.pop ();
254                            symbol_stack.push (symbol (symbol::type_argument_list));
255                            symbol_stack.push (symbol (symbol::type_argument));
256                            break;
257                        case token_type::type_semicolon:
258                        case token_type::type_endl:
259                            // argument_list -> EMPTY
260                            symbol_stack.pop ();
261                            break;
262                        default:
263                            ecstacy::util::throw_exception (failure ("unrecognized token"));
264                        }
265                        break;
266                        
267                    case symbol::type_argument:
268                        switch (token.type) {
269                        case token_type::type_string:
270                            // argument -> STRING
271                            symbol_stack.pop ();
272                            symbol_stack.push (symbol (token_type (token_type::type_string)));
273                            break;
274                        case token_type::type_block_begin:
275                            // argument -> block
276                            symbol_stack.pop ();
277                            symbol_stack.push (symbol (symbol::type_block));
278                            break;
279                        default:
280                            ecstacy::util::throw_exception (failure ("unrecognized token"));
281                        }
282                        break;
283                        
284                    case symbol::type_block:
285                        switch (token.type) {
286                        case token_type::type_block_begin:
287                            // block -> BLOCK_BEGIN statement_list BLOCK_END
288                            symbol_stack.pop ();
289                            symbol_stack.push (symbol (token_type (token_type::type_block_end)));
290                            symbol_stack.push (symbol (symbol::type_start));
291                            symbol_stack.push (symbol (token_type (token_type::type_block_begin)));
292                        default:
293                            ecstacy::util::throw_exception (failure ("unrecognized token"));
294                        }
295                        break;
296                        
297                    case symbol::type_assignment:
298                        switch (token.type) {
299                        case token_type::type_identifier:
300                            // assignment -> IDENTIFIER EQUALS STRING
301                            symbol_stack.pop ();
302                            symbol_stack.push (symbol (token_type (token_type::type_string)));
303                            symbol_stack.push (symbol (token_type (token_type::type_equals)));
304                            symbol_stack.push (symbol (token_type (token_type::type_identifier)));
305                        default:
306                            ecstacy::util::throw_exception (failure ("unrecognized token"));
307                        }
308                    default:
309                        ecstacy::util::throw_exception (std::logic_error ("what the fuck?"));
310                    }
311                } while (1);
312                return parse_tree ();
313          }          }
314      }      }
315  }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26