X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmbas%2Fmb-parser.jay;h=2d7d5fd0c715bddc8e27a1dc59a3f68706cf575d;hb=98b7597517475eb0b3096b6ac5f6f36fe5ee6e94;hp=8112d01f337586012631c65fdc14be614bddd7f7;hpb=c7cd6bad2d8045fac2204cd66d913ba0c5ff4a05;p=mono.git diff --git a/mcs/mbas/mb-parser.jay b/mcs/mbas/mb-parser.jay index 8112d01f337..2d7d5fd0c71 100644 --- a/mcs/mbas/mb-parser.jay +++ b/mcs/mbas/mb-parser.jay @@ -2,12 +2,14 @@ // // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler // -// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) -// Anirban Bhattacharjee (banirban@novell.com) +// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com) +// Anirban Bhattacharjee (banirban@novell.com) +// Jambunathan K (kjambunathan@novell.com) // // Licensed under the terms of the GNU GPL // -// Copyright (C) 2001 A Rafael D Teixeira +// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira +// Copyright (C) 2003, 2004 Novell // // @@ -40,6 +42,7 @@ namespace Mono.MonoBASIC { + /// /// Current block is used to add statements as we find /// them. @@ -364,6 +367,13 @@ namespace Mono.MonoBASIC } } } + + bool allow_global_attribs = true; + + bool expecting_global_attribs = false; + bool expecting_local_attribs = false; + + bool local_attrib_section_added = false; %} %token EOF @@ -618,13 +628,19 @@ compilation_unit : logical_end_of_line opt_option_directives opt_imports_directives - opt_global_attributes - opt_declarations + declarations EOF { - $$=$5; + $$=$4; + } + |logical_end_of_line + opt_option_directives + opt_imports_directives + opt_attributes + EOF + { + /* ????? */ ; } - ; opt_option_directives @@ -704,7 +720,7 @@ option_compare_directive opt_declarations : /* empty */ | declarations - ; + ; declarations : declaration @@ -712,14 +728,25 @@ declarations ; declaration - : namespace_declaration - | type_declaration + : declaration_qualifiers + { + // FIXME: Need to check declaration qualifiers for multi-file compilation + // FIXME: Qualifiers cannot be applied to namespaces + allow_global_attribs = false; + } + namespace_declaration + |declaration_qualifiers + { + // FIXME: Need to check declaration qualifiers for multi-file compilation + allow_global_attribs = false; + } + type_spec_declaration { string name = ""; int mod_flags; - if ($1 is Class || $1 is Struct || $1 is Module ){ - TypeContainer c = (TypeContainer) $1; + if ($3 is Class || $3 is Struct || $3 is Module ){ + TypeContainer c = (TypeContainer) $3; mod_flags = c.ModFlags; name = c.Name; } else @@ -802,93 +829,183 @@ opt_params | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; } ; -attribute_modifier - : ASSEMBLY - | MODULE - | identifier - { - Report.Error (658, lexer.Location, "`" + (string)$1 + "' is an invalid attribute target"); - } - ; +opt_attributes + : /* empty */ + | attribute_sections + { + $$ = $1; + local_attrib_section_added = false; + } + ; -global_attribute_list - : global_attribute - | global_attribute_list COMMA global_attribute - ; +attribute_sections + : attribute_section + { + $$ = $1; + if ($1 == null) { + expecting_local_attribs = false; + expecting_global_attribs = false; + break; + } + + if (expecting_local_attribs) { + local_attrib_section_added = true; + allow_global_attribs = false; -global_attribute - : attribute_modifier COLON attribute - ; + $$ = new Attributes ((ArrayList) $1); + } -global_attributes_definition - : attr_begin global_attribute_list attr_end - ; + if (expecting_global_attribs) { + $$ = null; + CodeGen.AddGlobalAttributes ((ArrayList) $1); + } -global_attributes - : global_attributes_definition - | global_attributes global_attributes_definition - | global_attributes end_of_stmt global_attributes_definition - ; + expecting_local_attribs = false; + expecting_global_attribs = false; + } + | attribute_sections + { + $$ = lexer.Location; + } + attribute_section + { + $$ = $1; + if ($3 != null) { + ArrayList attrs = (ArrayList) $3; + + if (expecting_local_attribs) { + if (local_attrib_section_added) { + expecting_local_attribs = false; + expecting_global_attribs = false; + Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section"); + break; + } -opt_global_attributes - : /* empty */ - | global_attributes end_of_stmt - ; + if ($1 == null) + $$ = new Attributes (attrs); + else + ((Attributes) $1).Add (attrs); -opt_attributes - : /* empty */ - | attributes { $$ = $1; } - ; + local_attrib_section_added = true; + allow_global_attribs = false; + } -attr_begin - : OP_LT - ; + if (expecting_global_attribs) { + $$ = null; + CodeGen.AddGlobalAttributes ((ArrayList) $3); + } + } -attr_end - : OP_GT + expecting_local_attribs = false; + expecting_global_attribs = false; + } ; -attributes - : attr_begin attribute_list attr_end +attribute_section + : OP_LT attribute_list OP_GT opt_end_of_stmt { - AttributeSection sect = new AttributeSection (null, (ArrayList) $2); - $$ = new Attributes (sect, lexer.Location); + $$ = null; + if ($2 != null) { + if (expecting_global_attribs && !(bool) $4) { + Report.Error (30205, lexer.Location, "End of statement expected"); + break; + } + + if (expecting_local_attribs) { + if ((bool) $4) { + Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement."); + break; + } + } + + $$ = $2; + } } - | attr_begin global_attribute_list attr_end logical_end_of_line ; +opt_end_of_stmt + : /* empty */ { $$ = false; } + | end_of_stmt { $$ = true; } + ; + attribute_list : attribute { - ArrayList attrs = new ArrayList (); - attrs.Add ($1); - + ArrayList attrs = null; + if ($1 != null) { + attrs = new ArrayList (); + attrs.Add ($1); + } $$ = attrs; - } | attribute_list COMMA attribute { - ArrayList attrs = (ArrayList) $1; - attrs.Add ($3); + ArrayList attrs = null; + + if ($3 != null) { + attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1; + attrs.Add ($3); + } $$ = attrs; } ; attribute - : attribute_name - { + : namespace_or_type_name + { $$ = lexer.Location; - } - opt_attribute_arguments - { - $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2); - } + } + opt_attribute_arguments + { + $$ = null; + + if (expecting_global_attribs) + Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers"); + else { + expecting_local_attribs = true; + $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2); + } + } + | attribute_target_specifier + { + $$ = lexer.Location; + } + COLON + namespace_or_type_name + { + $$ = lexer.Location; + } + opt_attribute_arguments + { + $$ = null; + + string attribute_target = (string) $1; + if (attribute_target != "assembly" && attribute_target != "module") { + Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier"); + break; + } + if (!allow_global_attribs) { + Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file"); + break; + } + + if (expecting_local_attribs) { + Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes"); + break; + } + + expecting_global_attribs = true; + $$ = new Attribute (attribute_target, (string) $4, (ArrayList) $6, (Location) $5); + } ; -attribute_name - : namespace_or_type_name +attribute_target_specifier + : ASSEMBLY { $$ = "assembly"; } + | MODULE { $$ = "module"; } + | namespace_or_type_name ; + opt_attribute_arguments : /* empty */ { $$ = null; } @@ -984,14 +1101,13 @@ namespace_declaration } ; -type_declaration +declaration_qualifiers : opt_attributes opt_modifiers { current_attributes = (Attributes) $1; current_modifiers = (int) $2; } - type_spec_declaration ; type_spec_declaration @@ -1335,7 +1451,7 @@ sub_declaration Statement addhnd = (Statement) new AddHandler ((Expression) $4, DecomposeQI((string) $2, loc), - DecomposeQI(evt_target, loc), loc); + loc); current_container.AddEventHandler (addhnd); found = true; @@ -1352,7 +1468,7 @@ sub_declaration string evt_id = ((BaseAccess) $4).member; Statement addhnd = (Statement) new AddHandler ((Expression) $4, DecomposeQI((string) $2, loc), - (Expression) $4, loc); + loc); current_container.AddEventHandler (addhnd); } @@ -1468,7 +1584,7 @@ event_declaration VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location); Event e = new Event ((Expression) $4, var.identifier, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, (ArrayList) $5, lexer.Location); @@ -1505,7 +1621,7 @@ event_declaration Event e = new Event (DecomposeQI (delName, lexer.Location), (string) $2, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, (ArrayList) $4, lexer.Location); @@ -1751,7 +1867,7 @@ interface_event_declaration VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location); Event e = new Event ((Expression) $4, var.identifier, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, lexer.Location); CheckDef (current_interface.AddEvent (e), e.Name, e.Location); @@ -1772,7 +1888,7 @@ interface_event_declaration Event e = new Event (DecomposeQI (delName, lexer.Location), (string) $2, - null, current_modifiers, null, null, + null, current_modifiers, current_attributes, lexer.Location); CheckDef (current_interface.AddEvent (e), e.Name, e.Location); @@ -1844,6 +1960,16 @@ abstract_propery_declaration non_abstract_propery_declaration : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line { + if ((current_modifiers & Modifiers.DEFAULT) > 0) { + if (current_container.DefaultPropName != null) + Report.Error (30359, + lexer.Location, + "Type '" + current_container.Name + + "' cannot have more than one 'Default Property' "); + + current_container.DefaultPropName = (string) $2; + } + get_implicit_value_parameter_type = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5; @@ -2034,11 +2160,11 @@ opt_set_parameter set_implicit_value_parameter_type = (Expression) $4; - if (set_implicit_value_parameter_type != get_implicit_value_parameter_type) + if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ()) Report.Error (31064, lexer.Location, "Set value parameter type can not be different from property type"); - + if ($2 != null) set_implicit_value_parameter_name = (string) $3; else @@ -2589,28 +2715,58 @@ iteration_statement ; foreach_statement - : FOR EACH identifier IN + : FOR EACH identifier opt_type_spec IN { oob_stack.Push (lexer.Location); } expression end_of_stmt { - - start_block(); - Block foreach_block = current_block; Location l = lexer.Location; LocalVariableReference v = null; VariableInfo vi; - vi = foreach_block.GetVariableInfo ((string) $3); - if (vi != null) { - // Get a reference to this variable. - v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false); + if ($4 != null) + { + start_block(); + VariableDeclaration decl = new VariableDeclaration ((string) $3, + (Expression) $4, null, lexer.Location, null); + + vi = current_block.AddVariable ( + (Expression) $4, decl.identifier, current_local_parameters, decl.Location); + + Expression expr; + if (decl.expression_or_array_initializer is Expression) + expr = (Expression) decl.expression_or_array_initializer; + else if (decl.expression_or_array_initializer == null) + expr = null; + else + { + ArrayList init = (ArrayList) decl.expression_or_array_initializer; + expr = new ArrayCreation ((Expression) $4, "", init, decl.Location); + } + + v = new LocalVariableReference (current_block, decl.identifier, l); + + if (expr != null) + { + Assign a = new Assign (v, expr, decl.Location); + current_block.AddStatement (new StatementExpression (a, lexer.Location)); + } } else - Report.Error (451, "Name '" + (string) $3 + "' is not declared."); - + { + vi = current_block.GetVariableInfo ((string) $3); + + if (vi != null) { + // Get a reference to this variable. + v = new LocalVariableReference (current_block, (string) $3, l, vi, false); + } + else + Report.Error (451, "Name '" + (string) $3 + "' is not declared."); + } + oob_stack.Push (v); + start_block(); } opt_statement_list NEXT opt_identifier @@ -2620,11 +2776,16 @@ foreach_statement Location l = (Location) oob_stack.Pop (); Foreach f = null; - if (v != null) { - f = new Foreach (null, v, (Expression) $6, foreach_block, l); - } + if (v != null) + f = new Foreach (null, v, (Expression) $7, foreach_block, l); - $$ = f; + if ($4 != null) + { + current_block.AddStatement (f); + $$ = end_block (); + } + else + $$ = f; } ; @@ -2771,8 +2932,13 @@ opt_identifier | identifier ; +opt_when + : /* empty */ { $$ = null; } + | WHEN boolean_expression { $$ = $2; } + ; + catch_clause - : CATCH opt_catch_args end_of_stmt + : CATCH opt_catch_args opt_when end_of_stmt { Expression type = null; string id = null; @@ -2788,14 +2954,12 @@ catch_clause one.Add (new VariableDeclaration (id, type, loc)); - $1 = current_block; current_block = new Block (current_block); Block b = declare_local_variables (type, one, loc); current_block = b; } } - } opt_statement_list { Expression type = null; @@ -2815,10 +2979,9 @@ catch_clause current_block = current_block.Parent; } } - - $$ = new Catch (type, id , (Block)b_catch, lexer.Location); + $$ = new Catch (type, id , (Block) b_catch, (Expression) $3, lexer.Location); } - ; + ; opt_catch_args : /* empty */ { $$ = null; } @@ -2895,29 +3058,48 @@ while_statement } ; - for_statement - : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt + : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt { - start_block(); + if ($3 != null) + { + start_block(); + ArrayList VarDeclaration = new ArrayList (); + VarDeclaration.Add (new VariableDeclaration ((string) $2, + (Expression) $3, null, lexer.Location, null)); + + DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration); + Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location); + current_block = b; + } + oob_stack.Push (lexer.Location); + start_block(); } opt_statement_list NEXT opt_identifier { - Block statement = end_block(); - Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);; - - Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location); - Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual, - for_var, (Expression) $6, lexer.Location); - Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition, - for_var, (Expression) $7, lexer.Location), lexer.Location); - - Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location); - Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location); - - $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location); - } + Block inner_statement = end_block(); + Location l = (Location) oob_stack.Pop (); + Expression for_var = (Expression) DecomposeQI ((string)$2, l); + + Expression assign_expr = new Assign (for_var, (Expression) $5, l); + Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual, + for_var, (Expression) $7, l); + Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition, + for_var, (Expression) $8, l), l); + + Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l); + Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l); + + For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l); + if ($3 != null) + { + current_block.AddStatement (f); + $$ = end_block(); + } + else + $$ = f; + } ; opt_step @@ -2935,11 +3117,28 @@ if_statement { $$ = $3; } - | if_statement_open THEN pre_embedded_statement + | if_statement_open THEN pre_embedded_statement opt_else_pre_embedded_statement { - Location l = (Location) oob_stack.Pop (); - tmp_expr = (Expression)expr_stack.Pop(); - $$ = new If ((Expression) tmp_expr, end_block(), l); + if ($4 == null) + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + $$ = new If ((Expression) tmp_expr, end_block(), l); + } + else + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + tmp_block = (Block) tmp_blocks.Pop (); + $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l); + } + } + | if_statement_open THEN else_pre_embedded_statement + { + Location l = (Location) oob_stack.Pop (); + tmp_expr = (Expression)expr_stack.Pop(); + tmp_block = (Block) tmp_blocks.Pop (); + $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, end_block(), l); } ; @@ -2951,6 +3150,30 @@ pre_embedded_statement current_block.AddStatement ((Statement) $1); } ; + +opt_else_pre_embedded_statement + : /* empty */ + | else_pre_embedded_statement + ; + +else_pre_embedded_statement + : ELSE + { + Block bl = end_block(); + tmp_blocks.Push(bl); + + start_block(); + } + | ELSE embedded_statement + { + Block bl = end_block(); + tmp_blocks.Push(bl); + + start_block(); + Statement s = (Statement) $2; + current_block.AddStatement ((Statement) $2); + } + ; if_statement_open : IF boolean_expression @@ -2973,7 +3196,7 @@ if_statement_rest END IF { Location l = (Location) oob_stack.Pop (); - Expression expr = (Expression)expr_stack.Pop(); + Expression expr = (Expression)expr_stack.Pop(); $$ = new If ((Expression) expr, (Statement) end_block(), l); } | end_of_stmt @@ -2981,7 +3204,7 @@ if_statement_rest ELSE end_of_stmt { Block bl = end_block(); - tmp_blocks.Push(bl); + tmp_blocks.Push(bl); start_block(); } opt_statement_list @@ -3122,7 +3345,7 @@ case_section topmost.statements.Add (new Break (lexer.Location)); $$ = new SwitchSection ((ArrayList) $2, topmost); } - | CASE ELSE ends + | CASE ELSE ends /* FIXME: we should somehow flag an error (BC30321 'Case' cannot follow a 'Case Else' in the same 'Select' statement.) @@ -3762,7 +3985,16 @@ invocation_expression } $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location); // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0); - } + } + | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS + { + if ($2 == null) { + Location l = lexer.Location; + Report.Error (1, l, "THIS IS CRAZY"); + } + $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location); +// Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0); + } ; base_access @@ -4770,15 +5002,10 @@ private void AddHandler (Block b, Expression evt_id, Expression handles_exp) Expression evt_target; Location loc = lexer.Location; - if (evt_id is MemberAccess) - evt_target = ((MemberAccess)evt_id).Expr; - else - evt_target = (new This (current_block, lexer.Location)); - Statement addhnd = (Statement) new AddHandler (evt_id, handles_exp, - evt_target, - loc); + loc); + b.AddStatement (addhnd); } @@ -4793,41 +5020,13 @@ private void RaiseEvent (string evt_name, ArrayList args) private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp) { - Location loc = lexer.Location; - if (handler_exp is MemberAccess) { - string evt_def = ((MemberAccess)handler_exp).ToString(); - string evt_target = evt_definition.ToString(); - evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.')); - - Statement s = (Statement) new RemoveHandler ( - evt_definition, - DecomposeQI(evt_def, loc), - DecomposeQI(evt_target, loc), loc); - - b.AddStatement (s); - - } else if (handler_exp is SimpleName) { - string evt_def = ((SimpleName)handler_exp).ToString(); - string evt_target = evt_definition.ToString(); - evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.')); - - Statement s = (Statement) new RemoveHandler ( - evt_definition, - DecomposeQI(evt_def, loc), - DecomposeQI(evt_target, loc), loc); - - b.AddStatement (s); - - } else if (handler_exp is BaseAccess) { - string evt_def = ((BaseAccess) handler_exp).member; - - Statement s = (Statement) new RemoveHandler ( - evt_definition, - DecomposeQI(evt_def, loc), - handler_exp , loc); - - b.AddStatement (s); - } + Expression evt_target; + Location loc = lexer.Location; + + Statement rmhnd = (Statement) new RemoveHandler (evt_definition, + handler_exp, + loc); + b.AddStatement (rmhnd); } // @@ -4907,6 +5106,11 @@ protected override int parse () with_stack = new Stack(); statement_stack = new Stack(); + allow_global_attribs = true; + expecting_global_attribs = false; + expecting_local_attribs = false; + local_attrib_section_added = false; + UseExtendedSyntax = name.EndsWith(".mbs"); OptionExplicit = InitialOptionExplicit || UseExtendedSyntax; OptionStrict = InitialOptionStrict || UseExtendedSyntax; @@ -4919,7 +5123,7 @@ protected override int parse () StringBuilder value = new StringBuilder (); try { - if (yacc_verbose_flag) + if (yacc_verbose_flag > 0) yyparse (lexer, new yydebug.yyDebugSimple ()); else { yyparse (lexer);