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