3 // cs-parser.jay: The Parser for the C# compiler
\r
5 // Author: Miguel de Icaza (miguel@gnu.org)
\r
7 // Licensed under the terms of the GNU GPL
\r
9 // (C) 2001 Ximian, Inc (http://www.ximian.com)
\r
12 // (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
\r
13 // And come to think of it, it is not that great, it duplicates a lot of code
\r
14 // for something which is not really needed. We still have piles of typecasts
\r
15 // anwyays (due to the nature of the stack being a collection of Objects).
\r
17 // (2) Figure out why error productions dont work. `type-declaration' is a
\r
18 // great spot to put an `error' because you can reproduce it with this input:
\r
21 // (3) Move Modifier checking from each object into the parser itself, that will
\r
22 // get rid of the global "error" symbol that we use now to report errors.
\r
23 // We still need to pass a pointer to the tree.ErrorHandler, but that is a
\r
32 using System.Collections;
\r
33 using Mono.Languages;
\r
38 public class CSharpParser : GenericParser {
\r
39 Namespace current_namespace;
\r
40 TypeContainer current_container;
\r
43 // Current block is used to add statements as we find
\r
47 Block current_block;
\r
50 // Current interface is used by the various declaration
\r
51 // productions in the interface declaration to "add"
\r
52 // the interfaces as we find them.
\r
54 Interface current_interface;
\r
57 // This is used by the unary_expression code to resolve
\r
58 // a name against a parameter.
\r
60 Parameters current_local_parameters;
\r
63 // Using during property parsing to describe the implicit
\r
64 // value parameter that is passed to the "set" accesor
\r
67 Parameter [] implicit_value_parameters;
\r
70 // Used to determine if we are parsing the get/set pair
\r
71 // of an indexer or a property
\r
73 bool parsing_indexer;
\r
76 // Used to record all types defined
\r
84 %token NONE /* This token is never returned by our lexer */
\r
85 %token ERROR // This is used not by the parser, but by the tokenizer.
\r
89 *These are the C# keywords
\r
169 /* C# keywords which are not really keywords */
\r
173 /* C# single character operators/punctuation. */
\r
174 %token OPEN_BRACE "{"
\r
175 %token CLOSE_BRACE "}"
\r
176 %token OPEN_BRACKET "["
\r
177 %token CLOSE_BRACKET "]"
\r
178 %token OPEN_PARENS "("
\r
179 %token CLOSE_PARENS ")"
\r
183 %token SEMICOLON ";"
\r
192 %token BITWISE_AND "&"
\r
193 %token BITWISE_OR "|"
\r
200 /* C# multi-character operators. */
\r
203 %token OP_SHIFT_LEFT "<<"
\r
204 %token OP_SHIFT_RIGHT ">>"
\r
211 %token OP_MULT_ASSIGN "*="
\r
212 %token OP_DIV_ASSIGN "/="
\r
213 %token OP_MOD_ASSIGN "%="
\r
214 %token OP_ADD_ASSIGN "+="
\r
215 %token OP_SUB_ASSIGN "-="
\r
216 %token OP_SHIFT_LEFT_ASSIGN "<<="
\r
217 %token OP_SHIFT_RIGHT_ASSIGN ">>="
\r
218 %token OP_AND_ASSIGN "&="
\r
219 %token OP_XOR_ASSIGN "^="
\r
220 %token OP_OR_ASSIGN "|="
\r
224 %token LITERAL_INTEGER "int literal"
\r
225 %token LITERAL_FLOAT "float literal"
\r
226 %token LITERAL_DOUBLE "double literal"
\r
227 %token LITERAL_DECIMAL "decimal literal"
\r
228 %token LITERAL_CHARACTER "character literal"
\r
229 %token LITERAL_STRING "string literal"
\r
233 /* Add precedence rules to solve dangling else s/r conflict */
\r
242 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
\r
244 %left STAR DIV PERCENT
\r
245 %right BANG CARRET UMINUS
\r
246 %nonassoc OP_INC OP_DEC
\r
248 %left OPEN_BRACKET OPEN_BRACE
\r
252 %start compilation_unit
\r
253 /*%start namespace_declaration */
\r
257 : opt_using_directives opt_attributes opt_namespace_member_declarations EOF
\r
259 // Check that using comes only before namespace elements
\r
265 | using_directives using_directive
\r
269 : using_alias_directive
\r
270 | using_namespace_directive
\r
273 using_alias_directive
\r
274 : USING IDENTIFIER ASSIGN
\r
275 namespace_or_type_name SEMICOLON
\r
277 // FIXME : Need to implement actual action.
\r
281 using_namespace_directive
\r
282 : USING namespace_name SEMICOLON
\r
284 current_namespace.Using ((string) $2);
\r
288 // namespace_declarations
\r
289 // : namespace_declaration
\r
290 // | namespace_declarations namespace_declaration
\r
292 namespace_declaration
\r
293 : NAMESPACE qualified_identifier
\r
295 current_namespace = new Namespace (current_namespace, (string) $2);
\r
296 tree.RecordNamespace ((string) $2, current_namespace);
\r
298 namespace_body opt_semicolon
\r
300 current_namespace = current_namespace.Parent;
\r
314 qualified_identifier
\r
316 | qualified_identifier DOT IDENTIFIER {
\r
317 $$ = (($1).ToString ()) + "." + ($3.ToString ()); }
\r
322 : namespace_or_type_name
\r
327 opt_using_directives
\r
328 opt_namespace_member_declarations
\r
334 opt_using_directives
\r
339 opt_namespace_member_declarations
\r
341 | namespace_member_declarations
\r
344 namespace_member_declarations
\r
345 : namespace_member_declaration
\r
346 | namespace_member_declarations namespace_member_declaration
\r
349 namespace_member_declaration
\r
356 Class c = (Class) $1;
\r
357 mod_flags = c.ModFlags;
\r
359 } else if ($1 is Struct){
\r
360 Struct s = (Struct) $1;
\r
361 mod_flags = s.ModFlags;
\r
367 // We remove this error until we can
\r
368 //if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
\r
369 // error (1527, "Namespace elements cant be explicitly " +
\r
370 // "declared private or protected in `" + name + "'");
\r
373 | namespace_declaration
\r
377 : class_declaration
\r
378 | struct_declaration
\r
379 | interface_declaration
\r
380 | enum_declaration
\r
381 | delegate_declaration
\r
388 : /* empty */ { $$ = null; }
\r
389 | attribute_section opt_attributes
\r
394 attrs = (Attributes) $2;
\r
395 attrs.AddAttribute ((Attribute) $1);
\r
397 attrs = new Attributes ((Attribute) $1);
\r
404 : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET
\r
406 string target = null;
\r
409 target = (string) $2;
\r
411 $$ = new Attribute (target, (ArrayList) $3);
\r
413 | OPEN_BRACKET attribute_list CLOSE_BRACKET
\r
415 $$ = new Attribute (null, (ArrayList) $2);
\r
419 attribute_target_specifier
\r
420 : attribute_target COLON
\r
429 CheckAttributeTarget ((string) $1);
\r
432 | EVENT { $$ = "event"; }
\r
433 | RETURN { $$ = "return"; }
\r
439 ArrayList attrs = new ArrayList ();
\r
445 | attribute_list COMMA attribute
\r
447 ArrayList attrs = (ArrayList) $1;
\r
455 : attribute_name opt_attribute_arguments
\r
457 $$ = new DictionaryEntry ($1, $2);
\r
462 : type_name { /* reserved attribute name or identifier: 17.4 */ }
\r
465 opt_attribute_arguments
\r
466 : /* empty */ { $$ = null; }
\r
467 | OPEN_PARENS attribute_arguments CLOSE_PARENS
\r
473 attribute_arguments
\r
476 ArrayList args = new ArrayList ();
\r
481 | attribute_arguments COMMA expression
\r
483 ArrayList args = (ArrayList) $1;
\r
492 : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
\r
495 opt_class_member_declarations
\r
497 | class_member_declarations
\r
500 class_member_declarations
\r
501 : class_member_declaration
\r
502 | class_member_declarations
\r
503 class_member_declaration
\r
506 class_member_declaration
\r
507 : constant_declaration // done
\r
508 | field_declaration // done
\r
509 | method_declaration // done
\r
510 | property_declaration // done
\r
511 | event_declaration // done
\r
512 | indexer_declaration // done
\r
513 | operator_declaration // done
\r
514 | constructor_declaration // done
\r
515 | destructor_declaration // done
\r
525 string full_struct_name = MakeName ((string) $4);
\r
527 new_struct = new Struct (rc, current_container, full_struct_name, (int) $2, (Attributes) $1);
\r
528 current_container = new_struct;
\r
529 current_container.Namespace = current_namespace;
\r
530 tree.RecordStruct (full_struct_name, new_struct);
\r
532 opt_struct_interfaces
\r
536 Struct new_struct = (Struct) current_container;
\r
538 current_container = current_container.Parent;
\r
539 CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
\r
544 opt_struct_interfaces
\r
546 | struct_interfaces
\r
551 | struct_interfaces struct_interface
\r
559 : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
\r
562 opt_struct_member_declarations
\r
564 | struct_member_declarations
\r
567 struct_member_declarations
\r
568 : struct_member_declaration
\r
569 | struct_member_declarations struct_member_declaration
\r
572 struct_member_declaration
\r
573 : constant_declaration
\r
574 | field_declaration
\r
575 | method_declaration
\r
576 | property_declaration
\r
577 | event_declaration
\r
578 | indexer_declaration
\r
579 | operator_declaration
\r
580 | constructor_declaration
\r
584 constant_declaration
\r
589 constant_declarators
\r
592 foreach (DictionaryEntry constant in (ArrayList) $5){
\r
593 Constant c = new Constant (
\r
594 (string) $4, (string) constant.Key,
\r
595 (Expression) constant.Value, (int) $2, (Attributes) $1);
\r
597 CheckDef (current_container.AddConstant (c), c.Name);
\r
602 constant_declarators
\r
603 : constant_declarator
\r
605 ArrayList constants = new ArrayList ();
\r
606 constants.Add ($1);
\r
609 | constant_declarators COMMA constant_declarator
\r
611 ArrayList constants = (ArrayList) $1;
\r
613 constants.Add ($3);
\r
617 constant_declarator
\r
618 : IDENTIFIER ASSIGN constant_expression
\r
620 $$ = new DictionaryEntry ($1, $3);
\r
628 variable_declarators
\r
631 string type = (string) $3;
\r
632 int mod = (int) $2;
\r
634 foreach (VariableDeclaration var in (ArrayList) $4){
\r
635 Field field = new Field (type, mod, var.identifier,
\r
636 var.expression_or_array_initializer, (Attributes) $1);
\r
638 CheckDef (current_container.AddField (field), field.Name);
\r
644 variable_declarators
\r
645 : variable_declarator
\r
647 ArrayList decl = new ArrayList ();
\r
651 | variable_declarators COMMA variable_declarator
\r
653 ArrayList decls = (ArrayList) $1;
\r
659 variable_declarator
\r
660 : IDENTIFIER ASSIGN variable_initializer
\r
662 $$ = new VariableDeclaration ((string) $1, $3);
\r
666 $$ = new VariableDeclaration ((string) $1, null);
\r
670 variable_initializer
\r
675 | array_initializer
\r
685 Method method = (Method) $1;
\r
687 method.Block = (Block) $2;
\r
688 CheckDef (current_container.AddMethod (method), method.Name);
\r
690 current_local_parameters = null;
\r
699 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
\r
701 Method method = new Method ((string) $3, (int) $2, (string) $4, (Parameters) $6, (Attributes) $1);
\r
703 current_local_parameters = (Parameters) $6;
\r
711 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
\r
713 Method method = new Method ("System.Void", (int) $2, (string) $4, (Parameters) $6, (Attributes) $1);
\r
715 current_local_parameters = (Parameters) $6;
\r
722 | SEMICOLON { $$ = null; }
\r
725 opt_formal_parameter_list
\r
726 : /* empty */ { $$ = new Parameters (null, null); }
\r
727 | formal_parameter_list
\r
730 formal_parameter_list
\r
731 : fixed_parameters
\r
733 ArrayList pars_list = (ArrayList) $1;
\r
735 Parameter [] pars = new Parameter [pars_list.Count];
\r
736 pars_list.CopyTo (pars);
\r
738 $$ = new Parameters (pars, null);
\r
740 | fixed_parameters COMMA parameter_array
\r
742 ArrayList pars_list = (ArrayList) $1;
\r
744 Parameter [] pars = new Parameter [pars_list.Count];
\r
745 pars_list.CopyTo (pars);
\r
747 $$ = new Parameters (pars, (Parameter) $3);
\r
751 $$ = new Parameters (null, (Parameter) $1);
\r
758 ArrayList pars = new ArrayList ();
\r
763 | fixed_parameters COMMA fixed_parameter
\r
765 ArrayList pars = (ArrayList) $1;
\r
774 opt_parameter_modifier
\r
778 $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
\r
782 opt_parameter_modifier
\r
783 : /* empty */ { $$ = Parameter.Modifier.NONE; }
\r
784 | parameter_modifier
\r
788 : REF { $$ = Parameter.Modifier.REF; }
\r
789 | OUT { $$ = Parameter.Modifier.OUT; }
\r
793 : opt_attributes PARAMS type IDENTIFIER
\r
795 $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
\r
796 note ("type must be a single-dimension array type");
\r
801 : IDENTIFIER { $$ = $1.ToString (); }
\r
802 | interface_type DOT IDENTIFIER { $$ = $1.ToString () + "." + $3.ToString (); }
\r
805 property_declaration
\r
811 Parameter implicit_value_parameter;
\r
812 implicit_value_parameter = new Parameter ((string) $3, "value", Parameter.Modifier.NONE, null);
\r
814 lexer.properties = true;
\r
816 implicit_value_parameters = new Parameter [1];
\r
817 implicit_value_parameters [0] = implicit_value_parameter;
\r
819 accessor_declarations
\r
821 lexer.properties = false;
\r
826 DictionaryEntry pair = (DictionaryEntry) $7;
\r
827 Block get_block = null;
\r
828 Block set_block = null;
\r
830 if (pair.Key != null)
\r
831 get_block = (Block) pair.Key;
\r
832 if (pair.Value != null)
\r
833 set_block = (Block) pair.Value;
\r
835 prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block, (Attributes) $1);
\r
837 CheckDef (current_container.AddProperty (prop), prop.Name);
\r
838 implicit_value_parameters = null;
\r
842 accessor_declarations
\r
843 : get_accessor_declaration opt_set_accessor_declaration
\r
845 $$ = new DictionaryEntry ($1, $2);
\r
847 | set_accessor_declaration opt_get_accessor_declaration
\r
849 $$ = new DictionaryEntry ($2, $1);
\r
853 opt_get_accessor_declaration
\r
854 : /* empty */ { $$ = null; }
\r
855 | get_accessor_declaration
\r
858 opt_set_accessor_declaration
\r
859 : /* empty */ { $$ = null; }
\r
860 | set_accessor_declaration
\r
863 get_accessor_declaration
\r
864 : opt_attributes GET
\r
866 // If this is not the case, then current_local_parameters has already
\r
867 // been set in indexer_declaration
\r
868 if (parsing_indexer == false)
\r
869 current_local_parameters = new Parameters (implicit_value_parameters, null);
\r
876 current_local_parameters = null;
\r
880 set_accessor_declaration
\r
881 : opt_attributes SET
\r
883 if (parsing_indexer == false)
\r
884 current_local_parameters = new Parameters (implicit_value_parameters, null);
\r
889 current_local_parameters = null;
\r
895 | SEMICOLON { $$ = new Block (null); }
\r
898 interface_declaration
\r
901 INTERFACE IDENTIFIER
\r
903 Interface new_interface;
\r
904 string full_interface_name = MakeName ((string) $4);
\r
906 new_interface = new Interface (current_container, full_interface_name, (int) $2, (Attributes) $1);
\r
907 if (current_interface != null) {
\r
908 Location l = lexer.Location;
\r
909 rc.Report.Error (-2, l, "Internal compiler error: interface inside interface");
\r
911 current_interface = new_interface;
\r
912 tree.RecordInterface (full_interface_name, new_interface);
\r
917 Interface new_interface = (Interface) current_interface;
\r
920 new_interface.Bases = (ArrayList) $6;
\r
922 current_interface = null;
\r
923 CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
\r
928 : /* empty */ { $$ = null; }
\r
933 : COLON interface_type_list { $$ = $2; }
\r
936 interface_type_list
\r
939 ArrayList interfaces = new ArrayList ();
\r
941 interfaces.Add ($1);
\r
944 | interface_type_list COMMA interface_type
\r
946 ArrayList interfaces = (ArrayList) $1;
\r
947 interfaces.Add ($3);
\r
954 opt_interface_member_declarations
\r
958 opt_interface_member_declarations
\r
960 | interface_member_declarations
\r
963 interface_member_declarations
\r
964 : interface_member_declaration
\r
965 | interface_member_declarations interface_member_declaration
\r
968 interface_member_declaration
\r
969 : interface_method_declaration
\r
971 InterfaceMethod m = (InterfaceMethod) $1;
\r
973 CheckDef (current_interface.AddMethod (m), m.Name);
\r
975 | interface_property_declaration
\r
977 InterfaceProperty p = (InterfaceProperty) $1;
\r
979 CheckDef (current_interface.AddProperty (p), p.Name);
\r
981 | interface_event_declaration
\r
983 InterfaceEvent e = (InterfaceEvent) $1;
\r
985 CheckDef (current_interface.AddEvent (e), e.Name);
\r
987 | interface_indexer_declaration
\r
989 InterfaceIndexer i = (InterfaceIndexer) $1;
\r
991 CheckDef (current_interface.AddIndexer (i), "indexer");
\r
996 : /* empty */ { $$ = false; }
\r
997 | NEW { $$ = true; }
\r
1000 interface_method_declaration
\r
1001 : opt_attributes opt_new type IDENTIFIER
\r
1002 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
\r
1005 $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
\r
1007 | opt_attributes opt_new VOID IDENTIFIER
\r
1008 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
\r
1011 $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
\r
1015 interface_property_declaration
\r
1020 { lexer.properties = true; }
\r
1021 interface_accesors
\r
1022 { lexer.properties = false; }
\r
1025 int gs = (int) $7;
\r
1027 $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2,
\r
1028 (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1);
\r
1032 interface_accesors
\r
1033 : opt_attributes GET SEMICOLON { $$ = 1; }
\r
1034 | opt_attributes SET SEMICOLON { $$ = 2; }
\r
1035 | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON
\r
1037 | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
\r
1041 interface_event_declaration
\r
1042 : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
\r
1044 $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2, (Attributes) $1);
\r
1048 interface_indexer_declaration
\r
1049 : opt_attributes opt_new type THIS
\r
1050 OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
\r
1052 { lexer.properties = true; }
\r
1053 interface_accesors
\r
1054 { lexer.properties = false; }
\r
1057 int a_flags = (int) $10;
\r
1059 bool do_get = (a_flags & 1) == 1;
\r
1060 bool do_set = (a_flags & 2) == 2;
\r
1062 $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set, (bool) $2, (Attributes) $1);
\r
1066 operator_declaration
\r
1067 : opt_attributes opt_modifiers operator_declarator block
\r
1069 OperatorDeclaration decl = (OperatorDeclaration) $3;
\r
1071 Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name,
\r
1072 decl.arg2type, decl.arg2name, (Block) $4, (Attributes) $1);
\r
1074 // Note again, checking is done in semantic analysis
\r
1075 current_container.AddOperator (op);
\r
1079 operator_declarator
\r
1080 : type OPERATOR overloadable_operator
\r
1081 OPEN_PARENS type IDENTIFIER CLOSE_PARENS
\r
1083 CheckUnaryOperator ((Operator.OpType) $3);
\r
1085 $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6, null, null);
\r
1087 | type OPERATOR overloadable_operator
\r
1089 type IDENTIFIER COMMA
\r
1093 CheckBinaryOperator ((Operator.OpType) $3);
\r
1095 $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
\r
1096 (string) $8, (string) $9);
\r
1098 | conversion_operator_declarator
\r
1101 overloadable_operator
\r
1102 // Unary operators:
\r
1103 : BANG { $$ = Operator.OpType.Negate; }
\r
1104 | TILDE { $$ = Operator.OpType.BitComplement; }
\r
1105 | OP_INC { $$ = Operator.OpType.Increment; }
\r
1106 | OP_DEC { $$ = Operator.OpType.Decrement; }
\r
1107 | TRUE { $$ = Operator.OpType.True; }
\r
1108 | FALSE { $$ = Operator.OpType.False; }
\r
1109 // Unary and binary:
\r
1110 | PLUS { $$ = Operator.OpType.Addition; }
\r
1111 | MINUS { $$ = Operator.OpType.Subtraction; }
\r
1113 | STAR { $$ = Operator.OpType.Multiply; }
\r
1114 | DIV { $$ = Operator.OpType.Division; }
\r
1115 | PERCENT { $$ = Operator.OpType.Modulus; }
\r
1116 | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
\r
1117 | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
\r
1118 | CARRET { $$ = Operator.OpType.ExclusiveOr; }
\r
1119 | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
\r
1120 | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
\r
1121 | OP_EQ { $$ = Operator.OpType.Equality; }
\r
1122 | OP_NE { $$ = Operator.OpType.Inequality; }
\r
1123 | OP_GT { $$ = Operator.OpType.GreaterThan; }
\r
1124 | OP_LT { $$ = Operator.OpType.LessThan; }
\r
1125 | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
\r
1126 | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
\r
1129 conversion_operator_declarator
\r
1130 : IMPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
\r
1132 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
\r
1135 | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
\r
1137 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
\r
1142 constructor_declaration
\r
1145 constructor_declarator
\r
1148 Constructor c = (Constructor) $3;
\r
1149 c.Block = (Block) $4;
\r
1150 c.ModFlags = (int) $2;
\r
1152 if ((c.ModFlags & Modifiers.STATIC) != 0){
\r
1153 if ((c.ModFlags & Modifiers.Accessibility) != 0) {
\r
1154 Location l = lexer.Location;
\r
1155 rc.Report.Error (515, l, "Access modifiers are not allowed on static constructors");
\r
1158 if (c.Initializer != null){
\r
1159 Location l = lexer.Location;
\r
1160 rc.Report.Error (514, l, "Static constructors can not have an explicit this or base constructor invocations");
\r
1163 if (!c.Parameters.Empty){
\r
1164 Location l = lexer.Location;
\r
1165 rc.Report.Error (103, l, "Static constructors should not have parameters");
\r
1168 if (c.Initializer == null)
\r
1169 c.Initializer = new ConstructorBaseInitializer (null, lexer.Location);
\r
1172 CheckDef (current_container.AddConstructor (c), c.Name);
\r
1174 current_local_parameters = null;
\r
1178 constructor_declarator
\r
1180 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
\r
1181 opt_constructor_initializer
\r
1183 $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5);
\r
1185 current_local_parameters = (Parameters) $3;
\r
1189 opt_constructor_initializer
\r
1190 : /* empty */ { $$ = null; }
\r
1191 | constructor_initializer
\r
1194 constructor_initializer
\r
1195 : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
\r
1197 $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
\r
1199 | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
\r
1201 $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
\r
1205 destructor_declaration
\r
1206 : opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
\r
1208 Method d = new Method ("System.Void", 0, "Finalize", new Parameters (null, null), (Attributes) $1);
\r
1210 d.Block = (Block) $6;
\r
1211 CheckDef (current_container.AddMethod (d), d.Name);
\r
1218 EVENT type variable_declarators SEMICOLON
\r
1220 foreach (VariableDeclaration var in (ArrayList) $5) {
\r
1222 // FIXME : Is this right ?
\r
1223 Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
\r
1224 (int) $2, null, null, (Attributes) $1);
\r
1226 CheckDef (current_container.AddEvent (e), e.Name);
\r
1232 EVENT type member_name
\r
1233 OPEN_BRACE event_accessor_declarations CLOSE_BRACE
\r
1235 DictionaryEntry pair = (DictionaryEntry) $7;
\r
1236 Block add_block = null;
\r
1237 Block rem_block = null;
\r
1239 if (pair.Key != null)
\r
1240 add_block = (Block) pair.Key;
\r
1241 if (pair.Value != null)
\r
1242 rem_block = (Block) pair.Value;
\r
1244 Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block, (Attributes) $1);
\r
1246 CheckDef (current_container.AddEvent (e), e.Name);
\r
1250 event_accessor_declarations
\r
1251 : add_accessor_declaration remove_accessor_declaration
\r
1253 $$ = new DictionaryEntry ($1, $2);
\r
1255 | remove_accessor_declaration add_accessor_declaration
\r
1257 $$ = new DictionaryEntry ($2, $1);
\r
1261 add_accessor_declaration
\r
1262 : opt_attributes ADD block
\r
1268 remove_accessor_declaration
\r
1269 : opt_attributes REMOVE block
\r
1275 indexer_declaration
\r
1276 : opt_attributes opt_modifiers indexer_declarator
\r
1279 IndexerDeclaration decl = (IndexerDeclaration) $3;
\r
1281 lexer.properties = true;
\r
1282 parsing_indexer = true;
\r
1284 current_local_parameters = decl.param_list;
\r
1286 accessor_declarations
\r
1288 lexer.properties = false;
\r
1289 parsing_indexer = false;
\r
1293 // The signature is computed from the signature of the indexer. Look
\r
1294 // at section 3.6 on the spec
\r
1297 IndexerDeclaration decl = (IndexerDeclaration) $3;
\r
1298 DictionaryEntry pair = (DictionaryEntry) $6;
\r
1299 Block get_block = null;
\r
1300 Block set_block = null;
\r
1302 if (pair.Key != null)
\r
1303 get_block = (Block) pair.Key;
\r
1304 if (pair.Value != null)
\r
1305 set_block = (Block) pair.Value;
\r
1307 indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
\r
1308 get_block, set_block, (Attributes) $1);
\r
1310 // Note that there is no equivalent of CheckDef for this case
\r
1311 // We shall handle this in semantic analysis
\r
1313 current_container.AddIndexer (indexer);
\r
1315 current_local_parameters = null;
\r
1319 indexer_declarator
\r
1320 : type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
\r
1322 $$ = new IndexerDeclaration ((string) $1, null, (Parameters) $4);
\r
1324 | type interface_type DOT THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
\r
1326 $$ = new IndexerDeclaration ((string) $1, (string) $2, (Parameters) $6);
\r
1338 string name = (string) $4;
\r
1339 Enum e = new Enum ((string) $5, (int) $2, name, (Attributes) $1);
\r
1341 foreach (VariableDeclaration ev in (ArrayList) $6){
\r
1342 CheckDef (e.AddEnumMember (ev.identifier,
\r
1343 (Expression) ev.expression_or_array_initializer),
\r
1347 CheckDef (current_container.AddEnum (e), name);
\r
1352 : /* empty */ { $$ = "System.Int32"; }
\r
1353 | COLON integral_type { $$ = $2; }
\r
1357 : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
\r
1363 opt_enum_member_declarations
\r
1364 : /* empty */ { $$ = new ArrayList (); }
\r
1365 | enum_member_declarations opt_comma { $$ = $1; }
\r
1368 enum_member_declarations
\r
1369 : enum_member_declaration
\r
1371 ArrayList l = new ArrayList ();
\r
1376 | enum_member_declarations COMMA enum_member_declaration
\r
1378 ArrayList l = (ArrayList) $1;
\r
1386 enum_member_declaration
\r
1387 : opt_attributes IDENTIFIER
\r
1389 $$ = new VariableDeclaration ((string) $2, null);
\r
1391 | opt_attributes IDENTIFIER ASSIGN expression
\r
1393 $$ = new VariableDeclaration ((string) $2, $4);
\r
1397 delegate_declaration
\r
1401 IDENTIFIER OPEN_PARENS
\r
1402 formal_parameter_list
\r
1406 Delegate del = new Delegate ((string) $4, (int) $2, (string) $5, (Parameters) $7, (Attributes) $1);
\r
1408 CheckDef (current_container.AddDelegate (del), del.Name);
\r
1413 IDENTIFIER OPEN_PARENS
\r
1414 formal_parameter_list
\r
1418 Delegate del = new Delegate (null, (int) $2, (string) $5, (Parameters) $7, (Attributes) $1);
\r
1420 CheckDef (current_container.AddDelegate (del), del.Name);
\r
1425 : namespace_or_type_name
\r
1428 namespace_or_type_name
\r
1429 : qualified_identifier
\r
1433 * Before you think of adding a return_type, notice that we have been
\r
1434 * using two rules in the places where it matters (one rule using type
\r
1435 * and another identical one that uses VOID as the return type). This
\r
1436 * gets rid of a shift/reduce couple
\r
1439 : type_name { /* class_type */
\r
1441 This does interfaces, delegates, struct_types, class_types,
\r
1442 parent classes, and more! 4.2
\r
1453 ArrayList types = new ArrayList ();
\r
1458 | type_list COMMA type
\r
1460 ArrayList types = (ArrayList) $1;
\r
1468 * replaces all the productions for isolating the various
\r
1469 * simple types, but we need this to reuse it easily in local_variable_type
\r
1472 : OBJECT { $$ = "System.Object"; }
\r
1473 | STRING { $$ = "System.String"; }
\r
1474 | BOOL { $$ = "System.Boolean"; }
\r
1475 | DECIMAL { $$ = "System.Decimal"; }
\r
1476 | FLOAT { $$ = "System.Single"; }
\r
1477 | DOUBLE { $$ = "System.Double"; }
\r
1482 : SBYTE { $$ = "System.SByte"; }
\r
1483 | BYTE { $$ = "System.Byte"; }
\r
1484 | SHORT { $$ = "System.Int16"; }
\r
1485 | USHORT { $$ = "System.UInt16"; }
\r
1486 | INT { $$ = "System.Int32"; }
\r
1487 | UINT { $$ = "System.UInt32"; }
\r
1488 | LONG { $$ = "System.Int64"; }
\r
1489 | ULONG { $$ = "System.UInt64"; }
\r
1490 | CHAR { $$ = "System.Char"; }
\r
1498 : type rank_specifiers
\r
1500 $$ = (string) $1 + (string) $2;
\r
1505 // Expressions, section 7.5
\r
1507 primary_expression
\r
1510 // 7.5.1: Literals
\r
1513 | qualified_identifier
\r
1515 string name = (string) $1;
\r
1518 $$ = QualifiedIdentifier (name, lexer.Location);
\r
1520 | parenthesized_expression
\r
1522 | invocation_expression
\r
1526 | post_increment_expression
\r
1527 | post_decrement_expression
\r
1529 | typeof_expression
\r
1530 | sizeof_expression
\r
1531 | checked_expression
\r
1532 | unchecked_expression
\r
1539 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
\r
1540 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
\r
1541 | NULL { $$ = new NullLiteral (); }
\r
1545 : LITERAL_FLOAT { $$ = new FloatLiteral ((float) lexer.Value); }
\r
1546 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
\r
1547 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
\r
1551 : LITERAL_INTEGER { $$ = new IntLiteral ((Int32) lexer.Value); }
\r
1555 : TRUE { $$ = new BoolLiteral (true); }
\r
1556 | FALSE { $$ = new BoolLiteral (false); }
\r
1559 parenthesized_expression
\r
1560 : OPEN_PARENS expression CLOSE_PARENS
\r
1565 : primary_expression DOT IDENTIFIER
\r
1567 $$ = new MemberAccess ((Expression) $1, (string) $3);
\r
1569 | predefined_type DOT IDENTIFIER
\r
1571 $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location);
\r
1579 invocation_expression
\r
1580 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
\r
1583 // if $1 is MethodGroup
\r
1584 // $$ = new Call ($1, $3);
\r
1586 // $$ = new DelegateCall ($1, $3);
\r
1588 Location l = lexer.Location;
\r
1589 rc.Report.Error (1, l, "THIS IS CRAZY");
\r
1591 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
\r
1597 : /* empty */ { $$ = null; }
\r
1604 ArrayList list = new ArrayList ();
\r
1608 | argument_list COMMA argument
\r
1610 ArrayList list = (ArrayList) $1;
\r
1619 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
\r
1621 | REF variable_reference
\r
1623 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
\r
1625 | OUT variable_reference
\r
1627 $$ = new Argument ((Expression) $2, Argument.AType.Out);
\r
1631 variable_reference
\r
1632 : expression { note ("section 5.4"); $$ = $1; }
\r
1636 : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET
\r
1638 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3);
\r
1645 ArrayList list = new ArrayList ();
\r
1649 | expression_list COMMA expression
\r
1651 ArrayList list = (ArrayList) $1;
\r
1665 : BASE DOT IDENTIFIER
\r
1667 $$ = new BaseAccess (BaseAccess.BaseAccessType.Member, (string) $3, null);
\r
1669 | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
\r
1671 $$ = new BaseAccess (BaseAccess.BaseAccessType.Indexer, null, (ArrayList) $3);
\r
1675 post_increment_expression
\r
1676 : primary_expression OP_INC
\r
1678 $$ = new Unary (Unary.Operator.PostIncrement, (Expression) $1, lexer.Location);
\r
1682 post_decrement_expression
\r
1683 : primary_expression OP_DEC
\r
1685 $$ = new Unary (Unary.Operator.PostDecrement, (Expression) $1, lexer.Location);
\r
1690 : object_or_delegate_creation_expression
\r
1691 | array_creation_expression
\r
1694 object_or_delegate_creation_expression
\r
1695 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
\r
1697 $$ = new New ((string) $2, (ArrayList) $4, lexer.Location);
\r
1701 array_creation_expression
\r
1702 : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET
\r
1703 opt_rank_specifier
\r
1704 opt_array_initializer
\r
1706 $$ = new New ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
\r
1710 opt_rank_specifier
\r
1726 | rank_specifier rank_specifiers
\r
1728 $$ = (string) $1 + (string) $2;
\r
1733 : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
\r
1735 $$ = "[" + (string) $2 + "]";
\r
1739 opt_dim_separators
\r
1755 | dim_separators COMMA
\r
1757 $$ =(string) $1 + ",";
\r
1761 opt_array_initializer
\r
1766 | array_initializer
\r
1773 : OPEN_BRACE CLOSE_BRACE
\r
1775 ArrayList list = new ArrayList ();
\r
1778 | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
\r
1780 $$ = (ArrayList) $2;
\r
1784 variable_initializer_list
\r
1785 : variable_initializer
\r
1787 ArrayList list = new ArrayList ();
\r
1791 | variable_initializer_list COMMA variable_initializer
\r
1793 ArrayList list = (ArrayList) $1;
\r
1800 : TYPEOF OPEN_PARENS type CLOSE_PARENS
\r
1802 $$ = new TypeOf ((string) $3);
\r
1807 : SIZEOF OPEN_PARENS type CLOSE_PARENS {
\r
1808 $$ = new SizeOf ((string) $3);
\r
1810 note ("Verify type is unmanaged");
\r
1811 note ("if (5.8) builtin, yield constant expression");
\r
1815 checked_expression
\r
1816 : CHECKED OPEN_PARENS expression CLOSE_PARENS
\r
1818 $$ = new CheckedExpr ((Expression) $3);
\r
1822 unchecked_expression
\r
1823 : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
\r
1825 $$ = new UnCheckedExpr ((Expression) $3);
\r
1830 : primary_expression
\r
1831 | PLUS unary_expression {
\r
1832 $$ = new Unary (Unary.Operator.Addition, (Expression) $2, lexer.Location);
\r
1834 | MINUS unary_expression
\r
1836 $$ = new Unary (Unary.Operator.Subtraction, (Expression) $2, lexer.Location);
\r
1838 | BANG unary_expression
\r
1840 $$ = new Unary (Unary.Operator.Negate, (Expression) $2, lexer.Location);
\r
1842 | TILDE unary_expression
\r
1844 $$ = new Unary (Unary.Operator.BitComplement, (Expression) $2, lexer.Location);
\r
1846 | STAR unary_expression
\r
1848 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, lexer.Location);
\r
1850 | BITWISE_AND unary_expression
\r
1852 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, lexer.Location);
\r
1854 | OP_INC unary_expression
\r
1856 $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
\r
1858 | OP_DEC unary_expression
\r
1860 $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
\r
1862 | cast_expression
\r
1864 we can not do cast expressions at this level,
\r
1865 as there is an ambiguity. Check "Cast Expressions" 7.6.8
\r
1866 for the recipe to handle this.
\r
1870 pre_increment_expression
\r
1871 : OP_INC unary_expression
\r
1873 $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
\r
1877 pre_decrement_expression
\r
1878 : OP_DEC unary_expression
\r
1880 $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
\r
1886 * FIXME: This is actually wrong, it should be `type' but that
\r
1887 * introduces a lot of {shift,reduce}/reduces
\r
1889 * This is really really wrong. We need to track down
\r
1890 * the source of problems with QIs because expressions like:
\r
1891 * foreach (string s in (string []) object) wont be parsed.
\r
1893 : OPEN_PARENS qualified_identifier CLOSE_PARENS unary_expression
\r
1895 $$ = new Cast ((string) $2, (Expression) $4);
\r
1897 | OPEN_PARENS builtin_types CLOSE_PARENS unary_expression
\r
1899 $$ = new Cast ((string) $2, (Expression) $4);
\r
1903 multiplicative_expression
\r
1904 : unary_expression
\r
1905 | multiplicative_expression STAR unary_expression
\r
1907 $$ = new Binary (Binary.Operator.Multiply,
\r
1908 (Expression) $1, (Expression) $3, lexer.Location);
\r
1910 | multiplicative_expression DIV unary_expression
\r
1912 $$ = new Binary (Binary.Operator.Division,
\r
1913 (Expression) $1, (Expression) $3, lexer.Location);
\r
1915 | multiplicative_expression PERCENT unary_expression
\r
1917 $$ = new Binary (Binary.Operator.Modulus,
\r
1918 (Expression) $1, (Expression) $3, lexer.Location);
\r
1922 additive_expression
\r
1923 : multiplicative_expression
\r
1924 | additive_expression PLUS multiplicative_expression
\r
1926 $$ = new Binary (Binary.Operator.Addition,
\r
1927 (Expression) $1, (Expression) $3, lexer.Location);
\r
1929 | additive_expression MINUS multiplicative_expression
\r
1931 $$ = new Binary (Binary.Operator.Subtraction,
\r
1932 (Expression) $1, (Expression) $3, lexer.Location);
\r
1937 : additive_expression
\r
1938 | shift_expression OP_SHIFT_LEFT additive_expression
\r
1940 $$ = new Binary (Binary.Operator.LeftShift,
\r
1941 (Expression) $1, (Expression) $3, lexer.Location);
\r
1943 | shift_expression OP_SHIFT_RIGHT additive_expression
\r
1945 $$ = new Binary (Binary.Operator.RightShift,
\r
1946 (Expression) $1, (Expression) $3, lexer.Location);
\r
1950 relational_expression
\r
1951 : shift_expression
\r
1952 | relational_expression OP_LT shift_expression
\r
1954 $$ = new Binary (Binary.Operator.LessThan,
\r
1955 (Expression) $1, (Expression) $3, lexer.Location);
\r
1957 | relational_expression OP_GT shift_expression
\r
1959 $$ = new Binary (Binary.Operator.GreaterThan,
\r
1960 (Expression) $1, (Expression) $3, lexer.Location);
\r
1962 | relational_expression OP_LE shift_expression
\r
1964 $$ = new Binary (Binary.Operator.LessThanOrEqual,
\r
1965 (Expression) $1, (Expression) $3, lexer.Location);
\r
1967 | relational_expression OP_GE shift_expression
\r
1969 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
\r
1970 (Expression) $1, (Expression) $3, lexer.Location);
\r
1972 | relational_expression IS type
\r
1974 $$ = new Probe (Probe.Operator.Is,
\r
1975 (Expression) $1, (string) $3);
\r
1977 | relational_expression AS type
\r
1979 $$ = new Probe (Probe.Operator.As,
\r
1980 (Expression) $1, (string) $3);
\r
1984 equality_expression
\r
1985 : relational_expression
\r
1986 | equality_expression OP_EQ relational_expression
\r
1988 $$ = new Binary (Binary.Operator.Equality,
\r
1989 (Expression) $1, (Expression) $3, lexer.Location);
\r
1991 | equality_expression OP_NE relational_expression
\r
1993 $$ = new Binary (Binary.Operator.Inequality,
\r
1994 (Expression) $1, (Expression) $3, lexer.Location);
\r
1999 : equality_expression
\r
2000 | and_expression BITWISE_AND equality_expression
\r
2002 $$ = new Binary (Binary.Operator.BitwiseAnd,
\r
2003 (Expression) $1, (Expression) $3, lexer.Location);
\r
2007 exclusive_or_expression
\r
2009 | exclusive_or_expression CARRET and_expression
\r
2011 $$ = new Binary (Binary.Operator.ExclusiveOr,
\r
2012 (Expression) $1, (Expression) $3, lexer.Location);
\r
2016 inclusive_or_expression
\r
2017 : exclusive_or_expression
\r
2018 | inclusive_or_expression BITWISE_OR exclusive_or_expression
\r
2020 $$ = new Binary (Binary.Operator.BitwiseOr,
\r
2021 (Expression) $1, (Expression) $3, lexer.Location);
\r
2025 conditional_and_expression
\r
2026 : inclusive_or_expression
\r
2027 | conditional_and_expression OP_AND inclusive_or_expression
\r
2029 $$ = new Binary (Binary.Operator.LogicalAnd,
\r
2030 (Expression) $1, (Expression) $3, lexer.Location);
\r
2034 conditional_or_expression
\r
2035 : conditional_and_expression
\r
2036 | conditional_or_expression OP_OR conditional_and_expression
\r
2038 $$ = new Binary (Binary.Operator.LogicalOr,
\r
2039 (Expression) $1, (Expression) $3, lexer.Location);
\r
2043 conditional_expression
\r
2044 : conditional_or_expression
\r
2045 | conditional_or_expression INTERR expression COLON expression
\r
2047 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5);
\r
2051 assignment_expression
\r
2052 : unary_expression ASSIGN expression
\r
2054 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
\r
2056 | unary_expression OP_MULT_ASSIGN expression
\r
2058 Location l = lexer.Location;
\r
2060 $$ = new Assign ((Expression) $1,
\r
2061 new Binary (Binary.Operator.Multiply,
\r
2063 (Expression) $3, l), l);
\r
2065 | unary_expression OP_DIV_ASSIGN expression
\r
2067 Location l = lexer.Location;
\r
2069 $$ = new Assign ((Expression) $1,
\r
2070 new Binary (Binary.Operator.Division,
\r
2072 (Expression) $3, l), l);
\r
2074 | unary_expression OP_MOD_ASSIGN expression
\r
2076 Location l = lexer.Location;
\r
2078 $$ = new Assign ((Expression) $1,
\r
2079 new Binary (Binary.Operator.Modulus,
\r
2081 (Expression) $3, l), l);
\r
2083 | unary_expression OP_ADD_ASSIGN expression
\r
2085 Location l = lexer.Location;
\r
2087 $$ = new Assign ((Expression) $1,
\r
2088 new Binary (Binary.Operator.Addition,
\r
2090 (Expression) $3, l), l);
\r
2092 | unary_expression OP_SUB_ASSIGN expression
\r
2094 Location l = lexer.Location;
\r
2096 $$ = new Assign ((Expression) $1,
\r
2097 new Binary (Binary.Operator.Subtraction,
\r
2099 (Expression) $3, l), l);
\r
2101 | unary_expression OP_SHIFT_LEFT_ASSIGN expression
\r
2103 Location l = lexer.Location;
\r
2105 $$ = new Assign ((Expression) $1,
\r
2106 new Binary (Binary.Operator.LeftShift,
\r
2108 (Expression) $3, l), l);
\r
2110 | unary_expression OP_SHIFT_RIGHT_ASSIGN expression
\r
2112 Location l = lexer.Location;
\r
2114 $$ = new Assign ((Expression) $1,
\r
2115 new Binary (Binary.Operator.RightShift,
\r
2117 (Expression) $3, l), l);
\r
2119 | unary_expression OP_AND_ASSIGN expression
\r
2121 Location l = lexer.Location;
\r
2123 $$ = new Assign ((Expression) $1,
\r
2124 new Binary (Binary.Operator.BitwiseAnd,
\r
2126 (Expression) $3, l), l);
\r
2128 | unary_expression OP_OR_ASSIGN expression
\r
2130 Location l = lexer.Location;
\r
2132 $$ = new Assign ((Expression) $1,
\r
2133 new Binary (Binary.Operator.BitwiseOr,
\r
2135 (Expression) $3, l), l);
\r
2137 | unary_expression OP_XOR_ASSIGN expression
\r
2139 Location l = lexer.Location;
\r
2141 $$ = new Assign ((Expression) $1,
\r
2142 new Binary (Binary.Operator.ExclusiveOr,
\r
2144 (Expression) $3, l), l);
\r
2149 : conditional_expression
\r
2150 | assignment_expression
\r
2153 constant_expression
\r
2157 boolean_expression
\r
2158 : expression { CheckBoolean ((Expression) $1); $$ = $1; }
\r
2170 string full_class_name = MakeName ((string) $4);
\r
2172 new_class = new Class (rc, current_container, full_class_name, (int) $2, (Attributes) $1);
\r
2173 current_container = new_class;
\r
2174 current_container.Namespace = current_namespace;
\r
2175 tree.RecordClass (full_class_name, new_class);
\r
2181 Class new_class = (Class) current_container;
\r
2184 new_class.Bases = (ArrayList) $6;
\r
2186 current_container = current_container.Parent;
\r
2187 CheckDef (current_container.AddClass (new_class), new_class.Name);
\r
2194 : /* empty */ { $$ = (int) 0; }
\r
2200 | modifiers modifier
\r
2202 int m1 = (int) $1;
\r
2203 int m2 = (int) $2;
\r
2205 if ((m1 & m2) != 0) {
\r
2206 Location l = lexer.Location;
\r
2207 rc.Report.Error (1002, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
\r
2209 $$ = (int) (m1 | m2);
\r
2214 : NEW { $$ = Modifiers.NEW; }
\r
2215 | PUBLIC { $$ = Modifiers.PUBLIC; }
\r
2216 | PROTECTED { $$ = Modifiers.PROTECTED; }
\r
2217 | INTERNAL { $$ = Modifiers.INTERNAL; }
\r
2218 | PRIVATE { $$ = Modifiers.PRIVATE; }
\r
2219 | ABSTRACT { $$ = Modifiers.ABSTRACT; }
\r
2220 | SEALED { $$ = Modifiers.SEALED; }
\r
2221 | STATIC { $$ = Modifiers.STATIC; }
\r
2222 | READONLY { $$ = Modifiers.READONLY; }
\r
2223 | VIRTUAL { $$ = Modifiers.VIRTUAL; }
\r
2224 | OVERRIDE { $$ = Modifiers.OVERRIDE; }
\r
2225 | EXTERN { $$ = Modifiers.EXTERN; }
\r
2229 : /* empty */ { $$ = null; }
\r
2230 | class_base { $$ = $1; }
\r
2234 : COLON type_list { $$ = $2; }
\r
2238 // Statements (8.2)
\r
2242 // A block is "contained" on the following places:
\r
2244 // property_declaration as part of the accessor body (get/set)
\r
2245 // operator_declaration
\r
2246 // constructor_declaration
\r
2247 // destructor_declaration
\r
2248 // event_declaration as part of add_accessor_declaration or remove_accessor_declaration
\r
2253 current_block = new Block (current_block);
\r
2255 opt_statement_list CLOSE_BRACE
\r
2257 while (current_block.Implicit)
\r
2258 current_block = current_block.Parent;
\r
2259 $$ = current_block;
\r
2260 current_block = current_block.Parent;
\r
2264 opt_statement_list
\r
2271 | statement_list statement
\r
2275 : declaration_statement
\r
2277 if ((Block) $1 != current_block){
\r
2278 current_block.AddStatement ((Statement) $1);
\r
2279 current_block = (Block) $1;
\r
2282 | embedded_statement
\r
2284 current_block.AddStatement ((Statement) $1);
\r
2286 | labeled_statement
\r
2288 current_block.AddStatement ((Statement) $1);
\r
2292 embedded_statement
\r
2295 | expression_statement
\r
2296 | selection_statement
\r
2297 | iteration_statement
\r
2300 | checked_statement
\r
2301 | unchecked_statement
\r
2309 $$ = new EmptyStatement ();
\r
2314 : IDENTIFIER COLON statement
\r
2316 string lab = (String) $1;
\r
2319 block = new Block (current_block, lab);
\r
2320 block.AddStatement ((Statement) $3);
\r
2323 if (!current_block.AddLabel (lab, block)){
\r
2324 Location l = lexer.Location;
\r
2325 rc.Report.Error (140, l, "The label '" + lab + "' is a duplicate");
\r
2331 declaration_statement
\r
2332 : local_variable_declaration SEMICOLON // done
\r
2333 | local_constant_declaration SEMICOLON // finishme
\r
2337 * The following is from Rhys' grammar:
\r
2338 * > Types in local variable declarations must be recognized as
\r
2339 * > expressions to prevent reduce/reduce errors in the grammar.
\r
2340 * > The expressions are converted into types during semantic analysis.
\r
2342 local_variable_type
\r
2343 : primary_expression type_suffixes
\r
2345 // FIXME: Do something smart here regarding the composition of the type.
\r
2347 // Ok, the above "primary_expression" is there to get rid of
\r
2348 // both reduce/reduce and shift/reduces in the grammar, it should
\r
2349 // really just be "type_name". If you use type_name, a reduce/reduce
\r
2350 // creeps up. If you use qualified_identifier (which is all we need
\r
2351 // really) two shift/reduces appear.
\r
2353 // So, instead we do a super trick: we just allow ($1) to be a
\r
2354 // SimpleName Expression.
\r
2356 if (((Expression) $1) is SimpleName)
\r
2357 $$ = ((SimpleName) $1).Name;
\r
2359 Location l = lexer.Location;
\r
2360 rc.Report.Error (-1, l, "Invalid Type definition");
\r
2361 $$ = "System.Object";
\r
2364 | builtin_types type_suffixes
\r
2366 $$ = (string) $1 + (string) $2;
\r
2370 // FIXME : How can the type of a local variable be void ? I don't quite see ;-)
\r
2373 // // FIXME: this is a string that represents the type
\r
2374 // // Figure out something to make this work.
\r
2384 | type_suffix_list
\r
2389 | type_suffix_list type_suffix
\r
2391 $$ = (string) $1 + (string) $2;
\r
2396 : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
\r
2398 $$ = "[" + (string) $2 + "]";
\r
2402 local_variable_declaration
\r
2403 : local_variable_type variable_declarators
\r
2405 $$ = declare_local_variables ((string) $1, (ArrayList) $2);
\r
2409 local_constant_declaration
\r
2410 : CONST type constant_declarator
\r
2414 expression_statement
\r
2415 : statement_expression SEMICOLON
\r
2422 // We have to do the wrapping here and not in the case above,
\r
2423 // because statement_expression is used for example in for_statement
\r
2425 statement_expression
\r
2426 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2427 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2428 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2429 | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2430 | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2431 | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2432 | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
\r
2435 object_creation_expression
\r
2436 : object_or_delegate_creation_expression
\r
2437 { note ("complain if this is a delegate maybe?"); }
\r
2440 selection_statement
\r
2442 | switch_statement
\r
2446 : IF OPEN_PARENS boolean_expression CLOSE_PARENS
\r
2447 embedded_statement
\r
2449 $$ = new If ((Expression) $3, (Statement) $5);
\r
2451 | IF OPEN_PARENS boolean_expression CLOSE_PARENS
\r
2452 embedded_statement ELSE embedded_statement
\r
2454 $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7);
\r
2459 : SWITCH OPEN_PARENS expression CLOSE_PARENS
\r
2462 $$ = new Switch ((Expression) $3, (ArrayList) $5);
\r
2468 opt_switch_sections
\r
2475 opt_switch_sections
\r
2476 : /* empty */ { $$ = new ArrayList (); }
\r
2483 ArrayList sections = new ArrayList ();
\r
2485 sections.Add ($1);
\r
2488 | switch_sections switch_section
\r
2490 ArrayList sections = (ArrayList) $1;
\r
2492 sections.Add ($2);
\r
2500 current_block = new Block (current_block);
\r
2504 while (current_block.Implicit)
\r
2505 current_block = current_block.Parent;
\r
2506 $$ = new SwitchSection ((ArrayList) $1, current_block);
\r
2507 current_block = current_block.Parent;
\r
2514 ArrayList labels = new ArrayList ();
\r
2519 | switch_labels switch_label
\r
2521 ArrayList labels = (ArrayList) ($1);
\r
2529 : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2); }
\r
2530 | DEFAULT COLON { $$ = new SwitchLabel (null); }
\r
2533 iteration_statement
\r
2537 | foreach_statement
\r
2541 : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
\r
2543 $$ = new While ((Expression) $3, (Statement) $5);
\r
2548 : DO embedded_statement
\r
2549 WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
\r
2551 $$ = new Do ((Statement) $2, (Expression) $5);
\r
2556 : FOR OPEN_PARENS
\r
2557 opt_for_initializer SEMICOLON
\r
2558 opt_for_condition SEMICOLON
\r
2559 opt_for_iterator CLOSE_PARENS
\r
2560 embedded_statement
\r
2562 $$ = new For ((Statement) $3, (Expression) $5, (Statement) $7, (Statement) $9);
\r
2566 opt_for_initializer
\r
2567 : /* empty */ { $$ = new EmptyStatement (); }
\r
2568 | for_initializer
\r
2572 : local_variable_declaration
\r
2573 | statement_expression_list
\r
2577 : /* empty */ { $$ = new BoolLiteral (true); }
\r
2578 | boolean_expression
\r
2582 : /* empty */ { $$ = new EmptyStatement (); }
\r
2587 : statement_expression_list
\r
2590 statement_expression_list
\r
2591 : statement_expression
\r
2593 Block b = new Block (null, true);
\r
2595 b.AddStatement ((Statement) $1);
\r
2598 | statement_expression_list COMMA statement_expression
\r
2600 Block b = (Block) $1;
\r
2602 b.AddStatement ((Statement) $3);
\r
2608 : FOREACH OPEN_PARENS type IDENTIFIER IN expression CLOSE_PARENS
\r
2609 embedded_statement
\r
2611 string temp_id = current_block.MakeInternalID ();
\r
2612 ExpressionStatement assign_e;
\r
2614 Statement getcurrent;
\r
2615 Block foreach_block, child_block;
\r
2617 foreach_block = new Block (current_block, true);
\r
2619 foreach_block.AddVariable ("System.IEnumerator", temp_id);
\r
2620 foreach_block.AddVariable ((string) $3, (string) $4);
\r
2621 assign_e = new Assign (new LocalVariableReference (foreach_block, temp_id),
\r
2623 new MemberAccess ((Expression) $6, "GetEnumerator"),
\r
2624 null, lexer.Location), lexer.Location);
\r
2625 current_block.AddStatement (new StatementExpression (assign_e));
\r
2626 ma = new MemberAccess (new LocalVariableReference (foreach_block, temp_id), "MoveNext");
\r
2627 child_block = new Block (current_block);
\r
2629 getcurrent = new StatementExpression (
\r
2631 new LocalVariableReference (foreach_block, (string) $4),
\r
2634 new MemberAccess (
\r
2635 new LocalVariableReference (foreach_block, temp_id), "Current")),
\r
2638 child_block.AddStatement (getcurrent);
\r
2639 child_block.AddStatement ((Statement) $8);
\r
2640 foreach_block.AddStatement (new While (ma, (Statement) child_block));
\r
2642 $$ = foreach_block;
\r
2648 | continue_statement
\r
2650 | return_statement
\r
2657 $$ = new Break ();
\r
2661 continue_statement
\r
2662 : CONTINUE SEMICOLON
\r
2664 $$ = new Continue ();
\r
2669 : GOTO IDENTIFIER SEMICOLON
\r
2671 $$ = new Goto ((string) $2);
\r
2673 | GOTO CASE constant_expression SEMICOLON
\r
2674 | GOTO DEFAULT SEMICOLON
\r
2678 : RETURN opt_expression SEMICOLON
\r
2680 $$ = new Return ((Expression) $2);
\r
2685 : THROW opt_expression SEMICOLON
\r
2687 $$ = new Throw ((Expression) $2);
\r
2697 : TRY block catch_clauses
\r
2700 ArrayList s = new ArrayList ();
\r
2702 foreach (Catch cc in (ArrayList) $3) {
\r
2703 if (cc.Type == null)
\r
2709 // Now s contains the list of specific catch clauses
\r
2710 // and g contains the general one.
\r
2712 $$ = new Try ((Block) $2, s, g, null);
\r
2714 | TRY block opt_catch_clauses FINALLY block
\r
2717 ArrayList s = new ArrayList ();
\r
2719 foreach (Catch cc in (ArrayList) $3) {
\r
2720 if (cc.Type == null)
\r
2726 $$ = new Try ((Block) $2, s, g, (Block) $5);
\r
2731 : /* empty */ { $$ = null; }
\r
2738 ArrayList l = new ArrayList ();
\r
2743 | catch_clauses catch_clause
\r
2745 ArrayList l = (ArrayList) $1;
\r
2753 : /* empty */ { $$ = null; }
\r
2758 : CATCH opt_catch_args block
\r
2760 string type = null;
\r
2764 DictionaryEntry cc = (DictionaryEntry) $2;
\r
2765 type = (string) cc.Key;
\r
2766 id = (string) cc.Value;
\r
2769 $$ = new Catch (type, id, (Block) $3);
\r
2774 : /* empty */ { $$ = null; }
\r
2779 : OPEN_PARENS type opt_identifier CLOSE_PARENS
\r
2781 $$ = new DictionaryEntry ($2, $3);
\r
2788 $$ = new Checked ((Block) $2);
\r
2792 unchecked_statement
\r
2795 $$ = new Unchecked ((Block) $2);
\r
2800 : LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement
\r
2802 $$ = new Lock ((Expression) $3, (Statement) $5);
\r
2807 : USING OPEN_PARENS resource_acquisition CLOSE_PARENS embedded_statement
\r
2811 resource_acquisition
\r
2812 : local_variable_declaration
\r
2820 // A class used to pass around variable declarations and constants
\r
2822 public class VariableDeclaration {
\r
2823 public string identifier;
\r
2824 public object expression_or_array_initializer;
\r
2826 public VariableDeclaration (string id, object eoai){
\r
2827 this.identifier = id;
\r
2828 this.expression_or_array_initializer = eoai;
\r
2833 // A class used to hold info about an indexer declarator
\r
2836 public class IndexerDeclaration {
\r
2837 public string type;
\r
2838 public string interface_type;
\r
2839 public Parameters param_list;
\r
2841 public IndexerDeclaration (string type, string interface_type, Parameters param_list)
\r
2844 this.interface_type = interface_type;
\r
2845 this.param_list = param_list;
\r
2850 // A class used to hold info about an operator declarator
\r
2853 public class OperatorDeclaration {
\r
2854 public Operator.OpType optype;
\r
2855 public string ret_type;
\r
2856 public string arg1type;
\r
2857 public string arg1name;
\r
2858 public string arg2type;
\r
2859 public string arg2name;
\r
2861 public OperatorDeclaration (Operator.OpType op, string ret_type, string arg1type, string arg1name,
\r
2862 string arg2type, string arg2name)
\r
2865 this.ret_type = ret_type;
\r
2866 this.arg1type = arg1type;
\r
2867 this.arg1name = arg1name;
\r
2868 this.arg2type = arg2type;
\r
2869 this.arg2name = arg2name;
\r
2875 // Given the @class_name name, it creates a fully qualified name
\r
2876 // based on the containing declaration space
\r
2879 MakeName (string class_name)
\r
2881 string ns = current_namespace.Name;
\r
2882 string container_name = current_container.Name;
\r
2884 if (container_name == ""){
\r
2886 return ns + "." + class_name;
\r
2888 return class_name;
\r
2890 return container_name + "." + class_name;
\r
2894 // Used to report back to the user the result of a declaration
\r
2895 // in the current declaration space
\r
2898 CheckDef (DeclSpace.AdditionResult result, string name)
\r
2900 if (result == DeclSpace.AdditionResult.Success)
\r
2903 Location l = lexer.Location;
\r
2906 case DeclSpace.AdditionResult.NameExists:
\r
2907 rc.Report.Error (102, l, "The namespace `" + current_container.Name +
\r
2908 "' already contains a definition for `"+
\r
2913 // NEED TO HANDLE THIS IN SEMANTIC ANALYSIS:
\r
2915 // case DeclSpace.AdditionResult.MethodDuplicated:
\r
2916 // error (111, "Class `"+current_container.Name+
\r
2917 // "' already defines a member called '" +
\r
2918 // name + "' with the same parameter types");
\r
2921 case DeclSpace.AdditionResult.EnclosingClash:
\r
2922 rc.Report.Error (542, l, "Member names cannot be the same as their enclosing type");
\r
2925 case DeclSpace.AdditionResult.NotAConstructor:
\r
2926 rc.Report.Error (1520, l, "Class, struct, or interface method must have a return type");
\r
2932 CheckDef (bool result, string name)
\r
2936 CheckDef (DeclSpace.AdditionResult.NameExists, name);
\r
2940 SimpleLookup (string name)
\r
2943 // we need to check against current_block not being null
\r
2944 // as `expression' is allowed in argument_lists, which
\r
2945 // do not exist inside a block.
\r
2947 if (current_block != null){
\r
2948 if (current_block.IsVariableDefined (name))
\r
2949 return new LocalVariableReference (current_block, name);
\r
2952 if (current_local_parameters != null){
\r
2954 Parameter par = current_local_parameters.GetParameterByName (name, out idx);
\r
2956 return new ParameterReference (current_local_parameters, idx, name);
\r
2963 // Assumes that the name contains a `.' and tries to perform a simple lookup
\r
2964 // and shape the result to be a MemberAccess on a Local/Parameter
\r
2966 object CompositeLookup (string name)
\r
2968 int pos = name.IndexOf (".");
\r
2969 string left = name.Substring (0, pos);
\r
2972 o = SimpleLookup (left);
\r
2974 string right = name.Substring (pos + 1);
\r
2975 return new MemberAccess ((Expression) o, right);
\r
2981 object QualifiedIdentifier (string name, Location l)
\r
2985 if (name.IndexOf ('.') == -1)
\r
2986 o = SimpleLookup (name);
\r
2988 o = CompositeLookup (name);
\r
2991 o = new SimpleName (name, l);
\r
2996 Block declare_local_variables (string type, ArrayList variable_declarators)
\r
2998 Block implicit_block;
\r
2999 ArrayList inits = null;
\r
3002 // We use the `Used' property to check whether statements
\r
3003 // have been added to the current block. If so, we need
\r
3004 // to create another block to contain the new declaration
\r
3005 // otherwise, as an optimization, we use the same block to
\r
3006 // add the declaration.
\r
3008 // FIXME: A further optimization is to check if the statements
\r
3009 // that were added were added as part of the initialization
\r
3010 // below. In which case, no other statements have been executed
\r
3011 // and we might be able to reduce the number of blocks for
\r
3012 // situations like this:
\r
3014 // int j = 1; int k = j + 1;
\r
3016 if (current_block.Used)
\r
3017 implicit_block = new Block (current_block, true);
\r
3019 implicit_block = new Block (current_block, true);
\r
3021 foreach (VariableDeclaration decl in variable_declarators){
\r
3022 if (implicit_block.AddVariable (type, decl.identifier)){
\r
3023 if (decl.expression_or_array_initializer != null){
\r
3024 if (inits == null)
\r
3025 inits = new ArrayList ();
\r
3029 Location l = lexer.Location;
\r
3030 rc.Report.Error (128, l, "A local variable `" + decl.identifier +
\r
3031 "' is already defined in this scope");
\r
3035 if (inits == null)
\r
3036 return implicit_block;
\r
3038 foreach (VariableDeclaration decl in inits){
\r
3039 if (decl.expression_or_array_initializer is Expression){
\r
3040 Expression expr = (Expression) decl.expression_or_array_initializer;
\r
3043 assign = new Assign (new LocalVariableReference (
\r
3044 implicit_block, decl.identifier),
\r
3045 expr, lexer.Location);
\r
3046 implicit_block.AddStatement (new StatementExpression (assign));
\r
3048 Console.WriteLine ("Not handling Array initializers yet");
\r
3052 return implicit_block;
\r
3055 void CheckConstant (Expression expr)
\r
3060 void CheckBoolean (Expression expr)
\r
3065 void CheckAttributeTarget (string a)
\r
3069 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
\r
3073 Location l = lexer.Location;
\r
3074 rc.Report.Error (658, l, "Invalid attribute target");
\r
3080 void CheckUnaryOperator (Operator.OpType op)
\r
3084 case Operator.OpType.Negate:
\r
3085 case Operator.OpType.BitComplement:
\r
3086 case Operator.OpType.Increment:
\r
3087 case Operator.OpType.Decrement:
\r
3088 case Operator.OpType.True:
\r
3089 case Operator.OpType.False:
\r
3090 case Operator.OpType.Addition:
\r
3091 case Operator.OpType.Subtraction:
\r
3096 Location l = lexer.Location;
\r
3097 rc.Report.Error (1019, l, "Overloadable unary operator expected");
\r
3103 void CheckBinaryOperator (Operator.OpType op)
\r
3107 case Operator.OpType.Addition:
\r
3108 case Operator.OpType.Subtraction:
\r
3109 case Operator.OpType.Multiply:
\r
3110 case Operator.OpType.Division:
\r
3111 case Operator.OpType.Modulus:
\r
3112 case Operator.OpType.BitwiseAnd:
\r
3113 case Operator.OpType.BitwiseOr:
\r
3114 case Operator.OpType.ExclusiveOr:
\r
3115 case Operator.OpType.LeftShift:
\r
3116 case Operator.OpType.RightShift:
\r
3117 case Operator.OpType.Equality:
\r
3118 case Operator.OpType.Inequality:
\r
3119 case Operator.OpType.GreaterThan:
\r
3120 case Operator.OpType.LessThan:
\r
3121 case Operator.OpType.GreaterThanOrEqual:
\r
3122 case Operator.OpType.LessThanOrEqual:
\r
3126 Location l = lexer.Location;
\r
3127 rc.Report.Error (1020, l, "Overloadable binary operator expected");
\r
3133 void output (string s)
\r
3135 Console.WriteLine (s);
\r
3138 void note (string s)
\r
3140 // Used to put annotations
\r
3145 public Tokenizer Lexer {
\r
3151 public CSharpParser(RootContext rc, string name, System.IO.Stream input)
\r
3153 current_namespace = new Namespace (null, "");
\r
3155 this.tree = rc.Tree;
\r
3157 this.input = input;
\r
3158 current_container = tree.Types;
\r
3159 current_container.Namespace = current_namespace;
\r
3161 lexer = new Tokenizer (input, name);
\r
3164 public override int parse ()
\r
3166 StringBuilder value = new StringBuilder ();
\r
3168 global_errors = 0;
\r
3170 if (yacc_verbose_flag)
\r
3171 yyparse (lexer, new yydebug.yyDebugSimple ());
\r
3174 } catch (Exception e){
\r
3175 // Console.WriteLine ("Fatal error: " + name);
\r
3176 // Console.WriteLine (lexer.location);
\r
3178 Console.WriteLine (lexer.location + " : Parsing error");
\r
3179 Console.WriteLine (e);
\r
3183 return global_errors;
\r