3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
6 // Anirban Bhattacharjee (banirban@novell.com)
7 // Jambunathan K (kjambunathan@novell.com)
9 // Licensed under the terms of the GNU GPL
11 // Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
12 // Copyright (C) 2003, 2004 Novell
20 using System.Reflection;
21 using System.Collections;
25 /// The MonoBASIC Parser
28 // public class Parser : GenericParser
33 // /// Current block is used to add statements as we find
36 // Block current_block;
39 // /// Tmp block is used to store block endings in if/select's
44 // /// Tmp block is used to store tmp copies of expressions
46 // Expression tmp_expr;
49 // /// Tmp catch is used to store catch clauses in try..catch..finally
51 // ArrayList tmp_catch_clauses;
54 // /// Current interface is used by the various declaration
55 // /// productions in the interface declaration to "add"
56 // /// the interfaces as we find them.
58 // Interface current_interface;
61 // /// This is used by the unary_expression code to resolve
62 // /// a name against a parameter.
64 // Parameters current_local_parameters;
67 // /// This are used when parsing parameters in property
70 // Parameters set_parameters;
71 // Parameters get_parameters;
74 // /// This is used by the sub_header parser to store modifiers
75 // /// to be passed to sub/constructor
77 // int current_modifiers;
80 // /// This is used by the sub_header parser to store attributes
81 // /// to be passed to sub/constructor
83 // Attributes current_attributes;
86 // /// Using during property parsing to describe the implicit
87 // /// value parameter that is passed to the "set" accessor
90 // string get_implicit_value_parameter_name;
93 // // Using during property parsing to describe the implicit
94 // // value parameter that is passed to the "set" and "get"accesor
95 // // methods (properties and indexers).
97 // Expression get_implicit_value_parameter_type;
100 // /// Using during property parsing to describe the implicit
101 // /// value parameter that is passed to the "set" accessor
104 // string set_implicit_value_parameter_name;
107 // // Using during property parsing to describe the implicit
108 // // value parameter that is passed to the "set" and "get"accesor
109 // // methods (properties and indexers).
111 // Expression set_implicit_value_parameter_type;
113 // Location member_location;
115 // // An out-of-band stack.
119 // ArrayList current_rank_specifiers;
121 // DoOptions do_type;
125 // Stack switch_stack;
127 // // Expression stack for nested ifs
131 // Stack statement_stack;
133 // // A stack for With expressions.
138 // static public bool InitialOptionExplicit = false;
139 // static public bool InitialOptionStrict = false;
140 // static public bool InitialOptionCompareBinary = true;
141 // static public ArrayList ImportsList = null;
143 // bool OptionExplicit;
144 // bool OptionStrict;
145 // bool OptionCompareBinary;
147 // static public bool UseExtendedSyntax; // for ".mbs" files
149 // bool implicit_modifiers;
151 // public override string[] extensions()
153 // string [] list = { ".vb", ".mbs" };
161 public class CSharpParser {
162 NamespaceEntry current_namespace;
163 TypeContainer current_container;
164 TypeContainer current_class;
166 IIteratorContainer iterator_container;
169 /// Current block is used to add statements as we find
172 Block current_block, top_current_block;
175 /// This is used by the unary_expression code to resolve
176 /// a name against a parameter.
178 Parameters current_local_parameters;
181 /// Using during property parsing to describe the implicit
182 /// value parameter that is passed to the "set" and "get"accesor
183 /// methods (properties and indexers).
185 Expression implicit_value_parameter_type;
186 Parameters indexer_parameters;
189 /// Used to determine if we are parsing the get/set pair
190 /// of an indexer or a property
192 bool parsing_indexer;
195 /// An out-of-band stack.
204 static public int yacc_verbose_flag;
206 // Name of the file we are parsing
210 /// The current file.
214 /// This is used by the sub_header parser to store modifiers
215 /// to be passed to sub/constructor
216 int current_modifiers;
218 /// This is used by the sub_header parser to store attributes
219 /// to be passed to sub/constructor
220 Attributes current_attributes;
222 /// This is used by the attributes parser to syntactically
223 /// validate the attribute rules
224 bool allow_global_attribs = true;
226 bool expecting_global_attribs = false;
227 bool expecting_local_attribs = false;
229 bool local_attrib_section_added = false;
232 ArrayList current_rank_specifiers;
235 /// Using during property parsing to describe the implicit
236 /// value parameter that is passed to the "set" accessor
239 string get_implicit_value_parameter_name;
242 // Using during property parsing to describe the implicit
243 // value parameter that is passed to the "set" and "get"accesor
244 // methods (properties and indexers).
246 Expression get_implicit_value_parameter_type;
249 /// Using during property parsing to describe the implicit
250 /// value parameter that is passed to the "set" accessor
253 string set_implicit_value_parameter_name;
256 // Using during property parsing to describe the implicit
257 // value parameter that is passed to the "set" and "get"accesor
258 // methods (properties and indexers).
260 Expression set_implicit_value_parameter_type;
263 /// This are used when parsing parameters in property
266 Parameters set_parameters;
267 Parameters get_parameters;
269 // static public ArrayList ImportsList = null;
271 bool implicit_modifiers;
275 /// This is used as a helper class for handling of
276 /// pre-processor statements.
279 // FIXME: This class MBASException is actually a kludge
280 // It can be done away with a more elegant replacement.
282 public class MBASException : ApplicationException
287 public MBASException(int code, Location loc, string text) : base(text)
296 public class IfElseStateMachine {
320 public static Hashtable errStrings = new Hashtable();
323 static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
325 static IfElseStateMachine()
327 // FIXME: Fix both the error nos and the error strings.
328 // Currently the error numbers and the error strings are
329 // just placeholders for getting the state-machine going.
331 errStrings.Add(0, "");
332 errStrings.Add(30012, "#If must end with a matching #End If");
333 errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
334 errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
335 errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
336 errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
338 errTable[(int)State.START, (int)Token.IF] = 0;
339 errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
340 errTable[(int)State.START, (int)Token.ELSE] = 30028;
341 errTable[(int)State.START, (int)Token.ENDIF] = 30013;
342 errTable[(int)State.START, (int)Token.EOF] = 0;
344 errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
345 errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
346 errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
347 errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
348 errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
350 errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
351 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
352 errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
353 errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
354 errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
356 errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
357 errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
358 errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
359 errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
360 errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
362 errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
363 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
364 errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
365 errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
366 errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
369 public IfElseStateMachine()
373 stateStack = new Stack();
374 stateStack.Push(state);
377 // The parameter here need not be qualified with IfElseStateMachine
378 // But it hits a bug in mcs. So temporarily scoping it so that builds
381 public void HandleToken(IfElseStateMachine.Token tok)
383 err = (int) errTable[(int)state, (int)tok];
386 throw new ApplicationException("Unexpected pre-processor directive #"+tok);
388 if(tok == Token.IF) {
389 stateStack.Push(state);
392 else if(tok == Token.ENDIF) {
393 state = (State)stateStack.Pop();
405 public string ErrString {
407 return (string) errStrings[err];
413 public class TokenizerController {
417 public bool CanAcceptTokens;
418 public bool CanSelectBlock;
426 public TokenizerController(Tokenizer lexer)
429 stateStack = new Stack();
431 currentState.CanAcceptTokens = true;
432 currentState.CanSelectBlock = true;
434 stateStack.Push(currentState);
439 return (State)stateStack.Peek();
443 public bool IsAcceptingTokens {
445 return currentState.CanAcceptTokens;
449 public void PositionCursorAtNextPreProcessorDirective()
451 lexer.PositionCursorAtNextPreProcessorDirective();
454 public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
456 if(tok == IfElseStateMachine.Token.ENDIF) {
457 currentState = (State)stateStack.Pop();
459 if(currentState.CanAcceptTokens)
462 PositionCursorAtNextPreProcessorDirective();
467 if(tok == IfElseStateMachine.Token.IF) {
468 stateStack.Push(currentState);
470 currentState.CanAcceptTokens = parentState.CanAcceptTokens;
471 currentState.CanSelectBlock = true;
474 if(parentState.CanAcceptTokens &&
475 currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
477 currentState.CanAcceptTokens = true;
478 currentState.CanSelectBlock = false;
482 currentState.CanAcceptTokens = false;
483 PositionCursorAtNextPreProcessorDirective();
489 bool in_external_source = false;
490 int in_marked_region = 0;
492 TokenizerController tokenizerController;
493 IfElseStateMachine ifElseStateMachine;
500 %token NONE /* This token is never returned by our lexer */
501 %token ERROR // This is used not by the parser, but by the tokenizer.
505 *These are the MonoBASIC keywords
597 %token NOTINHERITABLE
598 %token NOTOVERRIDABLE
654 %token YIELD // MonoBASIC extension
658 /* MonoBASIC single character operators/punctuation. */
660 %token OPEN_BRACKET "["
661 %token CLOSE_BRACKET "]"
662 %token OPEN_PARENS "("
663 %token OPEN_BRACE "{"
664 %token CLOSE_BRACE "}"
665 %token CLOSE_PARENS ")"
679 %token OP_IDIV "\\" //FIXME: This should be "\"
681 %token EXCLAMATION "!"
684 %token LONGTYPECHAR "&"
686 %token SINGLETYPECHAR "!"
687 %token NUMBER_SIGN "#"
688 %token DOLAR_SIGN "$"
690 %token ATTR_ASSIGN ":="
692 /* MonoBASIC multi-character operators. */
697 //%token OP_MODULUS //"mod"
699 /* VB.NET 2003 new bit-shift operators */
700 %token OP_SHIFT_LEFT "<<"
701 %token OP_SHIFT_RIGHT ">>"
704 %token LITERAL_INTEGER "int literal"
705 %token LITERAL_SINGLE "float literal"
706 %token LITERAL_DOUBLE "double literal"
707 %token LITERAL_DECIMAL "decimal literal"
708 %token LITERAL_CHARACTER "character literal"
709 %token LITERAL_STRING "string literal"
710 %token LITERAL_DATE "datetime literal"
714 /* Add precedence rules to solve dangling else s/r conflict */
723 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
725 %left STAR DIV PERCENT
726 %right BITWISE_NOT CARRET UMINUS
727 %nonassoc OP_INC OP_DEC
729 %left OPEN_BRACKET OPEN_BRACE
734 %start compilation_unit
738 : logical_end_of_line
744 | logical_end_of_line pp_directive
748 : logical_end_of_line
749 opt_option_directives
750 opt_imports_directives
757 opt_option_directives
758 opt_imports_directives
766 opt_option_directives
773 | option_directives option_directive
777 : option_explicit_directive
778 | option_strict_directive
779 | option_compare_directive
808 option_explicit_directive
809 : OPTION EXPLICIT on_off logical_end_of_line
811 // if (!UseExtendedSyntax)
812 // OptionExplicit = (bool)$3;
815 // 9999, lexer.Location,
816 // "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
821 option_strict_directive
822 : OPTION STRICT on_off logical_end_of_line
824 // if (!UseExtendedSyntax)
825 // OptionStrict = (bool)$3;
828 // 9999, lexer.Location,
829 // "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
833 option_compare_directive
834 : OPTION COMPARE text_or_binary logical_end_of_line
836 // OptionCompareBinary = (bool)$3;
847 | declarations declaration
851 : declaration_qualifiers
853 // FIXME: Need to check declaration qualifiers for multi-file compilation
854 // FIXME: Qualifiers cannot be applied to namespaces
855 allow_global_attribs = false;
857 namespace_declaration
859 current_namespace.DeclarationFound = true;
861 | declaration_qualifiers
863 // FIXME: Need to check declaration qualifiers for multi-file compilation
864 allow_global_attribs = false;
866 type_spec_declaration
872 Class c = (Class) $3;
873 mod_flags = c.ModFlags;
875 } else if ($3 is Struct){
876 Struct s = (Struct) $3;
877 mod_flags = s.ModFlags;
882 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
884 1527, lexer.Location,
885 "Namespace elements cant be explicitly " +
886 "declared private or protected in `" + name + "'");
888 current_namespace.DeclarationFound = true;
902 : PERCENT { $$ = TypeManager.system_int32_expr; }
903 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
904 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
905 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
906 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
907 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
911 : /* empty */ { $$ = null; }
912 | type_character { $$ = $1; }
919 $$ = new MemberName ((string) $1);
921 | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
923 $$ = new MemberName ((MemberName) $1, (string) $3, null);
927 opt_imports_directives
934 | imports_directives imports_directive
938 : IMPORTS imports_terms logical_end_of_line
943 | imports_terms COMMA imports_term
947 : namespace_or_type_name
949 string name = ((MemberName) $1).GetName ();
950 current_namespace.Using (name, lexer.Location);
952 | identifier ASSIGN namespace_or_type_name
954 current_namespace.UsingAlias ((string) $1, (MemberName) $3, lexer.Location);
960 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
961 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
962 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
968 current_attributes = null;
973 local_attrib_section_added = false;
974 current_attributes = (Attributes) $1;
983 expecting_local_attribs = false;
984 expecting_global_attribs = false;
988 if (expecting_local_attribs) {
989 local_attrib_section_added = true;
990 allow_global_attribs = false;
992 $$ = new Attributes ((ArrayList) $1);
995 if (expecting_global_attribs) {
997 CodeGen.AddGlobalAttributes ((ArrayList) $1);
1000 expecting_local_attribs = false;
1001 expecting_global_attribs = false;
1003 | attribute_sections
1005 $$ = lexer.Location;
1011 ArrayList attrs = (ArrayList) $3;
1013 if (expecting_local_attribs) {
1014 if (local_attrib_section_added) {
1015 expecting_local_attribs = false;
1016 expecting_global_attribs = false;
1017 Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
1022 $$ = new Attributes (attrs);
1024 ((Attributes) $1).AddAttributes (attrs);
1026 local_attrib_section_added = true;
1027 allow_global_attribs = false;
1030 if (expecting_global_attribs) {
1032 CodeGen.AddGlobalAttributes ((ArrayList) $3);
1036 expecting_local_attribs = false;
1037 expecting_global_attribs = false;
1042 : OP_LT attribute_list OP_GT opt_end_of_stmt
1046 if (expecting_global_attribs && !(bool) $4) {
1047 Report.Error (30205, lexer.Location, "End of statement expected");
1051 if (expecting_local_attribs) {
1053 Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
1064 : /* empty */ { $$ = false; }
1065 | end_of_stmt { $$ = true; }
1071 ArrayList attrs = null;
1073 attrs = new ArrayList ();
1078 | attribute_list COMMA attribute
1080 ArrayList attrs = null;
1083 attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
1092 : namespace_or_type_name
1094 $$ = lexer.Location;
1096 opt_attribute_arguments
1100 if (expecting_global_attribs)
1101 Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
1103 expecting_local_attribs = true;
1104 MemberName mname = (MemberName) $1;
1105 string name = mname.GetName ();
1107 $$ = new Attribute (null, name, (ArrayList) $3,
1111 | attribute_target_specifier
1113 $$ = lexer.Location;
1116 namespace_or_type_name
1118 $$ = lexer.Location;
1120 opt_attribute_arguments
1124 string attribute_target = (string) $1;
1125 if (attribute_target != "assembly" && attribute_target != "module") {
1126 Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
1129 if (!allow_global_attribs) {
1130 Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
1134 if (expecting_local_attribs) {
1135 Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
1139 expecting_global_attribs = true;
1141 MemberName mname = (MemberName) $4;
1142 string aname = mname.GetName ();
1144 $$ = new Attribute (attribute_target, aname, (ArrayList) $6, (Location) $5);
1149 attribute_target_specifier
1150 : ASSEMBLY { $$ = "assembly"; }
1151 | MODULE { $$ = "module"; }
1152 | namespace_or_type_name
1156 opt_attribute_arguments
1157 : /* empty */ { $$ = null; }
1158 | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
1164 opt_attribute_arguments_list
1166 | attribute_arguments_list
1169 attribute_arguments_list
1170 : positional_argument_list
1172 ArrayList args = new ArrayList (4);
1177 | positional_argument_list COMMA named_argument_list
1179 ArrayList args = new ArrayList (4);
1185 | named_argument_list
1187 ArrayList args = new ArrayList (4);
1195 positional_argument_list
1196 : constant_expression
1198 ArrayList args = new ArrayList ();
1199 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
1203 | positional_argument_list COMMA constant_expression
1205 ArrayList args = (ArrayList) $1;
1206 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
1215 ArrayList args = new ArrayList ();
1220 | named_argument_list COMMA named_argument
1222 ArrayList args = (ArrayList) $1;
1230 : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
1232 $$ = new DictionaryEntry (
1234 new Argument ((Expression) $3, Argument.AType.Expression));
1238 namespace_declaration
1239 : NAMESPACE qualified_identifier logical_end_of_line
1241 if (current_attributes != null) {
1242 Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
1243 + " Expected class, delegate, enum, interface, or struct");
1246 MemberName name = (MemberName) $2;
1248 if ((current_namespace.Parent != null) && (name.Left != null)) {
1249 Report.Error (134, lexer.Location,
1250 "Cannot use qualified namespace names in nested " +
1251 "namespace declarations");
1254 current_namespace = new NamespaceEntry (
1255 current_namespace, file, name.GetName (), lexer.Location);
1258 END NAMESPACE logical_end_of_line
1260 current_namespace = current_namespace.Parent;
1265 declaration_qualifiers
1266 : opt_attributes opt_modifiers
1269 type_spec_declaration
1271 | module_declaration
1272 | interface_declaration
1273 | delegate_declaration
1274 | struct_declaration
1279 : CLASS identifier logical_end_of_line
1281 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1282 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1284 MemberName name = MakeName (new MemberName ((string) $2));
1285 int mod_flags = current_modifiers;
1288 current_class = new Class (current_namespace, current_container, name,
1289 mod_flags, (Attributes) current_attributes, lexer.Location);
1292 current_container = current_class;
1293 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
1295 opt_inherits opt_implements
1298 ArrayList bases = (ArrayList) $5;
1299 ArrayList ifaces = (ArrayList) $6;
1301 if (ifaces != null){
1303 bases.AddRange(ifaces);
1308 if (bases != null) {
1309 if (current_class.Name == "System.Object") {
1310 Report.Error (537, current_class.Location,
1311 "The class System.Object cannot have a base " +
1312 "class or implement an interface.");
1314 current_class.Bases = (ArrayList) bases;
1317 current_class.Register ();
1319 opt_class_member_declarations
1320 END CLASS logical_end_of_line
1324 current_container = current_container.Parent;
1325 current_class = current_container;
1330 : /* empty */ { $$ = null; }
1331 | INHERITS type_list logical_end_of_line { $$ = $2; }
1335 : /* empty */ { $$ = null; }
1336 | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
1343 current_modifiers = 0;
1348 current_modifiers = (int) $1;
1354 | modifiers modifier
1359 if ((m1 & m2) != 0) {
1360 Location l = lexer.Location;
1361 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
1363 $$ = (int) (m1 | m2);
1368 : PUBLIC { $$ = Modifiers.PUBLIC; }
1369 | PROTECTED { $$ = Modifiers.PROTECTED; }
1370 | PRIVATE { $$ = Modifiers.PRIVATE; }
1371 | SHARED { $$ = Modifiers.STATIC; }
1372 | FRIEND { $$ = Modifiers.INTERNAL; }
1373 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
1374 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
1375 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
1376 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
1377 | OVERLOADS { $$ = Modifiers.NEW; }
1378 | SHADOWS { $$ = Modifiers.SHADOWS; }
1379 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
1380 | READONLY { $$ = Modifiers.READONLY; }
1381 | DEFAULT { $$ = Modifiers.DEFAULT; }
1382 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
1386 : MODULE identifier logical_end_of_line
1388 MemberName name = MakeName(new MemberName ((string) $2));
1389 current_class = new VBModule (current_namespace, current_container, name,
1390 current_modifiers, current_attributes, lexer.Location);
1392 current_container = current_class;
1393 RootContext.Tree.RecordDecl(name.GetName (true), current_class);
1395 current_class.Register ();
1397 opt_module_member_declarations
1398 END MODULE logical_end_of_line
1402 // TypeManager.AddStandardModule (current_class);
1404 current_container = current_container.Parent;
1405 current_class = current_container;
1409 opt_module_member_declarations
1411 | module_member_declarations
1414 module_member_declarations
1415 : module_member_declaration
1416 | module_member_declarations module_member_declaration
1419 module_member_declaration
1423 current_modifiers = ((int)$2) | Modifiers.STATIC;
1424 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
1425 implicit_modifiers = (!explicit_static);
1428 module_member_declarator
1430 implicit_modifiers = false;
1435 module_member_declarator
1436 : constructor_declaration
1437 | method_declaration
1439 // | withevents_declaration /* This is a field but must be treated specially, see below */
1440 | constant_declaration
1441 | property_declaration
1443 | type_spec_declaration
1447 constant_declaration
1448 : CONST constant_declarators logical_end_of_line
1450 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1451 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1453 int modflags = (int) current_modifiers;
1455 // Structure members are Public by default
1456 if ((current_container is Struct) && (modflags == 0))
1457 modflags = Modifiers.PUBLIC;
1459 ArrayList consts = (ArrayList) $2;
1460 if(consts.Count > 0)
1462 VariableDeclaration.FixupTypes ((ArrayList) $2);
1463 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1465 foreach (VariableDeclaration constant in (ArrayList) $2){
1466 Location l = constant.Location;
1467 Const c = new Const (current_class,
1468 (Expression) constant.type,
1469 (String) constant.identifier,
1470 (Expression) constant.expression_or_array_initializer,
1471 modflags, current_attributes, l);
1473 current_container.AddConstant (c);
1479 opt_class_member_declarations
1481 | class_member_declarations
1484 class_member_declarations
1485 : class_member_declaration
1486 | class_member_declarations class_member_declaration
1489 class_member_declaration
1492 class_member_declarator
1498 class_member_declarator
1500 | constant_declaration
1501 | method_declaration
1502 | constructor_declaration
1503 | property_declaration
1505 // | withevents_declaration /* This is a field but must be treated specially, see below */
1506 | type_spec_declaration
1513 // | must_override_declaration
1516 // must_override_declaration
1517 // : must_override_sub_declaration
1518 // | must_override_func_declaration
1521 // must_override_sub_declaration
1522 // : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
1524 // // if (current_container is Module)
1525 // // Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1527 // if (current_container is Struct)
1528 // Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1530 // current_modifiers |= Modifiers.ABSTRACT;
1532 // Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1533 // (Parameters) $4, null, (ArrayList) $5, lexer.Location);
1535 // if (!(current_container is Class))
1536 // Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1543 // must_override_func_declaration
1544 // : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
1546 // Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.
1547 // system_object_expr : (Expression) $4 ) : (Expression) $6;
1549 // if (current_container is Module)
1550 // Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1552 // if (current_container is Struct)
1553 // Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1555 // current_modifiers |= Modifiers.ABSTRACT;
1557 // Method method = new Method ((Expression) ftype, (int) current_modifiers,
1558 // (string) $3,(Parameters) $5, null, (ArrayList) $7,
1561 // if (!(current_container is Class))
1562 // Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1570 : SUB identifier opt_params
1572 MemberName name = new MemberName ((string) $2);
1574 if ((current_container is Struct) && (current_modifiers == 0))
1575 current_modifiers = Modifiers.PUBLIC;
1578 GenericMethod generic = null;
1579 Method method = new Method (current_class, generic, TypeManager.system_void_expr,
1580 (int) current_modifiers, false, name,
1581 (Parameters) $3, (Attributes) current_attributes,
1584 current_local_parameters = (Parameters) $3;
1587 iterator_container = (IIteratorContainer) method;
1589 opt_evt_handler opt_implement_clause logical_end_of_line
1590 // FIXME: opt_event_handler and opt_implements_clause are yet to be handled
1594 END SUB logical_end_of_line
1596 Method method = (Method) $4;
1597 Block b = (Block) $10;
1598 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
1601 if ((method.ModFlags & extern_abstract) == 0){
1603 501, lexer.Location, current_container.MakeName (method.Name) +
1604 "must declare a body because it is not marked abstract or extern");
1607 if ((method.ModFlags & Modifiers.EXTERN) != 0){
1609 179, lexer.Location, current_container.MakeName (method.Name) +
1610 " is declared extern, but has a body");
1614 method.Block = (ToplevelBlock) $10;
1615 current_container.AddMethod (method);
1617 current_local_parameters = null;
1618 iterator_container = null;
1623 : FUNCTION identifier opt_type_character
1624 opt_params opt_type_with_ranks
1626 MemberName name = new MemberName ((string) $2);
1627 Expression rettype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1629 GenericMethod generic = null;
1631 Method method = new Method (current_class, generic, rettype, current_modifiers,
1632 false, name, (Parameters) $4, current_attributes,
1635 current_local_parameters = (Parameters) $4;
1638 iterator_container = method;
1640 // FIXME: opt_implement_clauses needs to be taken care of
1641 opt_implement_clause logical_end_of_line
1644 Method method = (Method) $6;
1646 ArrayList retval = new ArrayList ();
1647 retval.Add (new VariableDeclaration ((string) $2, method.Type, lexer.Location));
1648 declare_local_variables (method.Type, retval, lexer.Location);
1652 END FUNCTION logical_end_of_line
1654 Method method = (Method) $6;
1655 Block b = (Block) $12;
1656 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
1659 if ((method.ModFlags & extern_abstract) == 0){
1661 501, lexer.Location, current_container.MakeName (method.Name) +
1662 "must declare a body because it is not marked abstract or extern");
1665 if ((method.ModFlags & Modifiers.EXTERN) != 0){
1667 179, lexer.Location, current_container.MakeName (method.Name) +
1668 " is declared extern, but has a body");
1672 method.Block = (ToplevelBlock) b;
1673 current_container.AddMethod (method);
1675 current_local_parameters = null;
1676 iterator_container = null;
1681 : STRUCTURE identifier logical_end_of_line
1682 opt_implement_clause
1684 MemberName name = MakeName (new MemberName ((string) $2));
1686 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1687 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1689 current_class = new Struct (current_namespace, current_container, name, current_modifiers,
1690 current_attributes, lexer.Location);
1692 current_container = current_class;
1693 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
1696 current_class.Bases = (ArrayList) $4;
1698 current_class.Register ();
1700 opt_struct_member_declarations
1704 current_container = current_container.Parent;
1705 current_class = current_container;
1707 END STRUCTURE logical_end_of_line
1712 // FIXME: logical_end_of_line is actually part of the opt_implements_clause
1713 // This rule is temporary
1715 opt_logical_end_of_line
1717 | logical_end_of_line
1721 opt_struct_member_declarations
1723 | struct_member_declarations
1726 struct_member_declarations
1727 : struct_member_declaration
1728 | struct_member_declarations struct_member_declaration
1731 struct_member_declaration
1733 struct_member_declarator
1736 struct_member_declarator
1738 | constant_declaration
1739 | constructor_declaration
1740 | method_declaration
1741 // | property_declaration
1743 | type_spec_declaration
1746 // * This is only included so we can flag error 575:
1747 // * destructors only allowed on class types
1748 // | destructor_declaration
1751 // event_declaration
1752 // : EVENT identifier AS type opt_implement_clause logical_end_of_line
1754 // VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1756 // Event e = new Event ((Expression) $4, var.identifier,
1757 // null, current_modifiers,
1758 // current_attributes, (ArrayList) $5,
1761 // CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1763 // | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1765 // string delName = null;
1767 // if ($4 == null) {
1768 // delName = (string) $2;
1769 // delName = delName + "EventHandler";
1770 // Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1771 // (current_container, TypeManager.system_void_expr,
1772 // (int) current_modifiers, MakeName(delName), (Parameters) $3,
1773 // (Attributes) current_attributes, lexer.Location);
1775 // del.Namespace = current_namespace;
1776 // CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1778 // ArrayList impls = (ArrayList) $4;
1779 // if (impls.Count > 1) {
1780 // string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1781 // "' can not be implemented with Event '" +
1782 // (string) $2 + "', since it's delegate type does not match " +
1783 // "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1784 // Report.Error (31407, lexer.Location, expstr);
1786 // Expression impl = (Expression) impls[0];
1787 // delName = impl.ToString();
1788 // delName = delName.Substring (delName.LastIndexOf(".") + 1);
1789 // delName = delName + "EventHandler";
1792 // Event e = new Event (DecomposeQI (delName, lexer.Location),
1794 // null, current_modifiers,
1795 // current_attributes, (ArrayList) $4,
1798 // CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1805 : EVENT identifier AS type opt_implement_clause logical_end_of_line
1807 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1809 MemberName name = new MemberName ((string) $2);
1811 Event e = new EventField (current_class, (Expression) $4, current_modifiers, false, name,
1812 var.expression_or_array_initializer, current_attributes,
1815 current_container.AddEvent (e);
1818 // | EVENT identifier opt_params opt_implement_clause logical_end_of_line
1820 // string delName = null;
1822 // if ($4 == null) {
1823 // delName = (string) $2;
1824 // delName = delName + "EventHandler";
1825 // Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1826 // (current_container, TypeManager.system_void_expr,
1827 // (int) current_modifiers, MakeName(delName), (Parameters) $3,
1828 // (Attributes) current_attributes, lexer.Location);
1830 // del.Namespace = current_namespace;
1831 // CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1833 // ArrayList impls = (ArrayList) $4;
1834 // if (impls.Count > 1) {
1835 // string expstr = "Event '" + ((Expression) impls[1]).ToString () +
1836 // "' can not be implemented with Event '" +
1837 // (string) $2 + "', since it's delegate type does not match " +
1838 // "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
1839 // Report.Error (31407, lexer.Location, expstr);
1841 // Expression impl = (Expression) impls[0];
1842 // delName = impl.ToString();
1843 // delName = delName.Substring (delName.LastIndexOf(".") + 1);
1844 // delName = delName + "EventHandler";
1847 // Event e = new Event (DecomposeQI (delName, lexer.Location),
1849 // null, current_modifiers,
1850 // current_attributes, (ArrayList) $4,
1853 // CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1858 : ENUM identifier opt_type_spec logical_end_of_line
1859 opt_enum_member_declarations
1861 Location enum_location = lexer.Location;
1863 Expression base_type = TypeManager.system_int32_expr;
1864 if ((Expression) $3 != null)
1865 base_type = (Expression) $3;
1867 ArrayList enum_members = (ArrayList) $5;
1868 if (enum_members.Count == 0)
1869 Report.Error (30280, enum_location,
1870 "Enum can not have empty member list");
1873 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1874 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1876 MemberName full_name = MakeName (new MemberName ((string) $2));
1877 Enum e = new Enum (current_namespace, current_container, base_type,
1878 (int) current_modifiers, full_name,
1879 (Attributes) current_attributes, enum_location);
1881 foreach (VariableDeclaration ev in (ArrayList) $5) {
1882 e.AddEnumMember (ev.identifier,
1883 (Expression) ev.expression_or_array_initializer,
1884 ev.Location, ev.OptAttributes, ev.DocComment);
1887 string name = full_name.GetName ();
1888 current_container.AddEnum (e);
1889 RootContext.Tree.RecordDecl (name, e);
1892 END ENUM logical_end_of_line
1895 opt_enum_member_declarations
1896 : /* empty */ { $$ = new ArrayList (4); }
1897 | enum_member_declarations { $$ = $1; }
1900 enum_member_declarations
1901 : enum_member_declaration
1903 ArrayList l = new ArrayList ();
1908 | enum_member_declarations enum_member_declaration
1910 ArrayList l = (ArrayList) $1;
1918 enum_member_declaration
1919 : opt_attributes identifier logical_end_of_line
1921 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1923 | opt_attributes identifier
1925 $$ = lexer.Location;
1927 ASSIGN expression logical_end_of_line
1929 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1933 // interface_property_declaration
1934 // : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
1936 // Expression ftype = ($5 == null) ? (($3 == null) ?
1937 // TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
1939 // current_local_parameters = (Parameters) $4;
1940 // if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1941 // get_parameters = current_local_parameters.Copy (lexer.Location);
1942 // set_parameters = current_local_parameters.Copy (lexer.Location);
1944 // Parameter implicit_value_parameter = new Parameter (
1945 // ftype, "Value", Parameter.Modifier.NONE, null);
1947 // set_parameters.AppendParameter (implicit_value_parameter);
1951 // get_parameters = Parameters.EmptyReadOnlyParameters;
1952 // set_parameters = new Parameters (null, null ,lexer.Location);
1954 // Parameter implicit_value_parameter = new Parameter (
1955 // ftype, "Value", Parameter.Modifier.NONE, null);
1957 // set_parameters.AppendParameter (implicit_value_parameter);
1959 // lexer.PropertyParsing = true;
1961 // Accessor get_block = new Accessor (null, null);
1962 // Accessor set_block = new Accessor (null, null);
1964 // Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
1965 // get_block, set_block, current_attributes, lexer.Location,
1966 // null, get_parameters, set_parameters, null);
1968 // CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
1970 // get_implicit_value_parameter_type = null;
1971 // set_implicit_value_parameter_type = null;
1972 // get_parameters = null;
1973 // set_parameters = null;
1974 // current_local_parameters = null;
1978 // interface_event_declaration
1979 // : EVENT identifier AS type logical_end_of_line
1981 // VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1983 // Event e = new Event ((Expression) $4, var.identifier,
1984 // null, current_modifiers,
1985 // current_attributes, lexer.Location);
1987 // CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
1990 // | EVENT identifier opt_params logical_end_of_line
1992 // string delName = (string) $2;
1993 // delName = delName + "EventHandler";
1994 // int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
1995 // Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1996 // (current_container, TypeManager.system_void_expr,
1997 // (int) delModifiers, MakeName(delName), (Parameters) $3,
1998 // (Attributes) current_attributes, lexer.Location);
2000 // del.Namespace = current_namespace;
2001 // CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
2003 // Event e = new Event (DecomposeQI (delName, lexer.Location),
2005 // null, current_modifiers,
2006 // current_attributes, lexer.Location);
2008 // CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2014 //FIXME: This apparently doesn't seem to emit the right code with property
2015 //having opt_property_parameters defined
2017 interface_property_declaration
2018 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2020 get_implicit_value_parameter_type =
2021 ($5 == null) ? (($3 == null) ?
2022 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
2024 current_local_parameters = (Parameters) $4;
2025 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2026 get_parameters = current_local_parameters.Copy (lexer.Location);
2027 set_parameters = current_local_parameters.Copy (lexer.Location);
2029 Parameter implicit_value_parameter = new Parameter (
2030 get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
2032 set_parameters.AppendParameter (implicit_value_parameter);
2036 get_parameters = Parameters.EmptyReadOnlyParameters;
2037 set_parameters = new Parameters (null, null ,lexer.Location);
2039 Parameter implicit_value_parameter = new Parameter (
2040 get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
2042 set_parameters.AppendParameter (implicit_value_parameter);
2044 lexer.PropertyParsing = true;
2046 Location loc = lexer.Location;
2047 MemberName name = new MemberName ((string) $2);
2049 Accessor get_block = new Accessor (null, 0, null, loc);
2050 Accessor set_block = new Accessor (null, 0, null, loc);
2052 Property prop = new Property (current_class, get_implicit_value_parameter_type,
2053 (int) current_modifiers, true,
2054 name, current_attributes,
2055 get_parameters, get_block,
2056 set_parameters, set_block, lexer.Location);
2058 current_container.AddProperty (prop);
2060 get_implicit_value_parameter_type = null;
2061 set_implicit_value_parameter_type = null;
2062 get_parameters = null;
2063 set_parameters = null;
2064 current_local_parameters = null;
2069 // interface_event_declaration
2070 // : EVENT identifier AS type logical_end_of_line
2072 // VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
2074 // Event e = new Event ((Expression) $4, var.identifier,
2075 // null, current_modifiers,
2076 // current_attributes, lexer.Location);
2078 // CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2081 // | EVENT identifier opt_params logical_end_of_line
2083 // string delName = (string) $2;
2084 // delName = delName + "EventHandler";
2085 // int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
2086 // Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
2087 // (current_container, TypeManager.system_void_expr,
2088 // (int) delModifiers, MakeName(delName), (Parameters) $3,
2089 // (Attributes) current_attributes, lexer.Location);
2091 // del.Namespace = current_namespace;
2092 // CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
2094 // Event e = new Event (DecomposeQI (delName, lexer.Location),
2096 // null, current_modifiers,
2097 // current_attributes, lexer.Location);
2099 // CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
2103 interface_declaration
2104 : INTERFACE identifier logical_end_of_line
2106 MemberName name = new MemberName ((string) $2);
2108 current_class = new Interface (current_namespace, current_container,
2109 name, (int) current_modifiers,
2110 (Attributes) current_attributes, lexer.Location);
2112 current_container = current_class;
2113 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
2118 current_class.Bases = (ArrayList) $5;
2119 current_class.Register ();
2125 current_container = current_container.Parent;
2126 current_class = current_container;
2128 END INTERFACE logical_end_of_line
2132 : /* empty */ { $$ = null; }
2133 | interface_bases { $$ = $1; }
2138 | interface_bases interface_base
2140 ArrayList bases = (ArrayList) $1;
2141 bases.AddRange ((ArrayList) $2);
2147 : INHERITS type_list logical_end_of_line { $$ = $2; }
2151 : opt_interface_member_declarations
2154 opt_interface_member_declarations
2156 | interface_member_declarations
2159 interface_member_declarations
2160 : interface_member_declaration
2161 | interface_member_declarations interface_member_declaration
2164 interface_member_declaration
2165 : opt_attributes opt_modifiers interface_member_declarator
2168 interface_member_declarator
2169 : interface_method_declaration
2171 Method m = (Method) $1;
2173 current_container.AddMethod (m);
2175 | interface_property_declaration
2176 // | interface_event_declaration
2179 interface_method_declaration
2180 : SUB identifier opt_params logical_end_of_line
2182 MemberName name = (MemberName) new MemberName ((string) $2);
2184 GenericMethod generic = null;
2186 $$ = new Method (current_class, generic, TypeManager.system_void_expr,
2187 (int) current_modifiers, true, name, (Parameters) $3,
2188 (Attributes) current_attributes, lexer.Location);
2191 | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
2193 MemberName name = new MemberName ((string) $2);
2194 Expression return_type = ($5 == null) ?
2195 (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 )
2198 GenericMethod generic = null;
2199 $$ = new Method (current_class, generic, return_type, (int) current_modifiers,
2200 true, name, (Parameters) $4, (Attributes) current_attributes,
2205 property_declaration
2206 : non_abstract_propery_declaration
2207 // | abstract_propery_declaration
2210 // abstract_propery_declaration
2211 // : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
2213 // Expression ftype = ($6 == null) ? (($4 == null) ?
2214 // TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
2216 // if (current_container is Module)
2217 // Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
2219 // if (current_container is Struct)
2220 // Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
2222 // current_modifiers |= Modifiers.ABSTRACT;
2224 // current_local_parameters = (Parameters) $5;
2225 // if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2226 // get_parameters = current_local_parameters.Copy (lexer.Location);
2227 // set_parameters = current_local_parameters.Copy (lexer.Location);
2229 // Parameter implicit_value_parameter = new Parameter (
2230 // ftype, "Value", Parameter.Modifier.NONE, null);
2232 // set_parameters.AppendParameter (implicit_value_parameter);
2236 // get_parameters = Parameters.EmptyReadOnlyParameters;
2237 // set_parameters = new Parameters (null, null ,lexer.Location);
2239 // Parameter implicit_value_parameter = new Parameter (
2240 // ftype, "Value", Parameter.Modifier.NONE, null);
2242 // set_parameters.AppendParameter (implicit_value_parameter);
2244 // lexer.PropertyParsing = true;
2246 // Accessor get_block = new Accessor (null, null);
2247 // Accessor set_block = new Accessor (null, null);
2249 // Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
2250 // get_block, set_block, current_attributes, lexer.Location,
2251 // null, get_parameters, set_parameters, null);
2253 // if (!(current_container is Class))
2254 // Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
2256 // CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
2258 // get_implicit_value_parameter_type = null;
2259 // set_implicit_value_parameter_type = null;
2260 // get_parameters = null;
2261 // set_parameters = null;
2262 // current_local_parameters = null;
2266 non_abstract_propery_declaration
2267 : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
2269 get_implicit_value_parameter_type =
2270 ($5 == null) ? (($3 == null) ?
2271 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
2272 get_implicit_value_parameter_name = (string) $2;
2274 current_local_parameters = (Parameters) $4;
2275 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
2276 get_parameters = current_local_parameters.Copy (lexer.Location);
2277 set_parameters = current_local_parameters.Copy (lexer.Location);
2281 get_parameters = Parameters.EmptyReadOnlyParameters;
2282 set_parameters = new Parameters (null, null ,lexer.Location);
2284 lexer.PropertyParsing = true;
2286 $$ = lexer.Location;
2288 accessor_declarations
2289 END PROPERTY logical_end_of_line
2291 lexer.PropertyParsing = false;
2294 Pair pair = (Pair) $9;
2296 Accessor get_block = (Accessor) pair.First;
2297 Accessor set_block = (Accessor) pair.Second;
2299 Location loc = lexer.Location;
2300 MemberName name = new MemberName ((string) $2);
2302 // FIXME: Implements Clause needs to be taken care of.
2304 if ((current_container is Struct) && (current_modifiers == 0))
2305 current_modifiers = Modifiers.PUBLIC;
2308 prop = new Property (current_class, get_implicit_value_parameter_type,
2309 (int) current_modifiers, false,
2310 name, (Attributes) current_attributes,
2311 get_parameters, get_block,
2312 set_parameters, set_block, lexer.Location);
2314 current_container.AddProperty (prop);
2315 get_implicit_value_parameter_type = null;
2316 set_implicit_value_parameter_type = null;
2317 get_parameters = null;
2318 set_parameters = null;
2319 current_local_parameters = null;
2323 opt_property_parameters
2326 $$ = Parameters.EmptyReadOnlyParameters;
2328 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2334 opt_implement_clause
2339 | IMPLEMENTS implement_clause_list
2345 implement_clause_list
2346 : qualified_identifier
2348 MemberName mname = (MemberName) $1;
2349 ArrayList impl_list = new ArrayList ();
2350 impl_list.Add (mname.GetTypeExpression (lexer.Location));
2353 | implement_clause_list COMMA qualified_identifier
2355 MemberName mname = (MemberName) $3;
2356 ArrayList impl_list = (ArrayList) $1;
2357 impl_list.Add (mname.GetTypeExpression (lexer.Location));
2362 accessor_declarations
2363 : get_accessor_declaration opt_set_accessor_declaration
2365 $$ = new Pair ($1, $2);
2367 | set_accessor_declaration opt_get_accessor_declaration
2369 $$ = new Pair ($2, $1);
2373 opt_get_accessor_declaration
2374 : /* empty */ { $$ = null; }
2375 | get_accessor_declaration
2378 opt_set_accessor_declaration
2379 : /* empty */ { $$ = null; }
2380 | set_accessor_declaration
2383 get_accessor_declaration
2384 : opt_attributes GET logical_end_of_line
2386 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
2387 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
2389 current_local_parameters = get_parameters;
2391 lexer.PropertyParsing = false;
2396 ArrayList retval = new ArrayList ();
2397 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
2398 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
2402 END GET logical_end_of_line
2404 $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers,
2405 (Attributes) $1, lexer.Location);
2407 current_local_parameters = null;
2408 lexer.PropertyParsing = true;
2414 set_accessor_declaration
2415 : opt_attributes SET opt_set_parameter logical_end_of_line
2417 if ((current_modifiers & Modifiers.READONLY) != 0)
2418 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
2420 Parameter implicit_value_parameter = new Parameter (
2421 set_implicit_value_parameter_type,
2422 set_implicit_value_parameter_name,
2423 Parameter.Modifier.NONE, null);
2425 set_parameters.AppendParameter (implicit_value_parameter);
2426 current_local_parameters = set_parameters;
2428 lexer.PropertyParsing = false;
2433 END SET logical_end_of_line
2435 $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers,
2436 (Attributes) $1, lexer.Location);
2437 current_local_parameters = null;
2438 lexer.PropertyParsing = true;
2445 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
2446 set_implicit_value_parameter_name = "Value";
2448 |OPEN_PARENS CLOSE_PARENS
2450 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
2451 set_implicit_value_parameter_name = "Value";
2453 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
2455 Parameter.Modifier pm = (Parameter.Modifier)$2;
2456 if ((pm | Parameter.Modifier.VAL) != 0)
2457 Report.Error (31065,
2459 "Set cannot have a paremeter modifier other than 'ByVal'");
2461 set_implicit_value_parameter_type = (Expression) $4;
2463 if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
2464 Report.Error (31064,
2466 "Set value parameter type can not be different from property type");
2469 set_implicit_value_parameter_name = (string) $3;
2471 set_implicit_value_parameter_name = "Value";
2477 variable_declarators logical_end_of_line
2479 int mod = (int) current_modifiers;
2481 VariableDeclaration.FixupTypes ((ArrayList) $2);
2482 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
2484 // if (current_container is Module)
2485 // mod = mod | Modifiers.STATIC;
2487 // Structure members are Public by default
2488 if ((current_container is Struct) && (mod == 0))
2489 mod = Modifiers.PUBLIC;
2491 if ((mod & Modifiers.Accessibility) == 0)
2492 mod |= Modifiers.PRIVATE;
2494 foreach (VariableDeclaration var in (ArrayList) $2){
2495 Location l = var.Location;
2496 Field field = new Field (current_class, var.type, mod,
2497 var.identifier, var.expression_or_array_initializer,
2498 (Attributes) null, l);
2500 current_container.AddField (field);
2506 // withevents_declaration
2507 // : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
2509 // // Module members are static by default, but delegates *can't* be declared static
2510 // // so we must fix it, if mbas was the one actually responsible for this
2511 // // instead of triggering an error.
2512 // if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2513 // current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2515 // /* WithEvents Fields must be resolved into properties
2516 // with a bit of magic behind the scenes */
2518 // VariableDeclaration.FixupTypes ((ArrayList) $3);
2520 // foreach (VariableDeclaration var in (ArrayList) $3) {
2521 // // 1 - We create a private field
2522 // Location l = var.Location;
2524 // if ((current_modifiers & Modifiers.STATIC) > 0)
2525 // Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
2527 // Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
2528 // var.expression_or_array_initializer,
2529 // (Attributes) null, l);
2531 // CheckDef (current_container.AddField (field), field.Name, l);
2533 // // 2 - Public property
2535 // prop = BuildSimpleProperty (var.type, (string) var.identifier,
2536 // field, (int) current_modifiers,
2537 // (Attributes) current_attributes, l);
2539 // CheckDef (current_container.AddProperty (prop), prop.Name, l);
2549 delegate_declaration
2551 identifier OPEN_PARENS
2552 opt_formal_parameter_list
2556 Location l = lexer.Location;
2557 MemberName name = MakeName (new MemberName ((string) $3));
2559 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2560 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2562 Delegate del = new Delegate (current_namespace, current_container, TypeManager.system_void_expr,
2563 current_modifiers, name, (Parameters) $5, current_attributes, l);
2565 current_container.AddDelegate (del);
2566 RootContext.Tree.RecordDecl (name.GetName (true), del);
2570 identifier OPEN_PARENS
2571 opt_formal_parameter_list
2572 CLOSE_PARENS opt_type_with_ranks logical_end_of_line
2574 Location l = lexer.Location;
2575 MemberName name = MakeName (new MemberName ((string) $3));
2577 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
2578 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
2580 Expression rettype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
2581 Delegate del = new Delegate (current_namespace, current_container, rettype,
2582 current_modifiers, name, (Parameters) $5, current_attributes, l);
2584 current_container.AddDelegate (del);
2585 RootContext.Tree.RecordDecl (name.GetName (true), del);
2592 : /* empty */ { $$ = null; }
2593 // | HANDLES evt_handler { $$ = $2; }
2597 // : qualified_identifier
2599 // $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);
2605 // | ME DOT qualified_identifier
2607 // $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);
2609 // /*| MYBASE DOT qualified_identifier
2611 // // FIXME: this is blatantly wrong and crash-prone
2612 // $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
2617 constructor_declaration
2618 : SUB NEW opt_params logical_end_of_line
2620 current_local_parameters = (Parameters) $3;
2621 $$ = new Constructor (current_class, current_container.Basename, 0, (Parameters) $3,
2622 (ConstructorInitializer) null, lexer.Location);
2628 Constructor c = (Constructor) $5;
2629 c.Block = (ToplevelBlock) $8;
2630 c.ModFlags = (int) current_modifiers;
2631 c.OptAttributes = current_attributes;
2633 // FIXME: Some more error checking from mcs needs to be merged here ???
2635 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
2637 current_container.AddConstructor(c);
2638 current_local_parameters = null;
2640 END SUB logical_end_of_line
2643 opt_formal_parameter_list
2646 $$ = Parameters.EmptyReadOnlyParameters;
2648 | formal_parameter_list
2654 formal_parameter_list
2657 ArrayList pars_list = (ArrayList) $1;
2658 Parameter [] pars = null;
2659 Parameter array_parameter = null;
2660 int non_array_count = pars_list.Count;
2661 if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
2662 array_parameter = (Parameter) pars_list [pars_list.Count - 1];
2663 non_array_count = pars_list.Count - 1;
2665 foreach (Parameter par in pars_list)
2666 if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
2667 Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
2668 non_array_count = 0;
2669 array_parameter = null;
2672 if (non_array_count > 0) {
2673 pars = new Parameter [non_array_count];
2674 pars_list.CopyTo (0, pars, 0, non_array_count);
2676 $$ = new Parameters (pars, array_parameter, lexer.Location);
2683 ArrayList pars = new ArrayList ();
2688 | parameters COMMA parameter
2690 ArrayList pars = (ArrayList) $1;
2699 opt_parameter_modifier
2700 identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
2702 Parameter.Modifier pm = (Parameter.Modifier)$2;
2703 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
2706 if (opt_parm && ($7 == null))
2707 Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
2709 if (!opt_parm && ($7 != null))
2710 Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
2712 if ((pm & Parameter.Modifier.PARAMS) != 0) {
2713 if ((pm & ~Parameter.Modifier.PARAMS) != 0)
2714 Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
2717 if ((pm & Parameter.Modifier.REF) !=0)
2718 pm |= Parameter.Modifier.ISBYREF;
2720 if ($4 != null && $6 != null && $4 != $6)
2721 Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
2723 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
2725 string t = ptype.ToString ();
2726 if (t.IndexOf('[') >= 0)
2727 Report.Error (31087, lexer.Location, "Array types specified in too many places");
2729 ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
2731 if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
2732 Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
2733 $$ = new Parameter (ptype, (string) $3, pm,
2734 (Attributes) $1, (Expression) $7, opt_parm);
2738 opt_parameter_modifier
2739 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2740 | parameter_modifiers { $$ = $1; }
2744 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2745 | parameter_modifier { $$ = $1; }
2749 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2750 | BYVAL { $$ = Parameter.Modifier.VAL; }
2751 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2752 | PARAM_ARRAY { $$ = Parameter.Modifier.PARAMS; }
2757 | statement_list end_of_stmt
2762 | statement_list end_of_stmt statement
2768 end_block { $$ = $3; }
2774 if (current_block == null){
2775 current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
2776 top_current_block = current_block;
2778 current_block = new Block (current_block, current_local_parameters,
2779 lexer.Location, Location.Null);
2788 while (current_block.Implicit)
2789 current_block = current_block.Parent;
2791 current_block.SetEndLocation (lexer.Location);
2792 current_block = current_block.Parent;
2793 if (current_block == null)
2794 top_current_block = null;
2799 : declaration_statement
2801 if ($1 != null && (Block) $1 != current_block){
2802 current_block.AddStatement ((Statement) $1);
2803 current_block = (Block) $1;
2806 | embedded_statement
2808 Statement s = (Statement) $1;
2810 current_block.AddStatement ((Statement) $1);
2812 // | labeled_statement
2813 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
2815 Location loc = lexer.Location;
2817 ExpressionStatement expr = new CompoundAssign (Binary.Operator.Addition,
2818 (Expression) $2, (Expression) $5, loc);
2820 Statement stmt = new StatementExpression (expr, loc);
2822 current_block.AddStatement (stmt);
2826 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
2828 Location loc = lexer.Location;
2830 ExpressionStatement expr = new CompoundAssign (Binary.Operator.Subtraction,
2831 (Expression) $2, (Expression) $5, loc);
2833 Statement stmt = new StatementExpression (expr, loc);
2835 current_block.AddStatement (stmt);
2838 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2840 Location loc = lexer.Location;
2841 MemberName mname = new MemberName ((string) $2);
2842 Expression expr = mname.GetTypeExpression (loc);
2844 Invocation inv_expr = new Invocation (expr, (ArrayList) $3, loc);
2845 Statement stmt = new StatementExpression (inv_expr, loc);
2846 current_block.AddStatement (stmt);
2848 // /* | array_handling_statement */
2849 // /* | empty_statement */
2852 // Statement s = (Statement) $1;
2854 // current_block.AddStatement ((Statement) $1);
2859 opt_raise_event_args
2860 : /* empty */ { $$ = null; }
2861 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2869 // | LITERAL_INTEGER
2871 // $$ = $1.ToString();
2875 // labeled_statement
2876 // : label_name COLON
2878 // LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2880 // if (!current_block.AddLabel ((string) $1, labeled)){
2881 // Location l = lexer.Location;
2882 // Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2884 // current_block.AddStatement (labeled);
2886 // | label_name COLON
2888 // LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2890 // if (!current_block.AddLabel ((string) $1, labeled)){
2891 // Location l = lexer.Location;
2892 // Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2894 // current_block.AddStatement (labeled);
2900 : expression_statement
2901 | selection_statement
2902 // | iteration_statement
2904 | synclock_statement
2906 // | array_handling_statement
2913 // $$ = new EmptyStatement ();
2919 // : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2921 // // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2922 // Expression e = (Expression) $2;
2923 // with_stack.Push(e);
2926 // opt_statement_list
2929 // Block b = end_block();
2930 // with_stack.Pop();
2936 // array_handling_statement
2937 // : redim_statement
2938 // | erase_statement
2942 // : REDIM opt_preserve redim_clauses
2944 // ArrayList list = (ArrayList) $3;
2945 // ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2952 // : /* empty */ { $$ = false; }
2953 // | PRESERVE { $$ = true; }
2959 // ArrayList clauses = new ArrayList ();
2961 // clauses.Add ($1);
2964 // | redim_clauses COMMA redim_clause
2966 // ArrayList clauses = (ArrayList) ($1);
2967 // clauses.Add ($2);
2974 // : invocation_expression
2976 // Invocation i = (Invocation) $1;
2977 // RedimClause rc = new RedimClause (i.expr, i.Arguments);
2983 // : ERASE erase_clauses
2985 // ArrayList list = (ArrayList) $2;
2986 // foreach(Expression e in list)
2988 // Erase r = new Erase (e, lexer.Location);
2997 // ArrayList clauses = new ArrayList ();
2999 // clauses.Add ($1);
3002 // | erase_clauses COMMA erase_clause
3004 // ArrayList clauses = (ArrayList) ($1);
3005 // clauses.Add ($2);
3012 // : primary_expression
3017 | continue_statement
3018 | */return_statement
3022 // | yield_statement
3028 $$ = new Goto (current_block, (string) $2, lexer.Location);
3033 : THROW opt_expression
3035 $$ = new Throw ((Expression) $2, lexer.Location);
3042 // $$ = new Exit ((ExitType)$2, lexer.Location);
3047 // : DO { $$ = ExitType.DO; }
3048 // | FOR { $$ = ExitType.FOR; }
3049 // | WHILE { $$ = ExitType.WHILE; }
3050 // | SELECT { $$ = ExitType.SELECT; }
3051 // | SUB { $$ = ExitType.SUB; }
3052 // | FUNCTION { $$ = ExitType.FUNCTION; }
3053 // | PROPERTY { $$ = ExitType.PROPERTY; }
3054 // | TRY { $$ = ExitType.TRY; }
3058 : RETURN opt_expression
3060 $$ = new Return ((Expression) $2, lexer.Location);
3064 // iteration_statement
3065 // : while_statement
3068 // | foreach_statement
3071 // foreach_statement
3072 // : FOR EACH identifier opt_type_spec IN
3074 // oob_stack.Push (lexer.Location);
3076 // expression end_of_stmt
3078 // Location l = lexer.Location;
3079 // LocalVariableReference v = null;
3085 // VariableDeclaration decl = new VariableDeclaration ((string) $3,
3086 // (Expression) $4, null, lexer.Location, null);
3088 // vi = current_block.AddVariable (
3089 // (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
3092 // if (decl.expression_or_array_initializer is Expression)
3093 // expr = (Expression) decl.expression_or_array_initializer;
3094 // else if (decl.expression_or_array_initializer == null)
3098 // ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3099 // expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
3102 // v = new LocalVariableReference (current_block, decl.identifier, l);
3104 // if (expr != null)
3106 // Assign a = new Assign (v, expr, decl.Location);
3107 // current_block.AddStatement (new StatementExpression (a, lexer.Location));
3112 // vi = current_block.GetVariableInfo ((string) $3);
3114 // if (vi != null) {
3115 // // Get a reference to this variable.
3116 // v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
3119 // Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
3122 // oob_stack.Push (v);
3125 // opt_statement_list
3126 // NEXT opt_identifier
3128 // LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
3129 // Block foreach_block = end_block();
3130 // Location l = (Location) oob_stack.Pop ();
3132 // Foreach f = null;
3134 // f = new Foreach (null, v, (Expression) $7, foreach_block, l);
3138 // current_block.AddStatement (f);
3139 // $$ = end_block ();
3147 // : YIELD expression
3149 // if (!UseExtendedSyntax)
3151 // ReportError9998();
3155 // if (iterator_container == null){
3156 // Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3159 // iterator_container.SetYields ();
3160 // $$ = new Yield ((Expression) $2, lexer.Location);
3165 // if (!UseExtendedSyntax)
3167 // ReportError9998();
3171 // if (iterator_container == null){
3172 // Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
3175 // iterator_container.SetYields ();
3176 // $$ = new YieldBreak (lexer.Location);
3182 : SYNCLOCK expression end_of_stmt
3186 $$ = new Lock ((Expression) $2, (Statement) $4, lexer.Location);
3197 : TRY end_of_stmt block opt_catch_clauses END TRY
3201 ArrayList c = (ArrayList)$4;
3202 for (int i = 0; i < c.Count; ++i) {
3203 Catch cc = (Catch) c [i];
3205 if (i != c.Count - 1)
3206 Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks");
3213 // Now s contains the list of specific catch clauses
3214 // and g contains the general one.
3216 $$ = new Try ((Block) $3, c, g, null, ((Block) $3).loc);
3229 ArrayList s = new ArrayList (4);
3230 ArrayList catch_list = (ArrayList) $4;
3232 if (catch_list != null){
3233 foreach (Catch cc in catch_list) {
3241 $$ = new Try ((Block) $3, s, g, (Block) $7, ((Block) $3).loc);
3246 : /* empty */ { $$ = null; }
3253 ArrayList l = new ArrayList (4);
3258 | catch_clauses catch_clause
3260 ArrayList l = (ArrayList) $1;
3268 : /* empty */ { $$ = null; }
3273 // : /* empty */ { $$ = null; }
3274 // | WHEN boolean_expression { $$ = $2; }
3279 // : CATCH opt_catch_args opt_when end_of_stmt
3280 : CATCH opt_catch_args end_of_stmt
3282 // FIXME: opt_when needs to be hnadled
3283 Expression type = null;
3287 DictionaryEntry cc = (DictionaryEntry) $2;
3288 type = (Expression) cc.Key;
3289 id = (string) cc.Value;
3292 ArrayList one = new ArrayList (4);
3293 Location loc = lexer.Location;
3295 one.Add (new VariableDeclaration (id, type, loc));
3298 current_block = new Block (current_block);
3299 Block b = declare_local_variables (type, one, loc);
3306 Expression type = null;
3310 DictionaryEntry cc = (DictionaryEntry) $2;
3311 type = (Expression) cc.Key;
3312 id = (string) cc.Value;
3316 // FIXME: I can change this for an assignment.
3318 while (current_block != (Block) $1)
3319 current_block = current_block.Parent;
3324 $$ = new Catch (type, id , (Block) $5, ((Block) $5).loc);
3329 : /* empty */ { $$ = null; }
3334 : identifier AS type
3336 $$ = new DictionaryEntry ($3, $1);
3342 // : DO opt_do_construct end_of_stmt
3345 // oob_stack.Push (lexer.Location);
3347 // opt_statement_list
3348 // LOOP opt_do_construct
3350 // Expression t_before = (Expression) $2;
3351 // Expression t_after = (Expression) $7;
3354 // if ((t_before != null) && (t_after != null))
3355 // Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
3357 // if ((t_before == null) && (t_after == null))
3358 // t = new BoolLiteral (true);
3360 // t = (t_before != null) ? t_before : t_after;
3362 // DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
3364 // if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
3365 // ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
3366 // t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
3368 // $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
3373 // : /* empty */ { $$ = null; }
3374 // | while_or_until boolean_expression
3376 // do_type = (DoOptions)$1;
3377 // $$ = (Expression) $2;
3382 // : WHILE { $$ = DoOptions.WHILE; }
3383 // | UNTIL { $$ = DoOptions.UNTIL; }
3389 oob_stack.Push (lexer.Location);
3391 boolean_expression end_of_stmt
3397 Location l = (Location) oob_stack.Pop ();
3398 $$ = new While ((Expression) $3, (Statement) $7, l);
3403 // : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
3408 // ArrayList VarDeclaration = new ArrayList ();
3409 // VarDeclaration.Add (new VariableDeclaration ((string) $2,
3410 // (Expression) $3, null, lexer.Location, null));
3412 // DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
3413 // Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3414 // current_block = b;
3416 // oob_stack.Push (lexer.Location);
3419 // opt_statement_list
3420 // NEXT opt_identifier
3422 // Block inner_statement = end_block();
3423 // Location l = (Location) oob_stack.Pop ();
3424 // Expression for_var = (Expression) DecomposeQI ((string)$2, l);
3426 // Expression assign_expr = new Assign (for_var, (Expression) $5, l);
3427 // Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
3428 // for_var, (Expression) $7, l);
3429 // Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
3430 // for_var, (Expression) $8, l), l);
3432 // Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
3433 // Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
3435 // For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
3438 // current_block.AddStatement (f);
3439 // $$ = end_block();
3447 // : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
3448 // | STEP expression { $$ = $2; }
3453 // | select_statement
3457 // : IF boolean_expression opt_then end_of_stmt
3458 // if_statement_rest
3459 // // | IF boolean_expression THEN block opt_else_pre_embedded_statement
3460 // // | IF boolean_expression else_pre_embedded_statement
3464 // FXIME: The rule for LineIfThenStatement needs to be still enabled
3465 // FIXME: The lexer.Location that is calculated may have to replaced with the most correct one
3468 : IF boolean_expression opt_then end_of_stmt
3472 oob_stack.Push (lexer.Location);
3473 Location l = (Location) oob_stack.Pop ();
3475 $$ = new If ((Expression) $2, (Statement) $5, l);
3477 if (RootContext.WarningLevel >= 3){
3478 if ($5 == EmptyStatement.Value)
3479 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3484 | IF boolean_expression opt_then end_of_stmt
3490 oob_stack.Push (lexer.Location);
3491 Location l = (Location) oob_stack.Pop ();
3493 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
3496 | IF boolean_expression opt_then end_of_stmt
3498 else_if_statement_rest
3500 oob_stack.Push (lexer.Location);
3501 Location l = (Location) oob_stack.Pop ();
3503 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
3507 else_if_statement_rest
3508 : ELSEIF boolean_expression opt_then end_of_stmt
3512 oob_stack.Push (lexer.Location);
3513 Location l = (Location) oob_stack.Pop ();
3515 $$ = new If ((Expression) $2, (Statement) $5, l);
3517 if (RootContext.WarningLevel >= 3){
3518 if ($5 == EmptyStatement.Value)
3519 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3524 | ELSEIF boolean_expression opt_then end_of_stmt
3530 oob_stack.Push (lexer.Location);
3531 Location l = (Location) oob_stack.Pop ();
3533 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
3536 | ELSEIF boolean_expression opt_then end_of_stmt
3538 else_if_statement_rest
3540 oob_stack.Push (lexer.Location);
3541 Location l = (Location) oob_stack.Pop ();
3543 $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
3548 // opt_else_pre_embedded_statement
3550 // | else_pre_embedded_statement
3553 // else_pre_embedded_statement
3556 // Block bl = end_block();
3557 // tmp_blocks.Push(bl);
3561 // | ELSE embedded_statement
3563 // Block bl = end_block();
3564 // tmp_blocks.Push(bl);
3567 // Statement s = (Statement) $2;
3568 // current_block.AddStatement ((Statement) $2);
3580 // : SELECT opt_case expression end_of_stmt
3582 // oob_stack.Push (lexer.Location);
3583 // switch_stack.Push (current_block);
3585 // opt_case_sections
3588 // $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
3589 // current_block = (Block) switch_stack.Pop ();
3593 // opt_case_sections
3594 // : /* empty */ { $$ = null; }
3595 // | case_sections { $$ = $1; }
3599 // : case_sections case_section
3601 // ArrayList sections = (ArrayList) $1;
3603 // sections.Add ($2);
3608 // ArrayList sections = new ArrayList (4);
3610 // sections.Add ($1);
3617 // | ends end_of_stmt
3622 // : CASE case_clauses ends
3626 // opt_statement_list
3628 // //Block topmost = current_block;
3629 // Block topmost = end_block();
3631 // while (topmost.Implicit)
3632 // topmost = topmost.Parent;
3634 // // FIXME: This is a horrible hack which MUST go
3635 // topmost.statements.Add (new Break (lexer.Location));
3636 // $$ = new SwitchSection ((ArrayList) $2, topmost);
3639 // /* FIXME: we should somehow flag an error
3640 // (BC30321 'Case' cannot follow a 'Case Else'
3641 // in the same 'Select' statement.)
3642 // if Case Else is not the last of the Case clauses
3647 // opt_statement_list
3649 // //Block topmost = current_block;
3650 // Block topmost = end_block();
3652 // while (topmost.Implicit)
3653 // topmost = topmost.Parent;
3655 // // FIXME: This is a horrible hack which MUST go
3656 // topmost.statements.Add (new Break (lexer.Location));
3658 // ArrayList a = new ArrayList();
3659 // a.Add (new SwitchLabel (null, lexer.Location));
3660 // $$ = new SwitchSection ((ArrayList) a, topmost);
3668 ArrayList labels = new ArrayList ();
3673 | case_clauses COMMA case_clause
3675 ArrayList labels = (ArrayList) ($1);
3683 : opt_is comparison_operator expression
3686 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
3708 expression_statement
3709 : statement_expression
3716 statement_expression
3717 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3718 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3719 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3722 object_creation_expression
3723 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3725 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
3729 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
3734 // array_creation_expression
3735 // : object_creation_expression opt_rank_specifiers array_initializer
3737 // New n = (New) $1;
3738 // ArrayList dims = new ArrayList();
3740 // if (n.Arguments != null) {
3741 // foreach (Argument a in n.Arguments) {
3742 // dims.Add (a.Expr);
3746 // Expression atype = n.RequestedType;
3749 // atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
3751 // ArrayList init = (ArrayList) $3;
3752 // if (init.Count == 0)
3755 // if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
3756 // VariableDeclaration.VBFixIndexList (ref dims);
3757 // $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
3761 // string rank = VariableDeclaration.BuildRank (dims);
3762 // $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location);
3764 // //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
3769 : object_creation_expression
3770 // | array_creation_expression
3773 declaration_statement
3774 : local_variable_declaration
3777 DictionaryEntry de = (DictionaryEntry) $1;
3779 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3782 | local_constant_declaration
3785 DictionaryEntry de = (DictionaryEntry) $1;
3787 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
3792 local_variable_declaration
3793 : DIM variable_declarators
3795 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
3800 local_constant_declaration
3801 : CONST constant_declarators
3804 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
3810 constant_declarators
3811 : constant_declarator
3813 ArrayList decl = new ArrayList ();
3819 | constant_declarators COMMA constant_declarator
3821 ArrayList decls = (ArrayList) $1;
3830 : variable_name opt_type_decl opt_variable_initializer
3832 VarName vname = (VarName) $1;
3833 string varname = (string) vname.Name;
3834 current_rank_specifiers = (ArrayList) vname.Rank;
3835 object varinit = $3;
3836 ArrayList a_dims = null;
3838 if (varinit == null)
3840 30438, lexer.Location, "Constant should have a value"
3843 if (vname.Type != null && $2 != null)
3845 30302, lexer.Location,
3846 "Type character cannot be used with explicit type declaration" );
3848 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3850 if (current_rank_specifiers != null)
3852 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3856 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3860 variable_declarators
3861 : variable_declarator
3863 ArrayList decl = new ArrayList ();
3864 decl.AddRange ((ArrayList) $1);
3867 | variable_declarators COMMA variable_declarator
3869 ArrayList decls = (ArrayList) $1;
3870 decls.AddRange ((ArrayList) $3);
3876 : variable_names opt_type_decl opt_variable_initializer
3878 ArrayList names = (ArrayList) $1;
3879 object varinit = $3;
3880 ArrayList VarDeclarations = new ArrayList();
3882 ArrayList a_dims = null;
3884 if ((names.Count > 1) && (varinit != null))
3886 30671, lexer.Location,
3887 "Multiple variables with single type can not have " +
3888 "a explicit initialization" );
3891 foreach (VarName vname in names)
3893 string varname = (string) vname.Name;
3894 current_rank_specifiers = (ArrayList) vname.Rank;
3898 if(vname.Type != null && $2 != null)
3900 30302, lexer.Location,
3901 "Type character cannot be used with explicit type declaration" );
3903 // Some checking is required for particularly weird declarations
3904 // like Dim a As Integer(,)
3906 vartype = (Expression) ((Pair) $2).First;
3908 /*if ($3 != null && $3 is ArrayList)
3909 Report.Error (205, "End of statement expected.");*/
3911 ArrayList args = (ArrayList) ((Pair) $2).Second;
3912 if (current_rank_specifiers != null)
3913 Report.Error (31087, lexer.Location,
3914 "Array types specified in too many places");
3916 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3917 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3919 current_rank_specifiers = new ArrayList ();
3920 current_rank_specifiers.Add (args);
3923 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3925 // if the variable is an array with explicit bound
3926 // and having explicit initialization throw exception
3927 if (current_rank_specifiers != null && varinit != null)
3929 bool broken = false;
3930 foreach (ArrayList exprs in current_rank_specifiers)
3932 foreach (Expression expr in exprs)
3934 if (!((Expression)expr is EmptyExpression ))
3937 30672, lexer.Location,
3938 "Array declared with explicit bound " +
3939 " can not have explicit initialization");
3950 Check for a declaration like Dim a(2) or Dim a(2,3)
3951 If this is the case, we must generate an ArrayCreationExpression
3952 and, in case, add the initializer after the array has been created.
3954 // if (VariableDeclaration.IsArrayDecl (this)) {
3955 // if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3956 // a_dims = (ArrayList) current_rank_specifiers;
3957 // VariableDeclaration.VBFixIndexLists (ref a_dims);
3958 // varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3960 // vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
3963 if (vartype is New) {
3964 if (varinit != null) {
3965 Report.Error (30205, lexer.Location, "End of statement expected");
3971 vartype = ((New)vartype).RequestedType;
3974 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3976 $$ = VarDeclarations;
3983 ArrayList list = new ArrayList ();
3987 | variable_names COMMA variable_name
3989 ArrayList list = (ArrayList) $1;
3996 : identifier opt_type_character opt_array_name_modifier
3998 $$ = new VarName ($1, $2, $3);
4009 $$ = (Expression) $2;
4015 // | AS type rank_specifiers
4017 // // $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
4022 : opt_type_with_ranks
4028 New n = new New ((Expression)$3, null, lexer.Location);
4029 $$ = (Expression) n;
4031 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
4033 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
4034 $$ = (Expression) n;
4036 /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
4038 ArrayList args = new ArrayList();
4039 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
4042 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
4043 $$ = (Expression) n;
4047 opt_array_name_modifier
4048 : /* empty */ { $$ = null; }
4049 // | array_type_modifier { $$ = $1; }
4052 // array_type_modifier
4053 // : rank_specifiers { $$ = $1; }
4056 opt_variable_initializer
4057 : /* empty */ { $$ = null; }
4058 | ASSIGN variable_initializer { $$ = $2; }
4061 variable_initializer
4074 : OPEN_BRACE CLOSE_BRACE
4076 ArrayList list = new ArrayList ();
4079 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
4081 $$ = (ArrayList) $2;
4085 variable_initializer_list
4086 : variable_initializer
4088 ArrayList list = new ArrayList ();
4092 | variable_initializer_list COMMA variable_initializer
4094 ArrayList list = (ArrayList) $1;
4115 ArrayList rs = new ArrayList();
4119 | rank_specifiers rank_specifier
4121 ArrayList rs = (ArrayList) $1;
4128 : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
4137 ArrayList ds = new ArrayList();
4138 ds.Add (new EmptyExpression());
4143 ArrayList ds = new ArrayList();
4144 ds.Add ((Expression) $1);
4147 | opt_dim_specifiers COMMA expression
4149 ArrayList ds = (ArrayList) $1;
4150 ds.Add ((Expression) $3);
4153 | opt_dim_specifiers COMMA
4155 ArrayList ds = (ArrayList) $1;
4156 ds.Add (new EmptyExpression());
4161 // primary_expression
4166 // | parenthesized_expression
4169 // | qualified_identifier
4171 // string name = (string) $1;
4172 // $$ = DecomposeQI (name, lexer.Location);
4174 // | get_type_expression
4176 // | invocation_expression
4177 // //| element_access
4179 // | cast_expression
4187 | parenthesized_expression
4190 | qualified_identifier
4192 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
4194 | get_type_expression
4196 | invocation_expression
4208 // | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
4209 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
4210 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
4211 | NOTHING { $$ = NullLiteral.Null; }
4215 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
4216 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
4217 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
4222 object v = lexer.Value;
4225 $$ = new IntLiteral ((Int32)v);
4226 // else if (v is short)
4227 // $$ = new ShortLiteral ((Int16)v);
4229 $$ = new LongLiteral ((Int64)v);
4231 Console.WriteLine ("OOPS. Unexpected result from scanner");
4237 : TRUE { $$ = new BoolLiteral (true); }
4238 | FALSE { $$ = new BoolLiteral (false); }
4241 parenthesized_expression
4242 : OPEN_PARENS expression CLOSE_PARENS
4247 : primary_expression DOT identifier
4250 string id_name = (string)$3;
4251 if (id_name.ToUpper() == "NEW")
4253 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
4257 // if (with_stack.Count > 0) {
4258 // Expression e = (Expression) with_stack.Peek();
4259 // $$ = new MemberAccess (e, (string) $3, lexer.Location);
4267 /* | primary_expression DOT NEW
4269 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
4271 | predefined_type DOT identifier
4274 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
4277 // if (with_stack.Count > 0) {
4278 // Expression e = (Expression) with_stack.Peek();
4279 // $$ = new MemberAccess (e, (string) $3, lexer.Location);
4293 invocation_expression
4294 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
4297 Location l = lexer.Location;
4298 Report.Error (1, l, "Parse error");
4300 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
4302 | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
4305 Location l = lexer.Location;
4306 Report.Error (1, l, "THIS IS CRAZY");
4308 $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
4309 // Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
4314 : MYBASE DOT IDENTIFIER
4316 string id_name = (string) $3;
4317 if (id_name.ToUpper() == "NEW")
4319 $$ = new BaseAccess (id_name, lexer.Location);
4323 $$ = new BaseAccess ("New", lexer.Location);
4331 The 'argument' rule returns an 'empty' argument
4332 of type NoArg (used for default arguments in invocations)
4333 if no arguments are actually passed.
4335 If there is only one argument and it is o type NoArg,
4336 we return a null (empty) list
4338 ArrayList args = (ArrayList) $1;
4339 if (args.Count == 1 &&
4340 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
4350 ArrayList list = new ArrayList ();
4354 | argument_list COMMA argument
4356 ArrayList list = (ArrayList) $1;
4365 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
4367 | BYREF variable_reference
4369 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
4373 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
4375 | ADDRESSOF expression
4377 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
4382 : expression {/* note ("section 5.4"); */ $$ = $1; }
4387 : conditional_xor_expression { $$ = $1; }
4388 /*| assignment_expression*/
4399 $$ = new This (current_block, lexer.Location);
4403 // FIXME: This is actually somewhat different from Me
4404 // because it is for accessing static (classifier) methods/properties/fields
4405 $$ = new This (current_block, lexer.Location);
4410 : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
4414 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
4416 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
4418 | cast_operator OPEN_PARENS expression CLOSE_PARENS
4420 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
4425 : CBOOL { $$ = TypeManager.system_boolean_expr; }
4426 | CBYTE { $$ = TypeManager.system_byte_expr; }
4427 | CCHAR { $$ = TypeManager.system_char_expr; }
4428 // | CDATE { $$ = TypeManager.system_date_expr; }
4429 | CDBL { $$ = TypeManager.system_double_expr; }
4430 | CDEC { $$ = TypeManager.system_decimal_expr; }
4431 | CINT { $$ = TypeManager.system_int32_expr; }
4432 | CLNG { $$ = TypeManager.system_int64_expr; }
4433 | COBJ { $$ = TypeManager.system_object_expr; }
4434 | CSHORT { $$ = TypeManager.system_int16_expr; }
4435 | CSNG { $$ = TypeManager.system_single_expr; }
4436 | CSTR { $$ = TypeManager.system_string_expr; }
4440 : GETTYPE OPEN_PARENS type CLOSE_PARENS
4442 $$ = new TypeOf ((Expression) $3, lexer.Location);
4446 exponentiation_expression
4447 : primary_expression
4448 | exponentiation_expression OP_EXP primary_expression
4454 prefixed_unary_expression
4455 : exponentiation_expression
4456 | PLUS prefixed_unary_expression
4458 //FIXME: Is this rule correctly defined ?
4459 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
4461 | MINUS prefixed_unary_expression
4463 //FIXME: Is this rule correctly defined ?
4464 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
4468 multiplicative_expression
4469 : prefixed_unary_expression
4470 | multiplicative_expression STAR prefixed_unary_expression
4472 $$ = new Binary (Binary.Operator.Multiply,
4473 (Expression) $1, (Expression) $3, lexer.Location);
4475 | multiplicative_expression DIV prefixed_unary_expression
4477 $$ = new Binary (Binary.Operator.Division,
4478 (Expression) $1, (Expression) $3, lexer.Location);
4482 integer_division_expression
4483 : multiplicative_expression
4484 | integer_division_expression OP_IDIV multiplicative_expression
4486 //FIXME: Is this right ?
4487 $$ = new Binary (Binary.Operator.Division,
4488 (Expression) $1, (Expression) $3, lexer.Location);
4493 : integer_division_expression
4494 | mod_expression MOD integer_division_expression
4496 $$ = new Binary (Binary.Operator.Modulus,
4497 (Expression) $1, (Expression) $3, lexer.Location);
4503 | additive_expression PLUS mod_expression
4505 $$ = new Binary (Binary.Operator.Addition,
4506 (Expression) $1, (Expression) $3, lexer.Location);
4508 | additive_expression MINUS mod_expression
4510 $$ = new Binary (Binary.Operator.Subtraction,
4511 (Expression) $1, (Expression) $3, lexer.Location);
4516 : additive_expression
4517 | concat_expression OP_CONCAT additive_expression
4519 // FIXME: This should only work for String expressions
4520 // We probably need to use something from the runtime
4521 $$ = new Binary (Binary.Operator.Addition,
4522 (Expression) $1, (Expression) $3, lexer.Location);
4528 | shift_expression OP_SHIFT_LEFT concat_expression
4532 | shift_expression OP_SHIFT_RIGHT concat_expression
4538 relational_expression
4540 | relational_expression ASSIGN shift_expression
4542 $$ = new Binary (Binary.Operator.Equality,
4543 (Expression) $1, (Expression) $3, lexer.Location);
4545 | relational_expression OP_NE shift_expression
4547 $$ = new Binary (Binary.Operator.Inequality,
4548 (Expression) $1, (Expression) $3, lexer.Location);
4550 | relational_expression OP_LT shift_expression
4552 $$ = new Binary (Binary.Operator.LessThan,
4553 (Expression) $1, (Expression) $3, lexer.Location);
4555 | relational_expression OP_GT shift_expression
4557 $$ = new Binary (Binary.Operator.GreaterThan,
4558 (Expression) $1, (Expression) $3, lexer.Location);
4560 | relational_expression OP_LE shift_expression
4562 $$ = new Binary (Binary.Operator.LessThanOrEqual,
4563 (Expression) $1, (Expression) $3, lexer.Location);
4565 | relational_expression OP_GE shift_expression
4567 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
4568 (Expression) $1, (Expression) $3, lexer.Location);
4570 | relational_expression IS shift_expression
4572 //FIXME: Should be a different op for reference equality but allows tests to use Is
4573 $$ = new Binary (Binary.Operator.Equality,
4574 (Expression) $1, (Expression) $3, lexer.Location);
4576 | TYPEOF shift_expression IS type
4578 //FIXME: Is this rule correctly defined ?
4579 $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
4584 : relational_expression
4585 | NOT negation_expression
4587 //FIXME: Is this rule correctly defined ?
4588 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
4592 conditional_and_expression
4593 : negation_expression
4594 | conditional_and_expression AND negation_expression
4596 $$ = new Binary (Binary.Operator.LogicalAnd,
4597 (Expression) $1, (Expression) $3, lexer.Location);
4599 | conditional_and_expression ANDALSO negation_expression
4600 { // FIXME: this is likely to be broken
4601 $$ = new Binary (Binary.Operator.LogicalAnd,
4602 (Expression) $1, (Expression) $3, lexer.Location);
4606 conditional_or_expression
4607 : conditional_and_expression
4608 | conditional_or_expression OR conditional_and_expression
4610 $$ = new Binary (Binary.Operator.LogicalOr,
4611 (Expression) $1, (Expression) $3, lexer.Location);
4613 | conditional_or_expression ORELSE conditional_and_expression
4614 { // FIXME: this is likely to be broken
4615 $$ = new Binary (Binary.Operator.LogicalOr,
4616 (Expression) $1, (Expression) $3, lexer.Location);
4620 conditional_xor_expression
4621 : conditional_or_expression
4622 | conditional_xor_expression XOR conditional_or_expression
4624 $$ = new Binary (Binary.Operator.ExclusiveOr,
4625 (Expression) $1, (Expression) $3, lexer.Location);
4629 assignment_expression
4630 : prefixed_unary_expression ASSIGN expression
4632 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
4634 | prefixed_unary_expression STAR ASSIGN expression
4636 Location l = lexer.Location;
4638 $$ = new CompoundAssign (
4639 Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
4641 | prefixed_unary_expression DIV ASSIGN expression
4643 Location l = lexer.Location;
4645 $$ = new CompoundAssign (
4646 Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
4648 | prefixed_unary_expression PLUS ASSIGN expression
4650 Location l = lexer.Location;
4652 $$ = new CompoundAssign (
4653 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4655 | prefixed_unary_expression MINUS ASSIGN expression
4657 Location l = lexer.Location;
4659 $$ = new CompoundAssign (
4660 Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
4662 | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
4664 Location l = lexer.Location;
4666 $$ = new CompoundAssign (
4667 Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
4669 | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
4671 Location l = lexer.Location;
4673 $$ = new CompoundAssign (
4674 Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
4676 | prefixed_unary_expression OP_CONCAT ASSIGN expression
4678 Location l = lexer.Location;
4680 // FIXME should be strings only
4681 $$ = new CompoundAssign (
4682 Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
4684 | prefixed_unary_expression OP_EXP ASSIGN expression
4686 Location l = lexer.Location;
4688 /* TODO: $$ = new CompoundAssign (
4689 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
4691 | prefixed_unary_expression ASSIGN ADDRESSOF expression
4693 // ArrayList args = new ArrayList();
4694 // Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
4697 // New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
4698 // n.isDelegate = true;
4699 $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
4712 : namespace_or_type_name
4714 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
4723 ArrayList types = new ArrayList ();
4728 | type_list COMMA type
4730 ArrayList types = (ArrayList) $1;
4737 namespace_or_type_name
4738 : qualified_identifier
4742 : OBJECT { $$ = TypeManager.system_object_expr; }
4748 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
4749 // | DATE { $$ = TypeManager.system_date_expr; }
4750 | CHAR { $$ = TypeManager.system_char_expr; }
4751 | STRING { $$ = TypeManager.system_string_expr; }
4757 | floating_point_type
4758 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
4763 | BYTE { $$ = TypeManager.system_byte_expr; }
4764 | SHORT { $$ = TypeManager.system_int16_expr; }
4765 | INTEGER { $$ = TypeManager.system_int32_expr; }
4766 | LONG { $$ = TypeManager.system_int64_expr; }
4770 : SINGLE { $$ = TypeManager.system_single_expr; }
4771 | DOUBLE { $$ = TypeManager.system_double_expr; }
4775 : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
4777 // if(tokenizerController.IsAcceptingTokens)
4779 // if(in_external_source)
4780 // Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
4782 // in_external_source = true;
4784 // lexer.EffectiveSource = (string) $4;
4785 // lexer.EffectiveLine = (int) $6;
4789 | HASH IDENTIFIER LITERAL_STRING EOL
4791 if(tokenizerController.IsAcceptingTokens)
4793 string id = ($2 as string);
4795 if(!($2 as string).ToLower().Equals("region"))
4796 Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
4803 | HASH END IDENTIFIER EOL
4805 if(tokenizerController.IsAcceptingTokens)
4807 // if( ($3 as string).ToLower().Equals("externalsource")) {
4808 // if(!in_external_source)
4809 // Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
4811 // in_external_source = false;
4812 // lexer.EffectiveSource = lexer.Source;
4813 // lexer.EffectiveLine = lexer.Line;
4816 /* else */if(($3 as string).ToLower().Equals("region")) {
4817 if(in_marked_region > 0)
4820 Report.Error (30205, lexer.Location, "'#End Region' must be preceded by a matching '#Region'");
4823 Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
4827 | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
4829 if(tokenizerController.IsAcceptingTokens)
4836 IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
4839 ifElseStateMachine.HandleToken(tok);
4841 catch(ApplicationException) {
4842 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4845 boolean_literal opt_then EOL
4847 HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
4851 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
4853 ifElseStateMachine.HandleToken(tok);
4855 catch(ApplicationException) {
4856 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4859 boolean_literal opt_then EOL
4861 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
4865 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
4867 ifElseStateMachine.HandleToken(tok);
4869 catch(ApplicationException) {
4870 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4875 HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
4879 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
4881 ifElseStateMachine.HandleToken(tok);
4883 catch(ApplicationException) {
4884 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
4889 HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
4893 if(tokenizerController.IsAcceptingTokens)
4894 Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
4896 Report.Warning (9999, lexer.Location, "Unrecognized Pre-Processor statement");
4906 public Tokenizer Lexer {
4912 public static Expression DecomposeQI (string name, Location loc)
4916 if (name.IndexOf ('.') == -1){
4917 return new SimpleName (name, loc);
4919 int pos = name.LastIndexOf (".");
4920 string left = name.Substring (0, pos);
4921 string right = name.Substring (pos + 1);
4923 o = DecomposeQI (left, loc);
4925 return new MemberAccess (o, right, loc);
4929 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
4931 Block implicit_block;
4932 ArrayList inits = null;
4935 // We use the `Used' property to check whether statements
4936 // have been added to the current block. If so, we need
4937 // to create another block to contain the new declaration
4938 // otherwise, as an optimization, we use the same block to
4939 // add the declaration.
4941 // FIXME: A further optimization is to check if the statements
4942 // that were added were added as part of the initialization
4943 // below. In which case, no other statements have been executed
4944 // and we might be able to reduce the number of blocks for
4945 // situations like this:
4947 // int j = 1; int k = j + 1;
4950 VariableDeclaration.FixupTypes (variable_declarators);
4951 // FIXME: Should VariableDeclaration.FixupArrayTypes be called here
4953 if (current_block.Used)
4954 implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
4956 implicit_block = current_block;
4959 foreach (VariableDeclaration decl in variable_declarators){
4960 Expression type = decl.type;
4961 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4962 if (decl.expression_or_array_initializer != null){
4964 inits = new ArrayList ();
4971 return implicit_block;
4973 foreach (VariableDeclaration decl in inits){
4976 Expression type = decl.type;
4978 if ((decl.expression_or_array_initializer is Expression) ||
4979 (decl.expression_or_array_initializer is New)) {
4980 expr = (Expression) decl.expression_or_array_initializer;
4982 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4984 expr = new ArrayCreation (type, "", init, decl.Location);
4987 LocalVariableReference var;
4988 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4990 assign = new Assign (var, expr, decl.Location);
4992 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4995 return implicit_block;
4998 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
5000 Block implicit_block;
5001 VariableDeclaration.FixupTypes (variable_declarators);
5003 if (current_block.Used)
5004 implicit_block = new Block (current_block, Block.Flags.Implicit);
5006 implicit_block = current_block;
5008 foreach (VariableDeclaration decl in variable_declarators){
5009 Expression type = decl.type;
5010 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
5011 current_local_parameters, decl.Location);
5014 return implicit_block;
5024 public VarName (object n, object t, object r)
5034 // A class used to pass around variable declarations and constants
5036 public class VariableDeclaration {
5037 public string identifier;
5038 public object expression_or_array_initializer;
5039 public Location Location;
5040 public Attributes OptAttributes;
5041 public string DocComment;
5042 public Expression type;
5043 public ArrayList dims;
5045 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
5047 this.identifier = id;
5048 this.expression_or_array_initializer = eoai;
5050 this.OptAttributes = opt_attrs;
5055 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
5059 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
5063 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
5064 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
5068 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
5070 // FIXME : This is broken: only the first rank is parsed
5071 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
5074 public static void FixupTypes (ArrayList vars)
5076 int varcount = vars.Count;
5077 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
5079 if (last_var.type == null)
5080 last_var.type = TypeManager.system_object_expr;
5082 Expression cur_type = last_var.type;
5083 int n = varcount - 1;
5086 VariableDeclaration var = (VariableDeclaration) vars[n--];
5087 if (var.type == null)
5088 var.type = cur_type;
5090 cur_type = var.type;
5094 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
5098 if (IndexList != null) {
5099 foreach (Expression e in IndexList)
5100 if (!(e is EmptyExpression)) {
5109 public static bool IndexesSpecified (ArrayList ranks)
5113 if (ranks != null) {
5114 foreach (ArrayList IndexList in ranks) {
5115 if (IndexesSpecifiedInRank (IndexList)) {
5124 public static string StripDims (string varname, ref string d)
5126 string res = varname;
5129 if (varname.IndexOf("[") >= 0) {
5130 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
5131 res = varname.Substring(0, varname.IndexOf("["));
5137 public static string StripDims (string varname)
5141 return (StripDims(varname, ref dres));
5144 public static string StripIndexesFromDims (string dims)
5146 StringBuilder sb = new StringBuilder();
5148 foreach (char c in dims)
5149 if (c == ',' || c == ']' || c == '[')
5152 return sb.ToString();
5155 public static string BuildRank (ArrayList rank)
5158 return BuildRank(rank, out allEmpty);
5161 public static string BuildRank (ArrayList rank, out bool allEmpty)
5168 foreach (object e in rank) {
5169 if (!(e is EmptyExpression))
5180 public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
5184 bool allEmpty = true;
5185 foreach (ArrayList rank in rank_specifiers) {
5187 res = BuildRank (rank, out tmp) + res;
5191 if (!allEmpty && mustBeEmpty)
5192 Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");
5197 public static void VBFixIndexList (ref ArrayList IndexList)
5199 if (IndexList != null) {
5200 for (int x = 0; x < IndexList.Count; x++) {
5201 Expression e = (Expression) IndexList[x];
5202 if (!(e is EmptyExpression)) {
5203 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
5209 // public static bool IsArrayDecl (Parser t)
5211 // // return (varname.IndexOf("[") >= 0);
5212 // return (t.current_rank_specifiers != null);
5215 public static void VBFixIndexLists (ref ArrayList ranks)
5217 if (ranks != null) {
5218 for (int x = 0; x < ranks.Count; x++) {
5219 ArrayList IndexList = (ArrayList) ranks[x];
5220 VBFixIndexList (ref IndexList);
5225 public static void FixupArrayTypes (ArrayList vars)
5227 int varcount = vars.Count;
5230 foreach (VariableDeclaration var in vars) {
5231 if (var.identifier.EndsWith(",")) {
5232 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
5233 var.identifier.LastIndexOf(",")) + "]";
5234 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
5235 var.type = new ComposedCast (var.type, (string) dims, var.Location);
5242 // public Property BuildSimpleProperty (Expression p_type, string name,
5243 // Field p_fld, int mod_flags,
5244 // Attributes attrs, Location loc)
5247 // Block get_block, set_block;
5248 // Accessor acc_set, acc_get;
5249 // StatementExpression a_set;
5251 // Parameter [] args;
5253 // // Build SET Block
5254 // Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
5255 // args = new Parameter [1];
5256 // args [0] = implicit_value_parameter;
5258 // Parameters set_params = new Parameters (args, null, loc);
5259 // a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
5260 // (Expression) new SimpleName("value", loc), loc), loc);
5262 // set_block = new Block (current_block, set_params, loc, Location.Null);
5263 // set_block.AddStatement ((Statement) a_set);
5264 // acc_set = new Accessor (set_block, attrs);
5266 // // Build GET Block
5267 // a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
5268 // get_block = new Block (current_block, null, loc, Location.Null);
5269 // get_block.AddStatement ((Statement) a_get);
5270 // acc_get = new Accessor (get_block, attrs);
5272 // p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
5279 if (current_block == null){
5280 current_block = new ToplevelBlock ((ToplevelBlock) top_current_block,
5281 current_local_parameters, lexer.Location);
5282 top_current_block = current_block;
5284 current_block = new Block (current_block, current_local_parameters,
5285 lexer.Location, Location.Null);
5294 while (current_block.Implicit)
5295 current_block = current_block.Parent;
5296 res = current_block;
5297 current_block.SetEndLocation (lexer.Location);
5298 current_block = current_block.Parent;
5299 if (current_block == null)
5300 top_current_block = null;
5305 // private void AddHandler (Expression evt_definition, Expression handler_exp)
5307 // AddHandler (current_block, evt_definition, handler_exp);
5310 void CheckAttributeTarget (string a)
5314 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
5318 Location l = lexer.Location;
5319 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
5324 // private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
5326 // Expression evt_target;
5327 // Location loc = lexer.Location;
5329 // Statement addhnd = (Statement) new AddHandler (evt_id,
5333 // b.AddStatement (addhnd);
5336 // private void RaiseEvent (string evt_name, ArrayList args)
5338 // Location loc = lexer.Location;
5340 // Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
5341 // Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
5342 // current_block.AddStatement (s);
5345 // private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
5347 // Expression evt_target;
5348 // Location loc = lexer.Location;
5350 // Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
5353 // b.AddStatement (rmhnd);
5357 // This method is used to get at the complete string representation of
5358 // a fully-qualified type name, hiding inside a MemberAccess ;-)
5359 // This is necessary because local_variable_type admits primary_expression
5360 // as the type of the variable. So we do some extra checking
5362 string GetQualifiedIdentifier (Expression expr)
5364 if (expr is SimpleName)
5365 return ((SimpleName)expr).Name;
5366 else if (expr is MemberAccess)
5367 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
5369 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
5373 // private void RemoveHandler (Expression evt_definition, Expression handler_exp)
5375 // RemoveHandler (current_block, evt_definition, handler_exp);
5378 // FIXME: This needs to be fixed for This and Base access because the way the name of the
5379 // mbas' constructor is changed from "New" to current_container.Basename
5381 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
5383 ConstructorInitializer ci = null;
5386 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
5387 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
5389 if (i.expr is BaseAccess) {
5390 BaseAccess ba = (BaseAccess) i.expr;
5391 if (ba.member == "New" || ba.member == ".ctor") {
5392 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
5396 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
5397 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
5405 void Error_ExpectingTypeName (Location l, Expression expr)
5407 if (expr is Invocation){
5408 Report.Error (1002, l, "; expected");
5410 Report.Error (-1, l, "Invalid Type definition");
5414 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
5418 private void ReportError9998()
5420 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
5423 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
5425 current_namespace = new NamespaceEntry (null, file, null, Location.Null);
5426 this.name = file.Name;
5428 current_container = RootContext.Tree.Types;
5429 current_container.NamespaceEntry = current_namespace;
5430 oob_stack = new Stack ();
5431 switch_stack = new Stack ();
5433 lexer = new Tokenizer (reader, file, defines);
5435 ifElseStateMachine = new IfElseStateMachine();
5436 tokenizerController = new TokenizerController(lexer);
5439 public void parse ()
5442 if (yacc_verbose_flag > 1)
5443 yyparse (lexer, new yydebug.yyDebugSimple ());
5446 Tokenizer tokenizer = lexer as Tokenizer;
5447 tokenizer.cleanup ();
5448 } catch (Exception e){
5450 // Removed for production use, use parser verbose to get the output.
5452 // Console.WriteLine (e);
5453 Report.Error (-25, lexer.Location, "Parsing error");
5454 if (yacc_verbose_flag > 0)
5455 Console.WriteLine (e);
5460 // protected override int parse ()
5462 // RootContext.InitializeImports(ImportsList);
5463 // current_namespace = new Namespace (null, RootContext.RootNamespace);
5464 // current_container = RootContext.Tree.Types;
5465 // current_container.Namespace = current_namespace;
5466 // oob_stack = new Stack ();
5467 // switch_stack = new Stack ();
5468 // expr_stack = new Stack ();
5469 // tmp_blocks = new Stack();
5470 // with_stack = new Stack();
5471 // statement_stack = new Stack();
5473 // allow_global_attribs = true;
5474 // expecting_global_attribs = false;
5475 // expecting_local_attribs = false;
5476 // local_attrib_section_added = false;
5478 // UseExtendedSyntax = name.EndsWith(".mbs");
5479 // OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
5480 // OptionStrict = InitialOptionStrict || UseExtendedSyntax;
5481 // OptionCompareBinary = InitialOptionCompareBinary;
5483 // lexer = new Tokenizer (input, name, defines);
5485 // ifElseStateMachine = new IfElseStateMachine();
5486 // tokenizerController = new TokenizerController(lexer);
5488 // StringBuilder value = new StringBuilder ();
5490 // if (yacc_verbose_flag > 0)
5491 // yyparse (lexer, new yydebug.yyDebugSimple ());
5497 // catch(MBASException e) {
5498 // Report.Error(e.code, e.loc, e.Message);
5500 // catch (Exception e) {
5501 // if (Report.Stacktrace)
5502 // Console.WriteLine(e);
5503 // Report.Error (29999, lexer.Location, "Parsing error");
5506 // RootContext.VerifyImports();
5508 // return Report.Errors;
5514 // ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
5516 // catch(ApplicationException) {
5517 // throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5520 // if(in_external_source)
5521 // Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
5523 // if(in_marked_region > 0)
5524 // Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
5527 void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
5530 tokenizerController.PositionTokenizerCursor(tok, expr);
5532 catch(ApplicationException) {
5533 tok = IfElseStateMachine.Token.EOF;
5535 ifElseStateMachine.HandleToken(tok);
5537 catch(ApplicationException) {
5538 throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
5545 // Given the @class_name name, it creates a fully qualified name
5546 // based on the containing declaration space
5549 MakeName (MemberName class_name)
5551 string ns = current_namespace.FullName;
5553 if (current_container.Name == ""){
5555 return new MemberName (new MemberName (ns), class_name);
5559 return new MemberName (current_container.MemberName, class_name);