//
// 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
//
//
{
+
/// <summary>
/// Current block is used to add statements as we find
/// them.
}
}
}
+
+ bool allow_global_attribs = true;
+
+ bool expecting_global_attribs = false;
+ bool expecting_local_attribs = false;
+
+ bool local_attrib_section_added = false;
%}
%token EOF
: 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
opt_declarations
: /* empty */
| declarations
- ;
+ ;
declarations
: declaration
;
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
break;
- if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+ if ((mod_flags & (Modifiers.PRIVATE)) != 0){
Report.Error (
- 1527, lexer.Location,
+ 31089, lexer.Location,
"Namespace elements cannot be explicitly " +
- "declared private or protected in '" + name + "'");
+ "declared private in '" + name + "'");
+ }
+ else if ((mod_flags & (Modifiers.PROTECTED)) != 0){
+ Report.Error (
+ 31047, lexer.Location,
+ "Namespace elements cannot be explicitly " +
+ "declared protected in '" + name + "'");
}
}
;
| 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; }
}
;
-type_declaration
+declaration_qualifiers
: opt_attributes
opt_modifiers
{
current_attributes = (Attributes) $1;
current_modifiers = (int) $2;
}
- type_spec_declaration
;
type_spec_declaration
;
class_declaration
- : CLASS identifier logical_end_of_line opt_inherits opt_implements
+ : CLASS identifier end_of_stmt opt_inherits opt_implements
{
// Module members are static by default, but Class *can't* be declared static
// so we must fix it, if mbas was the one actually responsible for this
opt_inherits
: /* empty */ { $$ = null; }
- | INHERITS type_list logical_end_of_line { $$ = $2; }
+ | INHERITS type_list end_of_stmt { $$ = $2; }
;
opt_implements
: /* empty */ { $$ = null; }
- | IMPLEMENTS type_list logical_end_of_line { $$ = $2; }
+ | IMPLEMENTS type_list end_of_stmt { $$ = $2; }
;
opt_modifiers
;
constant_declaration
- : CONST constant_declarators logical_end_of_line
+ : CONST constant_declarators end_of_stmt
{
// Module members are static by default, but constants *can't* be declared static
// so we must fix it, if mbas was the one actually responsible for this
evt_target + " is not declared with WithEvents");
}
} else if (handles_exp is BaseAccess) {
- string evt_id = ((BaseAccess) $4).member;
Statement addhnd = (Statement) new AddHandler ((Expression) $4,
DecomposeQI((string) $2, loc),
loc);
;
struct_declaration
- : STRUCTURE identifier logical_end_of_line
+ : STRUCTURE identifier end_of_stmt
opt_implement_clause
{
Struct new_struct;
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);
Event e = new Event (DecomposeQI (delName, lexer.Location),
(string) $2,
- null, current_modifiers, null, null,
+ null, current_modifiers,
current_attributes, (ArrayList) $4,
lexer.Location);
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);
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);
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
+ && current_container.DefaultPropName != (string) $2)
+ 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;
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
field_declaration
: opt_dim_stmt
- variable_declarators logical_end_of_line
+ variable_declarators end_of_stmt
{
int mod = (int) current_modifiers;
}
| embedded_statement
{
- Statement s = (Statement) $1;
-
current_block.AddStatement ((Statement) $1);
}
| labeled_statement
/* | empty_statement */
| with_statement
{
- Statement s = (Statement) $1;
-
current_block.AddStatement ((Statement) $1);
}
;
;
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
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;
}
;
| 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;
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;
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; }
}
;
-
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
$$ = 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);
+ }
;
pre_embedded_statement
: embedded_statement
{
- Statement s = (Statement) $1;
-
current_block.AddStatement ((Statement) $1);
}
;
opt_else_pre_embedded_statement
- : /* empty */
+ : /* 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);
}
;
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.)
string varname = (string) vname.Name;
current_rank_specifiers = (ArrayList) vname.Rank;
object varinit = $3;
- ArrayList a_dims = null;
if (varinit == null)
Report.Error (
}
| prefixed_unary_expression OP_EXP ASSIGN expression
{
- Location l = lexer.Location;
+ /*Location l = lexer.Location;
- /* TODO: $$ = new CompoundAssign (
+ TODO: $$ = new CompoundAssign (
Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
}
| prefixed_unary_expression ASSIGN ADDRESSOF expression
{
if(tokenizerController.IsAcceptingTokens)
{
- string id = ($2 as string);
-
if(!($2 as string).ToLower().Equals("region"))
Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
else
public static void FixupArrayTypes (ArrayList vars)
{
- int varcount = vars.Count;
string dims;
foreach (VariableDeclaration var in vars) {
private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
{
- Expression evt_target;
Location loc = lexer.Location;
Statement addhnd = (Statement) new AddHandler (evt_id,
handles_exp,
loc);
-
b.AddStatement (addhnd);
}
private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
{
- Expression evt_target;
Location loc = lexer.Location;
Statement rmhnd = (Statement) new RemoveHandler (evt_definition,
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;
ifElseStateMachine = new IfElseStateMachine();
tokenizerController = new TokenizerController(lexer);
- StringBuilder value = new StringBuilder ();
try {
- if (yacc_verbose_flag)
+ if (yacc_verbose_flag > 0)
yyparse (lexer, new yydebug.yyDebugSimple ());
else {
yyparse (lexer);