2002-06-15 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
[mono.git] / mcs / mbas / mb-parser.jay
1 %{\r
2 //\r
3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler\r
4 //\r
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)\r
6 //\r
7 // Licensed under the terms of the GNU GPL\r
8 //\r
9 // Copyright (C) 2001 A Rafael D Teixeira\r
10 //\r
11 // TODO:\r
12 //      Nearly everything\r
13 //\r
14 \r
15 namespace Mono.MonoBASIC\r
16 {\r
17         using System.Text;\r
18         using System;\r
19         using System.Collections;\r
20         using Mono.Languages;\r
21         using Mono.CSharp;\r
22 \r
23         /// <summary>\r
24         ///    The MonoBASIC Parser\r
25         /// </summary>\r
26         public class Parser : GenericParser \r
27         {\r
28         \r
29 /*\r
30                 /// <summary>\r
31                 ///   Current block is used to add statements as we find\r
32                 ///   them.  \r
33                 /// </summary>\r
34                 Block      current_block;\r
35 \r
36                 /// <summary>\r
37                 ///   Current interface is used by the various declaration\r
38                 ///   productions in the interface declaration to "add"\r
39                 ///   the interfaces as we find them.\r
40                 /// </summary>\r
41                 Interface  current_interface;\r
42 \r
43                 /// <summary>\r
44                 ///   This is used by the unary_expression code to resolve\r
45                 ///   a name against a parameter.  \r
46                 /// </summary>\r
47                 Parameters current_local_parameters;\r
48 \r
49                 /// <summary>\r
50                 ///   Using during property parsing to describe the implicit\r
51                 ///   value parameter that is passed to the "set" accessor\r
52                 ///   method\r
53                 /// </summary>\r
54                 Parameter [] implicit_value_parameters;\r
55 \r
56 */\r
57                 bool UseExtendedSyntax; // for ".mbs" files\r
58 \r
59                 public override string[] extensions()\r
60                 {\r
61                         string [] list = { ".vb", ".mbs" };\r
62                         return list;\r
63                 }\r
64 \r
65 %}\r
66 \r
67 %token EOF\r
68 %token NONE   /* This token is never returned by our lexer */\r
69 %token ERROR  // This is used not by the parser, but by the tokenizer.\r
70               // do not remove.\r
71 \r
72 /*\r
73  *These are the MonoBASIC keywords\r
74  */\r
75 %token ADDHANDLER\r
76 %token ADDRESSOF\r
77 %token ALIAS\r
78 %token AND\r
79 %token ANDALSO\r
80 %token ANSI\r
81 %token AS\r
82 %token ASSEMBLY\r
83 %token AUTO\r
84 %token BOOLEAN  \r
85 %token BYREF\r
86 %token BYTE\r
87 %token BYVAL    \r
88 %token CALL\r
89 %token CASE     \r
90 %token CATCH    \r
91 %token CBOOL\r
92 %token CBYTE\r
93 %token CCHAR    \r
94 %token CDATE\r
95 %token CDEC\r
96 %token CDBL\r
97 %token CHAR     \r
98 %token CINT\r
99 %token CLASS\r
100 %token CLNG\r
101 %token COBJ\r
102 //%token COMPARE        \r
103 %token CONST    \r
104 %token CSHORT   \r
105 %token CSNG\r
106 %token CSTR\r
107 %token CTYPE\r
108 %token DATE\r
109 %token DECIMAL  \r
110 %token DECLARE\r
111 %token DEFAULT  \r
112 %token DELEGATE \r
113 %token DESCRIPTION // MonoBASIC extension\r
114 %token DIM\r
115 %token DO       \r
116 %token DOUBLE   \r
117 %token EACH     \r
118 %token ELSE\r
119 %token ELSEIF\r
120 %token END      \r
121 %token ENUM     \r
122 %token EOL\r
123 %token ERASE\r
124 %token ERROR\r
125 %token EVENT\r
126 %token EXIT     \r
127 //%token EXPLICIT       \r
128 %token FALSE    \r
129 %token FINALLY  \r
130 %token FOR      \r
131 %token FRIEND\r
132 %token FUNCTION\r
133 %token GET\r
134 %token GETTYPE\r
135 %token GOTO     \r
136 %token HANDLES\r
137 %token IF       \r
138 %token IMPLEMENTS\r
139 %token IMPORTS  \r
140 %token IN       \r
141 %token INHERITS\r
142 %token INTEGER  \r
143 %token INTERFACE\r
144 %token IS\r
145 %token LET\r
146 %token LIB      \r
147 %token LIKE     \r
148 %token LONG     \r
149 %token LOOP\r
150 %token ME\r
151 %token MOD\r
152 %token MODULE\r
153 %token MUSTINHERIT      \r
154 %token MUSTOVERRIDE\r
155 %token MYBASE\r
156 %token MYCLASS\r
157 %token NAMESPACE\r
158 %token NEW\r
159 %token NEXT     \r
160 %token NOT\r
161 %token NOTHING\r
162 %token NOTINHERITABLE\r
163 %token NOTOVERRIDABLE\r
164 %token OBJECT   \r
165 %token ON\r
166 %token OPTION   \r
167 %token OPTIONAL \r
168 %token OR\r
169 %token ORELSE\r
170 %token OVERLOADS\r
171 %token OVERRIDABLE      \r
172 %token OVERRIDES        \r
173 %token PARAMETER // MonoBASIC extension\r
174 %token PARAM_ARRAY\r
175 %token PRESERVE\r
176 %token PRIVATE  \r
177 %token PROPERTY\r
178 %token PROTECTED\r
179 %token PUBLIC\r
180 %token RAISEEVENT\r
181 %token READONLY \r
182 %token REDIM\r
183 %token REM\r
184 %token REMOVEHANDLER\r
185 %token RESUME   \r
186 %token RETURN   \r
187 %token SELECT\r
188 %token SET\r
189 %token SHADOWS\r
190 %token SHARED\r
191 %token SHORT    \r
192 %token SINGLE\r
193 %token SIZEOF   \r
194 %token STATIC   \r
195 %token STEP\r
196 %token STOP\r
197 %token STRING   \r
198 %token STRUCTURE        \r
199 %token SUB\r
200 %token SUMMARY // MonoBASIC extension\r
201 %token SYNCLOCK\r
202 %token THEN\r
203 %token THROW\r
204 %token TO\r
205 %token TRUE     \r
206 %token TRY      \r
207 %token TYPEOF   \r
208 %token UNICODE\r
209 %token UNTIL\r
210 %token VARIANT  \r
211 %token WHEN     \r
212 %token WHILE    \r
213 %token WITH\r
214 %token WITHEVENTS\r
215 %token WRITEONLY\r
216 %token XOR\r
217 \r
218 /* MonoBASIC single character operators/punctuation. */\r
219 %token OPEN_BRACKET  "["\r
220 %token CLOSE_BRACKET "]"\r
221 %token OPEN_PARENS   "("\r
222 %token CLOSE_PARENS  ")"\r
223 %token DOT           "."\r
224 %token COMMA         ","\r
225 %token COLON         ":"\r
226 \r
227 %token PLUS           "+"\r
228 %token MINUS          "-"\r
229 %token ASSIGN         "="\r
230 %token OP_LT          "<"\r
231 %token OP_GT          ">"\r
232 %token STAR           "*"\r
233 %token PERCENT        "%"\r
234 %token DIV            "/"\r
235 %token OP_EXP         "^"\r
236 %token INTERR         "?"\r
237 %token OP_IDIV        "\\"\r
238 %token OP_CONCAT      "&"\r
239 \r
240 /* MonoBASIC multi-character operators. */\r
241 %token OP_LE                  "<="\r
242 %token OP_GE                  ">="\r
243 %token OP_EQ                  "=="\r
244 %token OP_NE                  "<>"\r
245 %token OP_AND                 //"and"\r
246 %token OP_OR                  //"or"\r
247 %token OP_XOR                 //"xor"\r
248 %token OP_MODULUS             //"mod"\r
249 %token OP_MULT_ASSIGN         "*="\r
250 %token OP_DIV_ASSIGN          "/="\r
251 %token OP_IDIV_ASSIGN         "\\="\r
252 %token OP_ADD_ASSIGN          "+="\r
253 %token OP_SUB_ASSIGN          "-="\r
254 %token OP_CONCAT_ASSIGN       "&="\r
255 %token OP_EXP_ASSIGN          "^="\r
256 \r
257 /* Numbers */\r
258 %token LITERAL_INTEGER           "int literal"\r
259 %token LITERAL_SINGLE            "float literal"\r
260 %token LITERAL_DOUBLE            "double literal"\r
261 %token LITERAL_DECIMAL           "decimal literal"\r
262 %token LITERAL_CHARACTER         "character literal"\r
263 %token LITERAL_STRING            "string literal"\r
264 \r
265 %token IDENTIFIER\r
266 \r
267 /* Add precedence rules to solve dangling else s/r conflict */\r
268 %nonassoc LOWPREC\r
269 %nonassoc IF\r
270 %nonassoc ELSE\r
271 %right ASSIGN\r
272 %left OP_OR\r
273 %left OP_AND\r
274 %left BITWISE_OR\r
275 %left BITWISE_AND\r
276 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT\r
277 %left PLUS MINUS\r
278 %left STAR DIV PERCENT\r
279 %right BITWISE_NOT CARRET UMINUS\r
280 %nonassoc OP_INC OP_DEC\r
281 %left OPEN_PARENS\r
282 %left OPEN_BRACKET OPEN_BRACE\r
283 %left DOT\r
284 %nonassoc HIGHPREC\r
285 \r
286 %start compilation_unit\r
287 %%\r
288 \r
289 compilation_unit\r
290         : opt_imports_directives \r
291           opt_attributes\r
292           opt_declarations \r
293           EOF\r
294           {\r
295                 $$ = $3;\r
296           }\r
297         ;\r
298         \r
299 opt_declarations\r
300         : /* empty */\r
301         | declarations\r
302         ;\r
303 \r
304 declarations\r
305         : declaration\r
306         | declarations declaration\r
307         ;\r
308         \r
309 declaration\r
310         : namespace_declaration\r
311         | type_declaration
312           {
313                 string name = "";
314                 int mod_flags;
315
316                 if ($1 is Class){
317                         Class c = (Class) $1;
318                         mod_flags = c.ModFlags;
319                         name = c.Name;
320                 } else if ($1 is Struct){
321                         Struct s = (Struct) $1;
322                         mod_flags = s.ModFlags;
323                         name = s.Name;
324                 } else
325                         break;
326
327                 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
328                         Report.Error (
329                                 1527, lexer.Location, 
330                                 "Namespace elements cannot be explicitly " +
331                                 "declared private or protected in '" + name + "'");
332                 }
333           }\r
334         ;\r
335 \r
336 qualified_identifier\r
337         : IDENTIFIER\r
338         | qualified_identifier DOT IDENTIFIER \r
339           { \r
340             $$ = (($1).ToString ()) + "." + ($3.ToString ()); \r
341           }\r
342         ;\r
343 opt_imports_directives\r
344         : /* empty */\r
345         | imports_directives\r
346         ;\r
347 \r
348 imports_directives\r
349         : imports_directive \r
350         | imports_directives imports_directive \r
351         ;\r
352 \r
353 imports_directive\r
354         : /* imports_alias_directive\r
355         | */ imports_namespace_directive\r
356         ;\r
357 \r
358 imports_namespace_directive\r
359         : IMPORTS qualified_identifier EOL \r
360           {\r
361                 current_namespace.Using ((string) $2);\r
362           }\r
363         ;\r
364 \r
365 opt_attributes\r
366         : /* empty */\r
367         ;\r
368 \r
369 namespace_declaration\r
370         : NAMESPACE qualified_identifier EOL\r
371           {\r
372                 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$2);
373           } \r
374           opt_imports_directives\r
375           opt_declarations\r
376           END NAMESPACE EOL\r
377           { \r
378                 current_namespace = current_namespace.Parent;\r
379           }\r
380         ;\r
381 \r
382 type_declaration\r
383         : class_declaration\r
384         | module_declaration\r
385 //      | struct_declaration            
386 //      | interface_declaration         
387 //      | enum_declaration              
388 //      | delegate_declaration
389         ;\r
390 \r
391 class_declaration\r
392         : /* opt_attributes opt_modifiers */\r
393           CLASS IDENTIFIER /* opt_class_interfaces */ EOL\r
394           { \r
395           }\r
396           opt_class_member_declarations\r
397           END CLASS EOL\r
398           {\r
399           }\r
400         ;\r
401 \r
402 opt_module_modifiers\r
403         : /* empty */   { $$ = (int) 0; }\r
404         | PUBLIC                { $$ = Modifiers.PUBLIC; }\r
405         | FRIEND                { $$ = Modifiers.INTERNAL; }\r
406         ;\r
407 \r
408 module_declaration\r
409         : opt_attributes opt_module_modifiers\r
410           MODULE IDENTIFIER EOL\r
411           { \r
412                 Module new_module;
413                 string name;
414
415                 name = MakeName((string) $4);
416                 new_module = new Module(current_container, 
417                                                                 name, 
418                                                                 (int) $2, 
419                                                                 (Attributes) $1,
420                                                                 lexer.Location);
421                 current_container = new_module;
422                 current_container.Namespace = current_namespace;
423                 RootContext.Tree.RecordDecl(name, new_module);
424           }\r
425           opt_class_member_declarations\r
426           END MODULE EOL\r
427           {\r
428                 Module new_module = (Module)current_container;
429
430                 current_container = current_container.Parent;
431                 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
432
433                 $$ = new_module;
434           }\r
435         ;\r
436 \r
437 opt_class_member_declarations\r
438         : /* empty */\r
439         | class_member_declarations\r
440         ;\r
441 \r
442 class_member_declarations\r
443         : class_member_declaration\r
444         | class_member_declarations class_member_declaration\r
445         ;\r
446 \r
447 class_member_declaration\r
448         : /* type_declaration\r
449         | */ sub_declaration\r
450         ;\r
451 \r
452 sub_declaration\r
453         : SUB qualified_identifier OPEN_PARENS opt_formal_parameters CLOSE_PARENS EOL\r
454           opt_statements\r
455           END SUB EOL\r
456         ;\r
457 \r
458 opt_statements\r
459         : /* empty */\r
460         | qualified_identifier OPEN_PARENS opt_actual_parameters CLOSE_PARENS EOL\r
461         ;\r
462 \r
463 opt_formal_parameters \r
464         : /* empty */\r
465         | qualified_identifier AS qualified_identifier\r
466         ;\r
467 \r
468 opt_actual_parameters \r
469         : /* empty */\r
470         | qualified_identifier\r
471         | LITERAL_STRING\r
472         ;\r
473 \r
474 %%\r
475 \r
476 \r
477 Tokenizer lexer;\r
478 \r
479 public Tokenizer Lexer {\r
480         get {\r
481                 return lexer;\r
482         }\r
483 }                  \r
484 \r
485 public override int parse ()\r
486 {\r
487         current_namespace = new Namespace (null, "");\r
488         current_container = RootContext.Tree.Types;\r
489         current_container.Namespace = current_namespace;\r
490 \r
491         UseExtendedSyntax = name.EndsWith(".mbs");\r
492 \r
493         lexer = new Tokenizer (input, name, defines);\r
494         StringBuilder value = new StringBuilder ();\r
495 \r
496         global_errors = 0;\r
497         try \r
498         {\r
499                 if (yacc_verbose_flag)\r
500                         yyparse (lexer, new yydebug.yyDebugSimple ());\r
501                 else\r
502                         yyparse (lexer);\r
503         } \r
504         catch (Exception e)\r
505         {\r
506                 Console.WriteLine (lexer.location + "  : Parsing error ");\r
507                 Console.WriteLine (e);\r
508                 global_errors++;\r
509         }\r
510 \r
511         return global_errors;\r
512 }\r
513 \r
514 /* end end end */\r
515 }\r
516 \r
517 \r