コード例 #1
0
		void HandleVisitorParameterDeclarationVisited (ParameterDeclaration node, InspectionData data)
		{
			foreach (var rule in policy.Rules) {
				if (rule.CheckParameter (node, data))
					return;
			}
		}
コード例 #2
0
        public override void CompileTimeValidate(ParameterDeclaration parameter, Type memberType, IMessageSink messages)
        {
            base.CompileTimeValidate(parameter, memberType, messages);

            bool isString = memberType == typeof(string);

            if (!isString)
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "PatternAttribute_TypeNotSupported",
                    string.Format(CultureInfo.InvariantCulture, "The type '{0}' is not a string to perform the expression validation on.", memberType.Name),
                    GetType().FullName
                ));
            }

            if (string.IsNullOrEmpty(expression))
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "PatternAttribute_PatternNotNullOrEmpty",
                    "The expression pattern must not be null or empty.",
                    GetType().FullName
                ));
            }
        }
コード例 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ParameterValueToken"/> class
        /// with the specified parameter.
        /// </summary>
        /// <param name="parameter">Parameter whose value the token expands to.</param>
        /// <exception cref="ArgumentNullException"><paramref name="parameter"/> is <see langword="null"/>.</exception>
        public ParameterValueToken(ParameterDeclaration parameter)
        {
            if (parameter == null) {
                throw new ArgumentNullException("parameter");
            }

            this.parameter = parameter;
        }
コード例 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ReturnValueToken"/> class
        /// with the specified return parameter metadata.
        /// </summary>
        /// <param name="returnParameter">Return parameter metadata.</param>
        /// <exception cref="ArgumentNullException"><paramref name="returnParameter"/> is <see langword="null"/>.</exception>
        public ReturnValueToken(ParameterDeclaration returnParameter)
        {
            if (returnParameter == null) {
                throw new ArgumentNullException("returnParameter");
            }

            this.returnParameter = returnParameter;
        }
コード例 #5
0
            public override object VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, object data)
            {
                if (parameterDeclaration.ParameterModifier == ParameterModifier.Params)
                {
                    UnlockWith(parameterDeclaration);
                }

                return base.VisitParameterDeclaration(parameterDeclaration, data);
            }
コード例 #6
0
			public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration)
			{
				base.VisitParameterDeclaration (parameterDeclaration);

				if (parameterDeclaration.Parent is ConstructorDeclaration)
					return;
				if (HidesMember (ctx, parameterDeclaration, parameterDeclaration.Name))
					AddIssue (parameterDeclaration.NameToken,
						ctx.TranslateString ("Parameter has the same name as a member and hides it"));
			}
コード例 #7
0
		protected override void AssertInvocationExpression(InvocationExpression invocation, ParameterDeclaration parameter)
		{
			foreach (var member in invocation.Descendants.OfType<MemberReferenceExpression>())
			{
				if (member.MemberName == "LoadDocument")
					throw new InvalidOperationException("Reduce cannot contain LoadDocument() methods.");
			}

			base.AssertInvocationExpression(invocation, parameter);
		}
コード例 #8
0
			public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration)
			{
				base.VisitParameterDeclaration (parameterDeclaration);

				var resolveResult = ctx.Resolve (parameterDeclaration) as LocalResolveResult;
				if (resolveResult == null)
					return;
				if (!TestOnlyAssigned (ctx, unit, resolveResult.Variable))
					return;
				AddIssue (parameterDeclaration.NameToken, 
					ctx.TranslateString ("Parameter is assigned by its value is never used"));
			}
コード例 #9
0
ファイル: AstBuilder.cs プロジェクト: KleinR/ILSpy
        public static IEnumerable<ParameterDeclaration> MakeParameters(IEnumerable<ParameterDefinition> paramCol)
        {
            foreach(ParameterDefinition paramDef in paramCol) {
                ParameterDeclaration astParam = new ParameterDeclaration();
                astParam.Type = ConvertType(paramDef.ParameterType, paramDef);
                astParam.Name = paramDef.Name;

                if (!paramDef.IsIn && paramDef.IsOut) astParam.ParameterModifier = ParameterModifier.Out;
                if (paramDef.IsIn && paramDef.IsOut)  astParam.ParameterModifier = ParameterModifier.Ref;
                // TODO: params, this

                yield return astParam;
            }
        }
コード例 #10
0
			public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration)
			{
				base.VisitParameterDeclaration (parameterDeclaration);

				if (!(parameterDeclaration.Parent is MethodDeclaration))
					return;

				var resolveResult = ctx.Resolve (parameterDeclaration) as LocalResolveResult;
				if (resolveResult == null)
					return;
				if (FindUsage (ctx, unit, resolveResult.Variable, parameterDeclaration))
					return;

				AddIssue (parameterDeclaration.NameToken, ctx.TranslateString ("Parameter is never used"));
			}
コード例 #11
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration(parameterDeclaration);

                var resolveResult = ctx.Resolve(parameterDeclaration) as LocalResolveResult;
                if (resolveResult == null)
                    return;

                var parameterModifier = parameterDeclaration.ParameterModifier;
                if (parameterModifier == ParameterModifier.Out || parameterModifier == ParameterModifier.Ref ||
                    !TestOnlyAssigned(ctx, parameterDeclaration.Parent, resolveResult.Variable)) {
                    return;
                }
                AddIssue(parameterDeclaration.NameToken,
                    ctx.TranslateString("Parameter is assigned but its value is never used"));
            }
        public override void CompileTimeValidate(ParameterDeclaration parameter, Type memberType, IMessageSink messages)
        {
            base.CompileTimeValidate(parameter, memberType, messages);

            if(exception != null)
            {
                if(!ValidateExceptionTypeIsException(messages))
                {
                    return;
                }
                if(!ValidateExceptionTypeCanBeInstantiated(messages))
                {
                    return;
                }
            }
        }
コード例 #13
0
			public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration)
			{
				base.VisitParameterDeclaration (parameterDeclaration);
				if (parameterDeclaration.ParameterModifier == ParameterModifier.Out ||
					parameterDeclaration.ParameterModifier == ParameterModifier.Ref)
					return;

				var resolveResult = ctx.Resolve (parameterDeclaration) as LocalResolveResult;
				BlockStatement rootStatement = null;
				if (parameterDeclaration.Parent is MethodDeclaration) {
					rootStatement = ((MethodDeclaration)parameterDeclaration.Parent).Body;
				} else if (parameterDeclaration.Parent is AnonymousMethodExpression) {
					rootStatement = ((AnonymousMethodExpression)parameterDeclaration.Parent).Body;
				} else if (parameterDeclaration.Parent is LambdaExpression) {
					rootStatement = ((LambdaExpression)parameterDeclaration.Parent).Body as BlockStatement;
				}
				CollectIssues (parameterDeclaration, rootStatement, resolveResult);
			}
コード例 #14
0
        public override void CompileTimeValidate(ParameterDeclaration parameter, Type memberType, IMessageSink messages)
        {
            base.CompileTimeValidate(parameter, memberType, messages);

            bool isNullable =
                !memberType.IsValueType ||
                (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(Nullable<>));

            if (!isNullable)
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "NotNullAttribute_TypeNotNullable",
                    string.Format(CultureInfo.InvariantCulture, "The type '{0}' is not nullable.", memberType.Name),
                    GetType().FullName
                ));
            }
        }
コード例 #15
0
 public void ChainConstructorsFromBaseType(BooClassBuilder builder)
 {
     foreach (IConstructor constructor in builder.Entity.BaseType.GetConstructors())
     {
         ExpressionStatement        stmt       = this.CodeBuilder.CreateSuperConstructorInvocation(constructor);
         MethodInvocationExpression expression = stmt.Expression as MethodInvocationExpression;
         BooMethodBuilder           builder2   = builder.AddConstructor();
         int          index      = 0;
         IParameter[] parameters = constructor.GetParameters();
         int          length     = parameters.Length;
         while (index < length)
         {
             ParameterDeclaration parameter = builder2.AddParameter(parameters[index].Name, parameters[index].Type);
             expression.Arguments.Add(this.CodeBuilder.CreateReference(parameter));
             index++;
         }
         builder2.Body.Add(stmt);
     }
 }
コード例 #16
0
            void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
            {
                var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;

                if (localResolveResult == null)
                {
                    return;
                }
                var variable = localResolveResult.Variable;
                var typeKind = variable.Type.Kind;

                if (!(typeKind == TypeKind.Class ||
                      typeKind == TypeKind.Struct ||
                      typeKind == TypeKind.Interface ||
                      typeKind == TypeKind.Array) ||
                    parameter.Type is PrimitiveType ||
                    !collector.UsedVariables.Contains(variable))
                {
                    return;
                }

                var candidateTypes = localResolveResult.Type.GetAllBaseTypes().ToList();

                TypesChecked += candidateTypes.Count;
                var criterion = collector.GetCriterion(variable);

                var possibleTypes =
                    (from type in candidateTypes
                     where !type.Equals(localResolveResult.Type) && criterion.SatisfiedBy(type)
                     select type).ToList();

                TypeResolveCount += possibleTypes.Count;
                var validTypes =
                    (from type in possibleTypes
                     where (!tryResolve || TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type)) && !FilterOut(variable.Type, type)
                     select type).ToList();

                if (validTypes.Any())
                {
                    AddIssue(parameter, ctx.TranslateString("Parameter can be demoted to base class"), GetActions(parameter, validTypes));
                    MembersWithIssues++;
                }
            }
コード例 #17
0
ファイル: TypeMembersVisitor.cs プロジェクト: smartfish/PT.PM
        public override Ust VisitParameter(ParameterSyntax node)
        {
            SyntaxToken modifier = node.Modifiers.FirstOrDefault(m =>
                                                                 m.IsKind(SyntaxKind.OutKeyword) || m.IsKind(SyntaxKind.RefKeyword));
            InOutModifierLiteral inOut = null;

            if (!modifier.IsKind(SyntaxKind.None))
            {
                inOut = new InOutModifierLiteral(
                    modifier.IsKind(SyntaxKind.OutKeyword) ? InOutModifier.Out : InOutModifier.InOut,
                    modifier.GetTextSpan());
            }

            TypeToken type   = ConvertType(base.Visit(node.Type));
            var       id     = ConvertId(node.Identifier);
            var       result = new ParameterDeclaration(inOut, type, id, node.GetTextSpan());

            return(result);
        }
コード例 #18
0
ファイル: BooPrinterVisitor.cs プロジェクト: codehaus/boo
        override public void OnParameterDeclaration(ParameterDeclaration p)
        {
            WriteAttributes(p.Attributes, false);

            if (p.IsByRef)
            {
                WriteKeyword("ref ");
            }

            if (p.ParentNode.NodeType == NodeType.CallableTypeReference)
            {
                Visit(p.Type);
            }
            else
            {
                Write(p.Name);
                WriteTypeReference(p.Type);
            }
        }
コード例 #19
0
ファイル: TypeResolver.cs プロジェクト: almeswe/alm
        public static void ResolveMethodsParametersTypes(MethodInvokationExpression method)
        {
            TableMethod tableMethod = GlobalTable.Table.FetchMethod(method.Name, method.GetParametersTypes());

            if (tableMethod == null)
            {
                return;
            }
            for (int i = 0; i < tableMethod.ArgCount; i++)
            {
                TableMethodArgument  tableArgument       = tableMethod.Arguments[i];
                ParameterDeclaration methodParameter     = method.Parameters[i];
                InnerType            methodParameterType = ResolveExpressionType(methodParameter.ParameterInstance);
                if (tableArgument.Type != methodParameterType)
                {
                    ReportError(new IncompatibleMethodParameterType(method.Name, tableArgument.Type, methodParameterType, methodParameter.SourceContext));
                }
            }
        }
コード例 #20
0
            /// <summary>Matches simple lambdas of the form "a => b"</summary>
            bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body)
            {
                expr = StripCastAndParenthasis(expr);
                LambdaExpression lambda = expr as LambdaExpression;

                if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression)
                {
                    ParameterDeclaration p = lambda.Parameters.Single();
                    if (p.ParameterModifier == ParameterModifier.None)
                    {
                        parameterName = p.Name;
                        body          = (Expression)lambda.Body;
                        return(true);
                    }
                }
                parameterName = null;
                body          = null;
                return(false);
            }
コード例 #21
0
        private string UninitializedComparisonForParameter(ParameterDeclaration parameter)
        {
            var type = parameter.AsTypeName?.ToUpper() ?? string.Empty;

            if (string.IsNullOrEmpty(type))
            {
                type = parameter.HasTypeHint
                    ? SymbolList.TypeHintToTypeName[parameter.TypeHint].ToUpper()
                    : Tokens.Variant.ToUpper();
            }

            if (BaseTypeUninitializedValues.ContainsKey(type))
            {
                return($"{parameter.IdentifierName} = {BaseTypeUninitializedValues[type]}");
            }

            if (type.Equals(Tokens.Object, StringComparison.InvariantCultureIgnoreCase))
            {
                return($"{parameter.IdentifierName} Is {Tokens.Nothing}");
            }

            if (type.Equals(Tokens.Object, StringComparison.InvariantCultureIgnoreCase) || parameter.AsTypeDeclaration == null)
            {
                return($"IsEmpty({parameter.IdentifierName})");
            }

            switch (parameter.AsTypeDeclaration.DeclarationType)
            {
            case DeclarationType.ClassModule:
            case DeclarationType.Document:
                return($"{parameter.IdentifierName} Is {Tokens.Nothing}");

            case DeclarationType.Enumeration:
                var members = _declarationFinderProvider.DeclarationFinder.AllDeclarations.OfType <ValuedDeclaration>()
                              .FirstOrDefault(decl =>
                                              ReferenceEquals(decl.ParentDeclaration, parameter.AsTypeDeclaration) &&
                                              decl.Expression.Equals("0"));
                return($"{parameter.IdentifierName} = {members?.IdentifierName ?? "0"}");

            default:
                return($"IsError({parameter.IdentifierName})");
            }
        }
コード例 #22
0
        private static ParameterDeclaration ConvertToParameter(AstNode node, int position)
        {
            var paramDecl = new ParameterDeclaration(node.Context)
            {
                Position = position
            };

            // check to see if there's a unary spread operator
            var unaryOp = node as UnaryOperator;

            if (unaryOp != null && unaryOp.OperatorToken == JSToken.RestSpread)
            {
                // there is. convert the operand and set the has-rest property
                paramDecl.HasRest     = true;
                paramDecl.RestContext = unaryOp.OperatorContext;
                paramDecl.Binding     = ConvertToBinding(unaryOp.Operand);
            }
            else
            {
                // check to see if there's an assignment operator. If so, then the right hand side is the initializer.
                // or if there's a unary rest, in which case this is a rest operation.
                var binOp = node as BinaryOperator;
                if (binOp != null && binOp.OperatorToken == JSToken.Assign)
                {
                    // initializer
                    paramDecl.AssignContext = binOp.OperatorContext;
                    paramDecl.Initializer   = binOp.Operand2;

                    // and binding
                    paramDecl.Binding = ConvertToBinding(binOp.Operand1);
                }
                else
                {
                    // no initializer
                    paramDecl.Binding = ConvertToBinding(node);
                }
            }

            // if we couldn't get a binding, then ignore this entire parameter
            // (which will lose it and its initializer, if any)
            return(paramDecl.Binding != null ? paramDecl : null);
        }
 public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
 {
     base.VisitParameterDeclaration(parameterDeclaration);
     if (parameterDeclaration.ParameterModifier != ParameterModifier.Ref && parameterDeclaration.ParameterModifier != ParameterModifier.Out)
     {
         return;
     }
     foreach (var sect in parameterDeclaration.Attributes)
     {
         foreach (var attr in sect.Attributes)
         {
             var rr = ctx.Resolve(attr);
             if (rr.Type.Name == "OptionalAttribute" && rr.Type.Namespace == "System.Runtime.InteropServices")
             {
                 AddIssue(new CodeIssue(attr, ctx.TranslateString("A 'ref' or 'out' parameter can't be optional")));
                 return;
             }
         }
     }
 }
コード例 #24
0
        private static bool ThereAreHandlersAndNoneUsesTheParameter(ParameterDeclaration parameter, EventDeclaration eventDeclaration, DeclarationFinder finder)
        {
            if (!TryFindParameterIndex(parameter, eventDeclaration, out var parameterIndex))
            {
                //This really should never happen.
                Debug.Fail($"Could not find index for parameter {parameter.IdentifierName} in event {eventDeclaration.IdentifierName}.");
                return(false);
            }

            if (!eventDeclaration.IsUserDefined)
            {
                return(false);
            }

            var handlers = finder.FindEventHandlers(eventDeclaration).ToList();

            //We do not want to report all parameters of not handled events.
            return(handlers.Any() &&
                   handlers.All(handler => ParameterAtIndexIsNotUsed(handler, parameterIndex)));
        }
コード例 #25
0
        private ParameterDeclaration VisitArrayPatternElement(IArrayPatternElement arrayPatternElement)
        {
            ParameterDeclaration paramDecl;

            if (arrayPatternElement is Identifier identifier)
            {
                var name = VisitIdentifier(identifier);
                paramDecl = new ParameterDeclaration(null, null, name, name.TextSpan);
            }
            else if (arrayPatternElement is AssignmentPattern assignmentPattern)
            {
                var assignExpr = VisitAssignmentPattern(assignmentPattern);
                UstTokens.IdToken name;

                if (assignExpr.Left is UstTokens.IdToken idToken)
                {
                    name = idToken;
                }
                else
                {
                    Logger?.LogDebug($"Not {nameof(UstTokens.IdToken)} nodes are not support as parameter names"); // TODO
                    name = null;
                }

                paramDecl = new ParameterDeclaration(null, null, name, assignExpr.TextSpan)
                {
                    Initializer = assignExpr.Right
                };
            }
            else if (arrayPatternElement == null)
            {
                paramDecl = null;
            }
            else
            {
                // TODO: other types
                paramDecl = null;
            }

            return(paramDecl);
        }
コード例 #26
0
        private void AddDebugInfoForAlloca(Alloca argSlot, IrFunction function, ParameterDeclaration param)
        {
            uint line = ( uint )param.Location.StartLine;
            uint col  = ( uint )param.Location.StartColumn;

            DILocalVariable debugVar = Module.DIBuilder.CreateArgument(scope: function.DISubProgram
                                                                       , name: param.Name
                                                                       , file: function.DISubProgram.File
                                                                       , line
                                                                       , type: DoubleType
                                                                       , alwaysPreserve: true
                                                                       , debugFlags: DebugInfoFlags.None
                                                                       , argNo: checked (( ushort )(param.Index + 1)) // Debug index starts at 1!
                                                                       );

            Module.DIBuilder.InsertDeclare(storage: argSlot
                                           , varInfo: debugVar
                                           , location: new DILocation(Context, line, col, function.DISubProgram)
                                           , insertAtEnd: InstructionBuilder.InsertBlock
                                           );
        }
コード例 #27
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration(parameterDeclaration);

                var resolveResult = ctx.Resolve(parameterDeclaration) as LocalResolveResult;

                if (resolveResult == null)
                {
                    return;
                }

                var parameterModifier = parameterDeclaration.ParameterModifier;

                if (parameterModifier == ParameterModifier.Out || parameterModifier == ParameterModifier.Ref ||
                    !TestOnlyAssigned(ctx, parameterDeclaration.Parent, resolveResult.Variable))
                {
                    return;
                }
                AddIssue(new CodeIssue(parameterDeclaration.NameToken,
                                       ctx.TranslateString("Parameter is assigned but its value is never used")));
            }
コード例 #28
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration(parameterDeclaration);

                if (!(parameterDeclaration.Parent is MethodDeclaration))
                {
                    return;
                }

                var resolveResult = ctx.Resolve(parameterDeclaration) as LocalResolveResult;

                if (resolveResult == null)
                {
                    return;
                }
                if (FindUsage(ctx, unit, resolveResult.Variable, parameterDeclaration))
                {
                    return;
                }

                AddIssue(parameterDeclaration.NameToken, ctx.TranslateString("Parameter is never used"));
            }
        internal static bool Identify(
            ParameterDeclaration parameter,
            ClassMetadata classMetadata,
            TypeScriptAST ast,
            TypeOverrideDetails typeOverrideDetails,
            out TypeStatement type
            )
        {
            type = new TypeStatement
            {
                Name = GenerationIdentifiedTypes.Object,
            };
            if (IsUnionTypeRule.Check(parameter))
            {
                var unionNode = parameter.OfKind(
                    SyntaxKind.UnionType
                    ).FirstOrDefault()
                                .Children.Where(
                    // Make sure does not contain undefined
                    a => a.Kind != SyntaxKind.UndefinedKeyword &&
                    a.Kind != SyntaxKind.NullKeyword &&
                    a.Kind != SyntaxKind.TypeLiteral &&
                    a.Kind != SyntaxKind.LiteralType
                    ).ToList().FirstOrDefault();

                if (unionNode != null)
                {
                    type = GenericTypeIdentifier.Identify(
                        unionNode,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        );
                }

                return(true);
            }
            return(false);
        }
コード例 #30
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration(parameterDeclaration);

                if (parameterDeclaration.Parent is ConstructorDeclaration)
                {
                    return;
                }
                IMember member;

                if (HidesMember(ctx, parameterDeclaration, parameterDeclaration.Name, out member))
                {
                    string msg;
                    switch (member.SymbolKind)
                    {
                    case SymbolKind.Field:
                        msg = ctx.TranslateString("Parameter '{0}' hides field '{1}'");
                        break;

                    case SymbolKind.Method:
                        msg = ctx.TranslateString("Parameter '{0}' hides method '{1}'");
                        break;

                    case SymbolKind.Property:
                        msg = ctx.TranslateString("Parameter '{0}' hides property '{1}'");
                        break;

                    case SymbolKind.Event:
                        msg = ctx.TranslateString("Parameter '{0}' hides event '{1}'");
                        break;

                    default:
                        msg = ctx.TranslateString("Parameter '{0}' hides member '{1}'");
                        break;
                    }
                    AddIssue(parameterDeclaration.NameToken,
                             string.Format(msg, parameterDeclaration.Name, member.FullName));
                }
            }
コード例 #31
0
        protected override void CompileTimeValidateParameters(MethodDefDeclaration method, IMessageSink messages, ParameterDeclaration firstParameter, ParameterDeclaration secondParameter)
        {
            base.CompileTimeValidateParameters(method, messages, firstParameter, secondParameter);

            if(typeof(IComparable).IsAssignableFrom(firstParameter.ParameterType.GetSystemType(null, null)))
            {
                firstParameterIsComparable = true;
            }
            else if(typeof(IComparable).IsAssignableFrom(secondParameter.ParameterType.GetSystemType(null, null)))
            {
                firstParameterIsComparable = false;
            }
            else
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "ComparisonValidatorAttribute_ParametersCantBeCompared",
                    string.Format(CultureInfo.InvariantCulture, "None of the parameters '{0}' and '{1}' implements IComparable.", firstParameter.Name, secondParameter.Name),
                    GetType().FullName
                ));
            }
        }
コード例 #32
0
        /// <summary>
        /// Parse a list of parameter declaration separated by a comma. This could be included between parenthesis.
        ///
        /// Corresponding grammar :
        ///     Parameter_Declaration? ( ',' Parameter_Declaration)*
        /// </summary>
        /// <returns>Returns an array of parameter declaration.</returns>
        private ParameterDeclaration[] ParseParameterList()
        {
            var list = new List <ParameterDeclaration>();

            ParameterDeclaration parameterDeclaration = null;

            do
            {
                parameterDeclaration = ParseParameterDeclaration();
                if (parameterDeclaration != null)
                {
                    list.Add(parameterDeclaration);

                    if (CurrentToken.TokenType == TokenType.Comma)
                    {
                        DiscardToken();
                    }
                }
            } while (parameterDeclaration != null);

            return(list.ToArray());
        }
コード例 #33
0
        public void DeclareFieldsAndConstructor(BooClassBuilder builder)
        {
            // referenced entities turn into fields
            foreach (ITypedEntity entity in Builtins.array(_referencedEntities.Keys))
            {
                Field field = builder.AddField("__" + entity.Name + _context.AllocIndex(), entity.Type);
                field.Modifiers             = TypeMemberModifiers.Internal;
                _referencedEntities[entity] = field.Entity;
            }

            // single constructor taking all referenced entities
            BooMethodBuilder constructor = builder.AddConstructor();

            constructor.Body.Add(CodeBuilder.CreateSuperConstructorInvocation(builder.Entity.BaseType));
            foreach (ITypedEntity entity in _referencedEntities.Keys)
            {
                InternalField        field     = (InternalField)_referencedEntities[entity];
                ParameterDeclaration parameter = constructor.AddParameter(field.Name, entity.Type);
                constructor.Body.Add(
                    CodeBuilder.CreateAssignment(CodeBuilder.CreateReference(field),
                                                 CodeBuilder.CreateReference(parameter)));
            }
        }
コード例 #34
0
        private void VisitParameters(IEnumerable <ParameterDeclaration> @params, CodeParameterDeclarationExpressionCollection collection)
        {
            IEnumerator <ParameterDeclaration> enumerator = @params.GetEnumerator();

            try
            {
                while (enumerator.MoveNext())
                {
                    ParameterDeclaration current = enumerator.Current;
                    CodeParameterDeclarationExpression codeParameterDeclarationExpression = new CodeParameterDeclarationExpression(BooCodeDomConverter.GetType(current.Type.ToString()), current.Name);
                    if (current.Modifiers == ParameterModifiers.Ref)
                    {
                        codeParameterDeclarationExpression.Direction = FieldDirection.Ref;
                    }
                    this.VisitAttributes(current.Attributes, codeParameterDeclarationExpression.CustomAttributes);
                    collection.Add(codeParameterDeclarationExpression);
                }
            }
            finally
            {
                enumerator.Dispose();
            }
        }
コード例 #35
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration(parameterDeclaration);

                if (!(parameterDeclaration.Parent is MethodDeclaration))
                {
                    return;
                }

                var resolveResult = ctx.Resolve(parameterDeclaration) as LocalResolveResult;

                if (resolveResult == null)
                {
                    return;
                }

                if (ctx.FindReferences(parameterDeclaration.Parent, resolveResult.Variable).Any(r => r.Node != parameterDeclaration))
                {
                    return;
                }

                AddIssue(parameterDeclaration.NameToken, ctx.TranslateString("Parameter is never used"));
            }
コード例 #36
0
        public void BindParameterDeclarations(bool isStatic, INodeWithParameters node)
        {
            // arg0 is the this pointer when member is not static
            int delta = isStatic ? 0 : 1;
            ParameterDeclarationCollection parameters = node.Parameters;

            for (int i = 0; i < parameters.Count; ++i)
            {
                ParameterDeclaration parameter = parameters[i];
                if (null == parameter.Type)
                {
                    if (parameter.IsParamArray)
                    {
                        parameter.Type = CreateTypeReference(TypeSystemServices.ObjectArrayType);
                    }
                    else
                    {
                        parameter.Type = CreateTypeReference(TypeSystemServices.ObjectType);
                    }
                }
                parameter.Entity = new InternalParameter(parameter, i + delta);
            }
        }
コード例 #37
0
ファイル: ScriptTests.cs プロジェクト: 0xb1dd1e/NRefactory
        public void InsertFirstParameterDeclarationIntoMethod()
        {
            var input =@"
public class Test
{
	void Test()
	{
	}
}";
            var expected = @"
public class Test
{
	void Test(int a)
	{
	}
}";
            DoInsertAfterTest(input, expected, (syntaxTree, script) =>
            {
                var nodeToInsert = new ParameterDeclaration(new PrimitiveType("int"),"a");
                var nodeToInsertAfter = syntaxTree.DescendantsAndSelf.OfType<MethodDeclaration>().Single().LParToken;
                script.InsertAfter(nodeToInsertAfter,nodeToInsert);
            });
        }
コード例 #38
0
ファイル: ScriptTests.cs プロジェクト: 0xb1dd1e/NRefactory
        public void InsertParameterDeclarationDoesNotIndent()
        {
            var input =@"
public class Test
{
	void Test(int a)
	{
	}
}";
            var expected = @"
public class Test
{
	void Test(int a, int b)
	{
	}
}";
            DoInsertAfterTest(input, expected, (syntaxTree, script) =>
            {
                var nodeToInsert = new ParameterDeclaration(new PrimitiveType("int"),"b");
                var nodeToInsertAfter = syntaxTree.DescendantsAndSelf.OfType<ParameterDeclaration>().Single();
                script.InsertAfter(nodeToInsertAfter,nodeToInsert);
            });
        }
コード例 #39
0
 public ParameterDeclaration ConvertParameter(IParameter parameter)
 {
     if (parameter == null)
         throw new ArgumentNullException("parameter");
     ParameterDeclaration decl = new ParameterDeclaration();
     if (parameter.IsRef) {
         decl.ParameterModifier = ParameterModifier.Ref;
     } else if (parameter.IsOut) {
         decl.ParameterModifier = ParameterModifier.Out;
     } else if (parameter.IsParams) {
         decl.ParameterModifier = ParameterModifier.Params;
     }
     if (ShowAttributes) {
         decl.Attributes.AddRange (parameter.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
     }
     decl.Type = ConvertType(parameter.Type);
     if (this.ShowParameterNames) {
         decl.Name = parameter.Name;
     }
     if (parameter.IsOptional && this.ShowConstantValues) {
         decl.DefaultExpression = ConvertConstantValue(parameter.Type, parameter.ConstantValue);
     }
     return decl;
 }
コード例 #40
0
        public void InsertFirstParameterDeclarationIntoMethod()
        {
            var input    = @"
public class Test
{
	void Test()
	{
	}
}";
            var expected = @"
public class Test
{
	void Test(int a)
	{
	}
}";

            DoInsertAfterTest(input, expected, (syntaxTree, script) =>
            {
                var nodeToInsert      = new ParameterDeclaration(new PrimitiveType("int"), "a");
                var nodeToInsertAfter = syntaxTree.DescendantsAndSelf.OfType <MethodDeclaration>().Single().LParToken;
                script.InsertAfter(nodeToInsertAfter, nodeToInsert);
            });
        }
コード例 #41
0
        /// <summary>
        /// Parse a parameter declaration.
        ///
        /// Corresponding grammar:
        ///     Identifier ('[]')?
        /// </summary>
        /// <returns>Returns a parameter declaration if it is found, or a null value.</returns>
        private ParameterDeclaration ParseParameterDeclaration()
        {
            if (CurrentToken.TokenType == TokenType.Identifier)
            {
                var identifierToken = CurrentToken;
                var parameterName   = string.Empty;
                var parameterArray  = false;

                TokenIdentificationHelper.CheckIdentifier(CurrentToken.Value, CurrentToken, false, _issues);
                parameterName = CurrentToken.Value;
                DiscardToken();

                if (CurrentToken.TokenType == TokenType.LeftBracket)
                {
                    DiscardToken();
                    DiscardToken(TokenType.RightBracket);
                    parameterArray = true;
                }

                var parameterDeclaration = new ParameterDeclaration(parameterName, parameterArray)
                {
                    Line        = identifierToken.Line,
                    Column      = identifierToken.Column,
                    StartOffset = identifierToken.StartOffset,
                    NodeLength  = identifierToken.ParsedLength
                };
                AddParameter(parameterDeclaration);
                return(parameterDeclaration);
            }
            else if (CurrentToken.TokenType != TokenType.RightParenth)
            {
                AddIssue(new BaZicParserException(CurrentToken.Line, CurrentToken.Column, CurrentToken.StartOffset, CurrentToken.ParsedLength, L.BaZic.Parser.UnexpectedOrMissingCharacter));
            }

            return(null);
        }
コード例 #42
0
        //-----------------------------------------------------------
        private Type Visit(ParameterDeclaration node, Table table, ref int position)
        {
            LocalSymbolTable lstable = table as LocalSymbolTable;

            if (lstable == null)
            {
                throw new TypeAccessException("Expecting a LocalSymbolTable");
            }

            Type paramType = Visit((dynamic)node[1], table);

            foreach (var n in node[0])
            {
                var symbolName = n.AnchorToken.Lexeme;
                if (lstable.Contains(symbolName))
                {
                    throw new SemanticError("Duplicated symbol: " + symbolName, n.AnchorToken);
                }

                lstable[symbolName] = new LocalSymbol(position++, paramType);
            }

            return(Type.VOID);
        }
コード例 #43
0
        public void BindParameterDeclarations(bool isStatic, INodeWithParameters node)
        {
            // arg0 is the this pointer when member is not static
            int delta = isStatic ? 0 : 1;
            ParameterDeclarationCollection parameters = node.Parameters;
            int last = parameters.Count - 1;

            for (int i = 0; i < parameters.Count; ++i)
            {
                ParameterDeclaration parameter = parameters[i];
                if (null == parameter.Type)
                {
                    if (last == i && parameters.VariableNumber)
                    {
                        parameter.Type = CreateTypeReference(_tss.ObjectArrayType);
                    }
                    else
                    {
                        parameter.Type = CreateTypeReference(_tss.ObjectType);
                    }
                }
                parameter.Entity = new InternalParameter(parameter, i + delta);
            }
        }
コード例 #44
0
ファイル: InternalMethod.cs プロジェクト: codehaus/boo
        public virtual bool Resolve(List targetList, string name, EntityType flags)
        {
            if (NameResolutionService.IsFlagSet(flags, EntityType.Local))
            {
                Local local = ResolveLocal(name);
                if (null != local)
                {
                    targetList.Add(TypeSystemServices.GetEntity(local));
                    return(true);
                }
            }

            if (NameResolutionService.IsFlagSet(flags, EntityType.Parameter))
            {
                ParameterDeclaration parameter = ResolveParameter(name);
                if (null != parameter)
                {
                    targetList.Add(TypeSystemServices.GetEntity(parameter));
                    return(true);
                }
            }

            return(false);
        }
コード例 #45
0
        public virtual bool Resolve(ICollection <IEntity> resultingSet, string name, EntityType typesToConsider)
        {
            if (Entities.IsFlagSet(typesToConsider, EntityType.Local))
            {
                Local local = ResolveLocal(name);
                if (null != local)
                {
                    resultingSet.Add(TypeSystemServices.GetEntity(local));
                    return(true);
                }
            }

            if (Entities.IsFlagSet(typesToConsider, EntityType.Parameter))
            {
                ParameterDeclaration parameter = ResolveParameter(name);
                if (null != parameter)
                {
                    resultingSet.Add(TypeSystemServices.GetEntity(parameter));
                    return(true);
                }
            }

            return(false);
        }
コード例 #46
0
        public void InsertParameterDeclarationDoesNotIndent()
        {
            var input    = @"
public class Test
{
	void Test(int a)
	{
	}
}";
            var expected = @"
public class Test
{
	void Test(int a, int b)
	{
	}
}";

            DoInsertAfterTest(input, expected, (syntaxTree, script) =>
            {
                var nodeToInsert      = new ParameterDeclaration(new PrimitiveType("int"), "b");
                var nodeToInsertAfter = syntaxTree.DescendantsAndSelf.OfType <ParameterDeclaration>().Single();
                script.InsertAfter(nodeToInsertAfter, nodeToInsert);
            });
        }
コード例 #47
0
ファイル: Script.cs プロジェクト: 0xd4d/NRefactory
		public void ChangeModifier(ParameterDeclaration param, ParameterModifier modifier)
		{
			var child = param.FirstChild;
			Func<AstNode, bool> pred = s => s.Role == ParameterDeclaration.RefModifierRole || s.Role == ParameterDeclaration.OutModifierRole || s.Role == ParameterDeclaration.ParamsModifierRole || s.Role == ParameterDeclaration.ThisModifierRole;
			if (!pred(child))
				child = child.GetNextSibling(pred); 

			int offset;
			int endOffset;

			if (child != null) {
				offset = GetCurrentOffset(child.StartLocation);
				endOffset = GetCurrentOffset(child.GetNextSibling (s => s.Role != Roles.NewLine && s.Role != Roles.Whitespace).StartLocation);
			} else {
				offset = endOffset = GetCurrentOffset(param.Type.StartLocation);
			}
			string modString;
			switch (modifier) {
				case ParameterModifier.None:
					modString = "";
					break;
				case ParameterModifier.Ref:
					modString = "ref ";
					break;
				case ParameterModifier.Out:
					modString = "out ";
					break;
				case ParameterModifier.Params:
					modString = "params ";
					break;
				case ParameterModifier.This:
					modString = "this ";
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
			Replace(offset, endOffset - offset, modString);
		}
コード例 #48
0
ファイル: CSharpOutputVisitor.cs プロジェクト: x-strong/ILSpy
		public void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
		{
			StartNode(parameterDeclaration);
			WriteAttributes(parameterDeclaration.Attributes);
			switch (parameterDeclaration.ParameterModifier) {
				case ParameterModifier.Ref:
					WriteKeyword(ParameterDeclaration.RefModifierRole);
					break;
				case ParameterModifier.Out:
					WriteKeyword(ParameterDeclaration.OutModifierRole);
					break;
				case ParameterModifier.Params:
					WriteKeyword(ParameterDeclaration.ParamsModifierRole);
					break;
				case ParameterModifier.This:
					WriteKeyword(ParameterDeclaration.ThisModifierRole);
					break;
			}
			parameterDeclaration.Type.AcceptVisitor(this);
			if (!parameterDeclaration.Type.IsNull && !string.IsNullOrEmpty(parameterDeclaration.Name)) {
				Space();
			}
			if (!string.IsNullOrEmpty(parameterDeclaration.Name)) {
				parameterDeclaration.NameToken.AcceptVisitor(this);
			}
			if (!parameterDeclaration.DefaultExpression.IsNull) {
				Space(policy.SpaceAroundAssignment);
				WriteToken(Roles.Assign);
				Space(policy.SpaceAroundAssignment);
				parameterDeclaration.DefaultExpression.AcceptVisitor(this);
			}
			EndNode(parameterDeclaration);
		}
コード例 #49
0
 public void VisitParameterDeclaration(ParameterDeclaration parameterDecl)
 {
     UniqueIdGenerator.DefineNewId(parameterDecl.NameToken);
 }
		public virtual void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration)
		{
			VisitChildren (parameterDeclaration);
		}
コード例 #51
0
ファイル: CSharpParser.cs プロジェクト: 0xb1dd1e/NRefactory
			ParameterDeclaration ConvertXmlDocParameter(DocumentationParameter p)
			{
				var result = new ParameterDeclaration();
				switch (p.Modifier) {
					case Parameter.Modifier.OUT:
						result.ParameterModifier = ParameterModifier.Out;
						break;
					case Parameter.Modifier.REF:
						result.ParameterModifier = ParameterModifier.Ref;
						break;
					case Parameter.Modifier.PARAMS:
						result.ParameterModifier = ParameterModifier.Params;
						break;
				}
				if (p.Type != null) {
					result.Type = ConvertToType(p.Type);
				}
				return result;
			}
コード例 #52
0
        /// <summary>
        /// Refactors the names of parameters and their references so the
        /// method body can be copied directly into the output.
        /// </summary>
        public static void InlineMethod(
            IAlgorithm algorithm, 
            MethodDeclaration method, 
            string outputName,
            string[] inputNames,
            Expression x, 
            Expression y, 
            Expression z,
            Expression i, 
            Expression j, 
            Expression k,
            Expression width, 
            Expression height, 
            Expression depth,
            Expression ox, 
            Expression oy, 
            Expression oz)
        {
            if (algorithm == null) throw new ArgumentNullException("algorithm");
            if (method == null) throw new ArgumentNullException("method");
            if (outputName == null) throw new ArgumentNullException("outputName");
            if (inputNames == null) throw new ArgumentNullException("inputNames");
            if (x == null) throw new ArgumentNullException("x");
            if (y == null) throw new ArgumentNullException("y");
            if (z == null) throw new ArgumentNullException("z");
            if (i == null) throw new ArgumentNullException("i");
            if (j == null) throw new ArgumentNullException("j");
            if (k == null) throw new ArgumentNullException("k");
            if (width == null) throw new ArgumentNullException("width");
            if (height == null) throw new ArgumentNullException("height");
            if (depth == null) throw new ArgumentNullException("depth");
            if (ox == null) throw new ArgumentNullException("ox");
            if (oy == null) throw new ArgumentNullException("oy");
            if (oz == null) throw new ArgumentNullException("oz");

            var parameterContext = method.Parameters.ElementAt(0);
            var parameterInputs = new ParameterDeclaration[method.Parameters.Count - 14];
            for (var idx = 1; idx < method.Parameters.Count - 13; idx++)
                parameterInputs[idx - 1] = method.Parameters.ElementAt(idx);
            var parameterOutput = method.Parameters.Reverse().ElementAt(12);
            var parameterX = method.Parameters.Reverse().ElementAt(11);
            var parameterY = method.Parameters.Reverse().ElementAt(10);
            var parameterZ = method.Parameters.Reverse().ElementAt(9);
            var parameterI = method.Parameters.Reverse().ElementAt(8);
            var parameterJ = method.Parameters.Reverse().ElementAt(7);
            var parameterK = method.Parameters.Reverse().ElementAt(6);
            var parameterWidth = method.Parameters.Reverse().ElementAt(5);
            var parameterHeight = method.Parameters.Reverse().ElementAt(4);
            var parameterDepth = method.Parameters.Reverse().ElementAt(3);
            var parameterOX = method.Parameters.Reverse().ElementAt(2);
            var parameterOY = method.Parameters.Reverse().ElementAt(1);
            var parameterOZ = method.Parameters.Reverse().ElementAt(0);

            // Replace properties.
            method.AcceptVisitor(new FindPropertiesVisitor
            {
                Algorithm = algorithm,
                ParameterContextName = parameterContext.Name
            });

            // Replace identifiers.
            var identifiers =
                method
                    .Body
                    .Descendants
                    .Where(v => v is IdentifierExpression)
                    .Cast<IdentifierExpression>()
                    .ToArray();
            foreach (var e in identifiers)
            {
                if (e.Identifier == parameterX.Name)
                    e.ReplaceWith(x.Clone());
                else if (e.Identifier == parameterY.Name)
                    e.ReplaceWith(y.Clone());
                else if (e.Identifier == parameterZ.Name)
                    e.ReplaceWith(z.Clone());
                else if (e.Identifier == parameterI.Name)
                    e.ReplaceWith(i.Clone());
                else if (e.Identifier == parameterJ.Name)
                    e.ReplaceWith(j.Clone());
                else if (e.Identifier == parameterK.Name)
                    e.ReplaceWith(k.Clone());
                else if (e.Identifier == parameterWidth.Name)
                    e.ReplaceWith(width.Clone());
                else if (e.Identifier == parameterHeight.Name)
                    e.ReplaceWith(height.Clone());
                else if (e.Identifier == parameterDepth.Name)
                    e.ReplaceWith(depth.Clone());
                else if (e.Identifier == parameterOX.Name)
                    e.ReplaceWith(ox.Clone());
                else if (e.Identifier == parameterOY.Name)
                    e.ReplaceWith(oy.Clone());
                else if (e.Identifier == parameterOZ.Name)
                    e.ReplaceWith(oz.Clone());
                else if (e.Identifier == parameterOutput.Name)
                    e.Identifier = outputName;
                else if (parameterInputs.Count(v => v.Name == e.Identifier) > 0)
                    e.Identifier = inputNames.ElementAt(Array.FindIndex(parameterInputs, v => v.Name == e.Identifier));
                else if (e.Identifier == "context")
                    e.ReplaceWith(new ThisReferenceExpression());
            }
        }
コード例 #53
0
ファイル: Emitter.Helpers.cs プロジェクト: Cestbienmoi/Bridge
        public virtual string GetEntityName(ParameterDeclaration entity, bool forcePreserveMemberCase = false)
        {
            var name = entity.Name;

            if (entity.Parent != null && entity.GetParent<SyntaxTree>() != null)
            {
                var rr = this.Resolver.ResolveNode(entity, this) as LocalResolveResult;
                if (rr != null)
                {
                    var iparam = rr.Variable as IParameter;

                    if (iparam != null && iparam.Attributes != null)
                    {
                        var attr = iparam.Attributes.FirstOrDefault(a => a.AttributeType.FullName == Bridge.Translator.Translator.Bridge_ASSEMBLY + ".NameAttribute");

                        if (attr != null)
                        {
                            var value = attr.PositionalArguments.First().ConstantValue;
                            if (value is string)
                            {
                                name = value.ToString();
                            }
                        }
                    }
                }
            }

            if (Helpers.IsReservedWord(name))
            {
                name = Helpers.ChangeReservedWord(name);
            }

            return name;
        }
コード例 #54
0
 public ParameterDeclaration ConvertParameter(IParameter parameter)
 {
     if (parameter == null)
         throw new ArgumentNullException("parameter");
     ParameterDeclaration decl = new ParameterDeclaration();
     if (parameter.IsRef) {
         decl.ParameterModifier = ParameterModifier.Ref;
     } else if (parameter.IsOut) {
         decl.ParameterModifier = ParameterModifier.Out;
     } else if (parameter.IsParams) {
         decl.ParameterModifier = ParameterModifier.Params;
     }
     decl.Type = ConvertType(parameter.Type);
     if (this.ShowParameterNames) {
         decl.Name = parameter.Name;
     }
     if (parameter.IsOptional && this.ShowConstantValues) {
         decl.DefaultExpression = ConvertConstantValue(parameter.Type, parameter.ConstantValue);
     }
     return decl;
 }
コード例 #55
0
 private static bool IsStringParameter(ParameterDeclaration parameter)
 {
     ITypeSignature type = parameter.ParameterType;
     PointerTypeSignature pointerType = type as PointerTypeSignature;
     if (pointerType != null && pointerType.IsManaged)
     type = pointerType.ElementType;
     return IntrinsicTypeSignature.Is( type, IntrinsicType.String );
 }
コード例 #56
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration (parameterDeclaration);

                if (!(parameterDeclaration.Parent is MethodDeclaration || parameterDeclaration.Parent is ConstructorDeclaration))
                    return;

                var resolveResult = ctx.Resolve (parameterDeclaration) as LocalResolveResult;
                if (resolveResult == null)
                    return;

                if (ctx.FindReferences (parameterDeclaration.Parent, resolveResult.Variable).Any(r => r.Node != parameterDeclaration))
                    return;

                AddIssue (parameterDeclaration.NameToken, ctx.TranslateString ("Parameter is never used"));
            }
コード例 #57
0
ファイル: CSharpGrammar.cs プロジェクト: JerreS/AbstractCode
        // IMPORTANT NOTE:
        // The grammar consists of a few LALR(1) conflicts. These issues are, however, correctly handled, due to the fact that the grammar 
        // is defined in a specific order making the already added parser actions have precedence over the other.
        //
        // Known conflicts that are correctly handled:
        //
        // - ELSE:          Shift/Reduce conflict Dangling ELSE problem.  Lots of articles are around on the internet. 
        //                  The shift action is taken here.
        //
        // - CLOSE_PARENS:  Shift/Reduce conflict. This is due to the fact that the explicit cast expression is like the parenthesized 
        //                  expression. The shift action is taken here.
        //
        // - STAR:          Reduce/Reduce conflict, between VariableType -> TypeNameExpression and PrimaryExpression -> TypeNameExpression, 
        //                  due to the fact variable types can have '*', and look therefore like a binary operator expression. 
        //                  The first reduce action is taken here.

        public CSharpGrammar()
        {
            // Please let me know if there is a better way of tidying this :s

            TokenMapping.Add((int)ERROR, Error);

            #region Definitions to use later

            var statementList = new GrammarDefinition("StatementList");
            var statementListOptional = new GrammarDefinition("StatementListOptional",
                rule: null
                      | statementList);

            var blockStatement = new GrammarDefinition("BlockStatement");

            var variableDeclarator = new GrammarDefinition("VariableDeclarator");
            var variableDeclaratorList = new GrammarDefinition("VariableDeclaratorList");
            variableDeclaratorList.Rule = variableDeclarator
                                          | variableDeclaratorList
                                          + ToElement(COMMA)
                                          + variableDeclarator;
            var variableDeclaration = new GrammarDefinition("VariableDeclaration");
            var variableInitializer = new GrammarDefinition("VariableInitializer");
            var arrayInitializer = new GrammarDefinition("ArrayInitializer");
            var arrayInitializerOptional = new GrammarDefinition("ArrayInitializerOptional",
                rule: null | arrayInitializer);
            var identifierInsideBody = new GrammarDefinition("IdentifierInsideBody",
                rule: ToElement(IDENTIFIER),
                createNode: node => ToIdentifier(node.Children[0].Result));
            var identifierInsideBodyOptional = new GrammarDefinition("IdentifierInsideBodyOptional",
                rule: null | identifierInsideBody);

            variableDeclarator.Rule = identifierInsideBody
                                      | identifierInsideBody
                                      + ToElement(EQUALS)
                                      + variableInitializer;
            variableDeclarator.ComputeResult = node =>
            {
                var result = new VariableDeclarator((Identifier) node.Children[0].Result);
                if (node.Children.Count > 1)
                {
                    result.OperatorToken = (AstToken) node.Children[1].Result;
                    result.Value = (Expression) node.Children[2].Result;
                }
                return result;
            };

            var typeReference = new GrammarDefinition("TypeReference");

            var identifierExpression = new GrammarDefinition("IdentifierExpression",
                rule: identifierInsideBody,
                createNode: node => new IdentifierExpression((Identifier) node.Children[0].Result));

            var usingDirectiveListOptional = new GrammarDefinition("UsingDirectiveListOptional");

            #endregion

            #region Type References

            var namespaceOrTypeExpression = new GrammarDefinition("NamespaceOrTypeExpression");

            namespaceOrTypeExpression.Rule = identifierExpression |
                                             namespaceOrTypeExpression
                                             + ToElement(DOT)
                                             + ToElement(IDENTIFIER);

            namespaceOrTypeExpression.ComputeResult = node =>
            {
                if (node.Children.Count == 1)
                    return ToTypeReference((IConvertibleToType) node.Children[0].Result);
                var result = new MemberTypeReference();
                result.Target = (TypeReference) node.Children[0].Result;
                result.AddChild(AstNodeTitles.Accessor, node.Children[1].Result);
                result.Identifier = ToIdentifier(node.Children[2].Result);
                return result;
            };

            ComputeResultDelegate createPrimitiveTypeExpression = node =>
            {
                if (node.Children[0].Result is PrimitiveTypeReference)
                    return node.Children[0].Result;
                return new PrimitiveTypeReference
                {
                    Identifier = ToIdentifier(node.Children[0].Result),
                    PrimitiveType = CSharpLanguage.PrimitiveTypeFromString(((AstToken) node.Children[0].Result).Value)
                };
            };

            var integralType = new GrammarDefinition("IntegralType",
                rule: ToElement(SBYTE)
                      | ToElement(BYTE)
                      | ToElement(SHORT)
                      | ToElement(USHORT)
                      | ToElement(INT)
                      | ToElement(UINT)
                      | ToElement(LONG)
                      | ToElement(ULONG)
                      | ToElement(CHAR),
                createNode: createPrimitiveTypeExpression);

            var primitiveType = new GrammarDefinition("PrimitiveTypeExpression",
                rule: ToElement(OBJECT)
                      | ToElement(STRING)
                      | ToElement(BOOL)
                      | ToElement(DECIMAL)
                      | ToElement(FLOAT)
                      | ToElement(DOUBLE)
                      | ToElement(VOID)
                      | integralType,
                createNode: createPrimitiveTypeExpression);

            var dimensionSeparators = new GrammarDefinition("DimensionSeparators");
            dimensionSeparators.Rule = ToElement(COMMA)
                                       | dimensionSeparators + ToElement(COMMA);

            var rankSpecifier = new GrammarDefinition("RankSpecifier",
                rule: ToElement(OPEN_BRACKET) + ToElement(CLOSE_BRACKET)
                      | ToElement(OPEN_BRACKET) + dimensionSeparators
                      + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new ArrayTypeRankSpecifier();
                    result.LeftBracket = (AstToken) node.Children[0].Result;
                    if (node.Children.Count == 3)
                    {
                        foreach (var dimensionSeparator in node.Children[1].GetAllNodesFromListDefinition()
                            .Select(x => x.Result))
                        {
                            result.Dimensions++;
                            result.AddChild(AstNodeTitles.ElementSeparator, dimensionSeparator);
                        }
                    }
                    result.RightBracket = (AstToken) node.Children[node.Children.Count - 1].Result;
                    return result;
                });

            var arrayType = new GrammarDefinition("ArrayType",
                rule: typeReference
                      + rankSpecifier,
                createNode: node => new ArrayTypeReference()
                {
                    BaseType = (TypeReference) node.Children[0].Result,
                    RankSpecifier = (ArrayTypeRankSpecifier) node.Children[1].Result
                });

            var pointerType = new GrammarDefinition("PointerType",
                rule: typeReference
                      + ToElement(STAR),
                createNode: node => new PointerTypeReference()
                {
                    BaseType = (TypeReference) node.Children[0].Result,
                    PointerToken = (AstToken) node.Children[1].Result
                });

            var typeExpression = new GrammarDefinition("TypeExpression",
                rule: namespaceOrTypeExpression
                      | primitiveType);

            typeReference.Rule = typeExpression
                                 | arrayType
                                 | pointerType
                ;

            #endregion

            #region Expressions

            ComputeResultDelegate createBinaryOperatorExpression = node =>
            {
                if (node.Children.Count == 1)
                    return node.Children[0].Result;

                var result = new BinaryOperatorExpression();
                result.Left = (Expression) node.Children[0].Result;
                var operatorToken = (AstToken) (node.Children[1].Result ?? node.Children[1].Children[0].Result);
                result.Operator = CSharpLanguage.BinaryOperatorFromString(operatorToken.Value);
                result.OperatorToken = (AstToken) operatorToken;
                result.Right = (Expression) node.Children[2].Result;
                return result;
            };

            var expression = new GrammarDefinition("Expression");
            var expressionOptional = new GrammarDefinition("ExpressionOptional",
                rule: null
                      | expression);

            var primaryExpression = new GrammarDefinition("PrimaryExpression");

            var primitiveExpression = new GrammarDefinition("PrimitiveExpression",
                rule: ToElement(LITERAL)
                      | ToElement(TRUE)
                      | ToElement(FALSE)
                      | ToElement(NULL),
                createNode: node =>
                {
                    object interpretedValue;
                    node.Children[0].Result.UserData.TryGetValue("InterpretedValue", out interpretedValue);
                    var result = new PrimitiveExpression(interpretedValue, ((AstToken) node.Children[0].Result).Value, node.Children[0].Range);
                    return result;
                });

            var parenthesizedExpression = new GrammarDefinition("ParenthesizedExpression",
                rule: ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      | ToElement(OPEN_PARENS)
                      + Error
                      + ToElement(CLOSE_PARENS),
                createNode: node => new ParenthesizedExpression
                {
                    LeftParenthese = (AstToken) node.Children[0].Result,
                    Expression = (Expression) node.Children[1].Result,
                    RightParenthese = (AstToken) node.Children[2].Result,
                });

            var memberAccessorOperator = new GrammarDefinition("MemberAccessorOperator",
                rule: ToElement(DOT)
                      | ToElement(OP_PTR)
                      | ToElement(INTERR_OPERATOR));

            var memberReferenceExpression = new GrammarDefinition("MemberReferenceExpression",
                rule: primaryExpression + memberAccessorOperator + identifierInsideBody
                | primaryExpression + memberAccessorOperator + Error,
                createNode: node => new MemberReferenceExpression
                {
                    Target =
                        (Expression)
                            ((IConvertibleToExpression) node.Children[0].Result).ToExpression().Remove(),
                    Accessor = CSharpLanguage.AccessorFromString(((AstToken) node.Children[1].Children[0].Result).Value),
                    AccessorToken = (AstToken) node.Children[1].Children[0].Result,
                    Identifier = (Identifier) node.Children[2].Result
                });

            var argument = new GrammarDefinition("Argument",
                rule: expression
                      | ToElement(REF) + expression
                      | ToElement(OUT) + expression,
                createNode: node =>
                {
                    if (node.Children.Count > 1)
                    {
                        return new DirectionExpression()
                        {
                            DirectionToken = (AstToken) node.Children[0].Result,
                            Direction = CSharpLanguage.DirectionFromString(((AstToken) node.Children[0].Result).Value),
                            Expression = (Expression) node.Children[1].Result
                        };
                    }
                    return node.Children[0].Result;
                });

            var argumentList = new GrammarDefinition("ArgumentList");
            argumentList.Rule = argument
                                | argumentList + ToElement(COMMA) + argument;
            var argumentListOptional = new GrammarDefinition("ArgumentListOptional",
                rule: null | argumentList);

            var invocationExpression = new GrammarDefinition("InvocationExpression",
                rule: primaryExpression
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new InvocationExpression()
                    {
                        Target = (Expression) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                    };

                    if (node.Children[2].HasChildren)
                    {
                        foreach (var subNode in node.Children[2].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Arguments.Add((Expression) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    return result;
                });

            var indexerExpression = new GrammarDefinition("IndexerExpression",
                rule: primaryExpression
                      + ToElement(OPEN_BRACKET_EXPR)
                      + argumentList
                      + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new IndexerExpression()
                    {
                        Target = (Expression) node.Children[0].Result,
                        LeftBracket = (AstToken) node.Children[1].Result,
                    };

                    foreach (var subNode in node.Children[2].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Indices.Add((Expression) subNode);
                    }

                    result.RightBracket = (AstToken) node.Children[3].Result;
                    return result;
                });

            var createObjectExpression = new GrammarDefinition("CreateObjectExpression",
                rule: ToElement(NEW)
                      + typeReference
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS)
                      + arrayInitializerOptional
                      | ToElement(NEW)
                      + namespaceOrTypeExpression
                      + arrayInitializer,
                createNode: node =>
                {
                    var result = new CreateObjectExpression();
                    result.NewKeyword = (AstToken) node.Children[0].Result;
                    result.Type = (TypeReference) node.Children[1].Result;

                    if (node.Children.Count == 6)
                    {
                        result.LeftParenthese = (AstToken) node.Children[2].Result;

                        if (node.Children[3].HasChildren)
                        {
                            foreach (var subNode in node.Children[3].Children[0].GetAllListAstNodes())
                            {
                                if (subNode is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                                else
                                    result.Arguments.Add((Expression) subNode);
                            }
                        }

                        result.RightParenthese = (AstToken) node.Children[4].Result;
                    }

                    var initializerNode = node.Children[node.Children.Count - 1];
                    if (initializerNode.HasChildren)
                        result.Initializer = (ArrayInitializer) initializerNode.Result;
                    return result;
                });

            var createArrayExpression = new GrammarDefinition("CreateArrayExpression",
                rule: ToElement(NEW)
                      + rankSpecifier
                      + arrayInitializer
                      | ToElement(NEW)
                      + typeReference
                      + rankSpecifier
                      + arrayInitializer
                      | ToElement(NEW)
                      + typeReference
                      + ToElement(OPEN_BRACKET_EXPR)
                      + argumentList
                      + ToElement(CLOSE_BRACKET)
                      + arrayInitializerOptional
                ,
                createNode: node =>
                {
                    var result = new CreateArrayExpression();
                    result.NewKeyword = (AstToken) node.Children[0].Result;

                    switch (node.Children.Count)
                    {
                        case 3:
                            {
                                var rankSpecifierNode = (ArrayTypeRankSpecifier) node.Children[1].Result;
                                result.LeftBracket = (AstToken) rankSpecifierNode.LeftBracket.Remove();
                                result.RightBracket = (AstToken) rankSpecifierNode.RightBracket.Remove();
                                break;
                            }
                        case 4:
                            {
                                result.Type = (TypeReference) node.Children[1].Result;
                                var rankSpecifierNode = (ArrayTypeRankSpecifier) node.Children[2].Result;
                                result.LeftBracket = (AstToken) rankSpecifierNode.LeftBracket.Remove();
                                result.RightBracket = (AstToken) rankSpecifierNode.RightBracket.Remove();
                                break;
                            }
                        case 6:
                            {
                                result.Type = (TypeReference) node.Children[1].Result;
                                result.LeftBracket = (AstToken) node.Children[2].Result;
                                if (node.Children[3].HasChildren)
                                {
                                    foreach (var subNode in node.Children[3].Children[0].GetAllListAstNodes())
                                    {
                                        if (subNode is AstToken)
                                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                                        else
                                            result.Arguments.Add((Expression) subNode);
                                    }
                                }
                                result.RightBracket = (AstToken) node.Children[4].Result;
                                break;
                            }
                    }
                    var initializerNode = node.Children[node.Children.Count - 1];
                    if (initializerNode.HasChildren)
                        result.Initializer = (ArrayInitializer) initializerNode.Result;
                    return result;
                });

            var primitiveTypeExpression = new GrammarDefinition("PrimitiveTypeExpression",
                rule: primitiveType,
                createNode: node => ((IConvertibleToExpression) node.Children[0].Result).ToExpression());

            var typeNameExpression = new GrammarDefinition("TypeNameExpression",
                rule: identifierExpression
                      | memberReferenceExpression
                      | primitiveTypeExpression);

            var thisExpression = new GrammarDefinition("ThisExpression",
                rule: ToElement(THIS),
                createNode: node => new ThisReferenceExpression()
                {
                    ThisKeywordToken = (AstToken) node.Children[0].Result,
                });

            var baseExpression = new GrammarDefinition("BaseExpression",
                rule: ToElement(BASE),
                createNode: node => new BaseReferenceExpression()
                {
                    BaseKeywordToken = (AstToken) node.Children[0].Result,
                });

            var typeofExpression = new GrammarDefinition("TypeOfExpression",
                rule: ToElement(TYPEOF) + ToElement(OPEN_PARENS) + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new GetTypeExpression()
                {
                    GetTypeKeywordToken = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var defaultExpression = new GrammarDefinition("DefaultExpression",
                rule: ToElement(DEFAULT)
                      + ToElement(OPEN_PARENS)
                      + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new DefaultExpression()
                {
                    KeywordToken = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var sizeofExpression = new GrammarDefinition("SizeOfExpression",
                rule: ToElement(SIZEOF) + ToElement(OPEN_PARENS) + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new SizeOfExpression()
                {
                    SizeofKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var checkedExpression = new GrammarDefinition("CheckedExpression",
                rule:
                    ToElement(CHECKED) + ToElement(OPEN_PARENS) + expression +
                    ToElement(CLOSE_PARENS),
                createNode: node => new CheckedExpression()
                {
                    CheckedKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetExpression = (Expression) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var uncheckedExpression = new GrammarDefinition("UncheckedExpression",
                rule:
                    ToElement(UNCHECKED) + ToElement(OPEN_PARENS) + expression +
                    ToElement(CLOSE_PARENS),
                createNode: node => new UncheckedExpression()
                {
                    UncheckedKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetExpression = (Expression) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var stackAllocExpression = new GrammarDefinition("StackAllocExpression",
                rule:
                    ToElement(STACKALLOC)
                    + typeReference
                    + ToElement(OPEN_BRACKET_EXPR)
                    + expression
                    + ToElement(CLOSE_BRACKET),
                createNode: node => new StackAllocExpression()
                {
                    StackAllocKeyword = (AstToken) node.Children[0].Result,
                    Type = (TypeReference) node.Children[1].Result,
                    LeftBracket = (AstToken) node.Children[2].Result,
                    Counter = (Expression) node.Children[3].Result,
                    RightBracket = (AstToken) node.Children[4].Result,
                });

            var explicitAnonymousMethodParameter = new GrammarDefinition("ExplicitAnonymousMethodParameter",
                rule: typeReference + ToElement(IDENTIFIER),
                createNode: node => new ParameterDeclaration
                {
                    ParameterType = (TypeReference)node.Children[0].Result,
                    Declarator = new VariableDeclarator(ToIdentifier(node.Children[1].Result))
                });

            var explicitAnonymousMethodParameterList = new GrammarDefinition("ExplicitAnonymousMethodParameterList");
            explicitAnonymousMethodParameterList.Rule = explicitAnonymousMethodParameter
                                                        | explicitAnonymousMethodParameterList
                                                        + ToElement(COMMA)
                                                        + explicitAnonymousMethodParameter;

            var explicitAnonymousMethodParameterListOptional = new GrammarDefinition("ExplicitAnonymousMethodParameterListOptional",
                rule: null | explicitAnonymousMethodParameterList);

            var explicitAnonymousMethodSignature = new GrammarDefinition("ExplicitAnonymousMethodSignature",
                rule: ToElement(OPEN_PARENS) + explicitAnonymousMethodParameterListOptional + ToElement(CLOSE_PARENS));

            var explicitAnonymousMethodSignatureOptional =
                new GrammarDefinition("ExplicitAnonymousMethodSignatureOptional",
                    rule: null | explicitAnonymousMethodSignature);

            var anonymousMethodExpression = new GrammarDefinition("AnonymousMethodExpression",
                rule: ToElement(DELEGATE) + explicitAnonymousMethodSignatureOptional + blockStatement,
                createNode: node =>
                {
                    var result = new AnonymousMethodExpression();
                    result.DelegateKeyword = (AstToken) node.Children[0].Result;

                    if (node.Children[1].HasChildren)
                    {
                        var signature = node.Children[1].Children[0];
                        result.LeftParenthese = (AstToken) signature.Children[0].Result;

                        if (signature.Children[1].HasChildren)
                        {
                            foreach (var child in signature.Children[1].Children[0].GetAllListAstNodes())
                            {
                                if (child is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, child);
                                else
                                    result.Parameters.Add((ParameterDeclaration) child);
                            }
                        }

                        result.RightParenthese = (AstToken)signature.Children[2].Result;
                    }

                    result.Body = (BlockStatement) node.Children[2].Result;
                    return result;
                });


            var implicitAnonymousMethodParameter = new GrammarDefinition("ImplicitAnonymousMethodParameter",
                rule: ToElement(IDENTIFIER),
                createNode: node => new ParameterDeclaration
                {
                    Declarator = new VariableDeclarator(ToIdentifier(node.Children[0].Result))
                });

            var implicitAnonymousMethodParameterList = new GrammarDefinition("ImplicitAnonymousMethodParameterList");
            implicitAnonymousMethodParameterList.Rule = implicitAnonymousMethodParameter
                                                        | implicitAnonymousMethodParameterList
                                                        + ToElement(COMMA)
                                                        + implicitAnonymousMethodParameter;

            var implicitAnonymousMethodParameterListOptional = new GrammarDefinition("ImplicitAnonymousMethodParameterListOptional",
                rule: null | implicitAnonymousMethodParameterList);

            var implicitAnonymousMethodSignature = new GrammarDefinition("implicitAnonymousMethodSignature",
                rule: implicitAnonymousMethodParameter | ToElement(OPEN_PARENS_LAMBDA) + implicitAnonymousMethodParameterList + ToElement(CLOSE_PARENS));

            var anonymousMethodSignature = new GrammarDefinition("AnonymousMethodSignature",
                rule: implicitAnonymousMethodSignature);

            var anonymousFunctionBody = new GrammarDefinition("AnonymousFunctionBody",
                rule: expression | blockStatement);

            var lambdaExpression = new GrammarDefinition("LambdaExpression",
                rule: anonymousMethodSignature + ToElement(ARROW) + anonymousFunctionBody,
                createNode: node =>
                {
                    var result = new LambdaExpression();
                    result.Arrow = (AstToken)node.Children[1].Result;
                    result.Body = node.Children[2].Result;
                    return result;

                });

            primaryExpression.Rule =
                typeNameExpression
                | primitiveExpression
                | parenthesizedExpression
                | invocationExpression
                | indexerExpression
                | thisExpression
                | baseExpression
                | createObjectExpression
                | createArrayExpression
                | typeofExpression
                | defaultExpression
                | sizeofExpression
                | checkedExpression
                | uncheckedExpression
                | stackAllocExpression
                | anonymousMethodExpression
                ;

            var preFixUnaryOperator = new GrammarDefinition("PreFixUnaryOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS)
                      | ToElement(STAR)
                      | ToElement(BANG)
                      | ToElement(OP_INC)
                      | ToElement(OP_DEC)
                      | ToElement(BITWISE_AND)
                      | ToElement(TILDE)
                      | ToElement(AWAIT));
            var postFixUnaryOperator = new GrammarDefinition("PostFixUnaryOperator",
                rule: ToElement(OP_INC)
                      | ToElement(OP_DEC));


            var castExpression = new GrammarDefinition("CastExpression");

            var unaryOperatorExpression = new GrammarDefinition("UnaryOperatorExpression",
                rule: primaryExpression
                      | castExpression
                      | (preFixUnaryOperator + primaryExpression)
                      | (primaryExpression + postFixUnaryOperator),
                createNode: node =>
                {
                    if (node.Children.Count == 1)
                        return node.Children[0].Result;

                    var result = new UnaryOperatorExpression();
                    var isPrefix = node.Children[0].GrammarElement == preFixUnaryOperator;
                    if (isPrefix)
                    {
                        var operatorToken = ((AstToken) node.Children[0].Children[0].Result);
                        result.Operator = CSharpLanguage.UnaryOperatorFromString(operatorToken.Value);
                        result.OperatorToken = operatorToken;
                    }

                    result.Expression = (Expression) node.Children[isPrefix ? 1 : 0].Result;
                    if (!isPrefix)
                    {
                        var operatorToken = (AstToken) node.Children[1].Children[0].Result;
                        result.Operator = CSharpLanguage.UnaryOperatorFromString(operatorToken.Value, false);
                        result.OperatorToken = operatorToken;
                    }
                    return result;
                });

            castExpression.Rule = ToElement(OPEN_PARENS)
                                  + typeNameExpression
                                  + ToElement(CLOSE_PARENS)
                                  + unaryOperatorExpression;
            castExpression.ComputeResult = node => new ExplicitCastExpression
            {
                LeftParenthese = (AstToken) node.Children[0].Result,
                TargetType = ToTypeReference((IConvertibleToType) node.Children[1].Result),
                RightParenthese = (AstToken) node.Children[2].Result,
                TargetExpression = (Expression) node.Children[3].Result
            };

            var multiplicativeOperator = new GrammarDefinition("MultiplicativeOperator",
                rule: ToElement(STAR)
                      | ToElement(DIV)
                      | ToElement(PERCENT));

            var multiplicativeExpression = new GrammarDefinition("MultiplicativeExpression");
            multiplicativeExpression.Rule = unaryOperatorExpression
                                            | multiplicativeExpression
                                            + multiplicativeOperator
                                            + unaryOperatorExpression;
            multiplicativeExpression.ComputeResult = createBinaryOperatorExpression;

            var additiveOperator = new GrammarDefinition("AdditiveOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS));
            var additiveExpression = new GrammarDefinition("AdditiveExpression");
            additiveExpression.Rule = multiplicativeExpression
                                      | additiveExpression
                                      + additiveOperator
                                      + multiplicativeExpression;
            additiveExpression.ComputeResult = createBinaryOperatorExpression;

            var shiftOperator = new GrammarDefinition("ShiftOperator",
                rule: ToElement(OP_SHIFT_LEFT)
                      | ToElement(OP_SHIFT_RIGHT));
            var shiftExpression = new GrammarDefinition("ShiftExpression");
            shiftExpression.Rule = additiveExpression
                                   | shiftExpression
                                   + shiftOperator
                                   + additiveExpression;
            shiftExpression.ComputeResult = createBinaryOperatorExpression;

            var relationalOperator = new GrammarDefinition("RelationalOperator",
                rule: ToElement(OP_GT)
                      | ToElement(OP_GE)
                      | ToElement(OP_LT)
                      | ToElement(OP_LE)
                      | ToElement(IS)
                      | ToElement(AS));
            var relationalExpression = new GrammarDefinition("RelationalExpression");
            relationalExpression.Rule = shiftExpression
                                        | relationalExpression
                                        + relationalOperator
                                        + shiftExpression;
            relationalExpression.ComputeResult = node =>
            {
                if (node.Children.Count == 1)
                    return node.Children[0].Result;
                var operatorToken = (CSharpAstToken) node.Children[1].Children[0].Result;
                switch (operatorToken.Code)
                {
                    case IS:
                        return new TypeCheckExpression()
                        {
                            TargetExpression = (Expression) node.Children[0].Result,
                            IsKeyword = operatorToken,
                            TargetType = ToTypeReference((IConvertibleToType) node.Children[2].Result)
                        };
                    case AS:
                        return new SafeCastExpression()
                        {
                            TargetExpression = (Expression) node.Children[0].Result,
                            CastKeyword = operatorToken,
                            TargetType = ToTypeReference((IConvertibleToType) node.Children[2].Result)
                        };
                    default:
                        return createBinaryOperatorExpression(node);
                }
            };

            var equalityOperator = new GrammarDefinition("equalityOperator",
                rule: ToElement(OP_EQUALS)
                      | ToElement(OP_NOTEQUALS));
            var equalityExpression = new GrammarDefinition("EqualityExpression");
            equalityExpression.Rule = relationalExpression
                                      | equalityExpression
                                      + equalityOperator
                                      + relationalExpression;
            equalityExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalAndExpression = new GrammarDefinition("LogicalAndExpression");
            logicalAndExpression.Rule = equalityExpression
                                      | logicalAndExpression
                                      + ToElement(BITWISE_AND)
                                      + equalityExpression;
            logicalAndExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalXorExpression = new GrammarDefinition("LogicalOrExpression");
            logicalXorExpression.Rule = logicalAndExpression
                                      | logicalXorExpression
                                      + ToElement(CARRET)
                                      + logicalAndExpression;
            logicalXorExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalOrExpression = new GrammarDefinition("LogicalOrExpression");
            logicalOrExpression.Rule = logicalXorExpression
                                      | logicalOrExpression
                                      + ToElement(BITWISE_OR)
                                      + logicalXorExpression;
            logicalOrExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalAndExpression = new GrammarDefinition("ConditionalAndExpression");
            conditionalAndExpression.Rule = logicalOrExpression
                                      | conditionalAndExpression
                                      + ToElement(OP_AND)
                                      + logicalOrExpression;
            conditionalAndExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalOrExpression = new GrammarDefinition("ConditionalOrExpression");
            conditionalOrExpression.Rule = conditionalAndExpression
                                      | conditionalOrExpression
                                      + ToElement(OP_OR)
                                      + conditionalAndExpression;
            conditionalOrExpression.ComputeResult = createBinaryOperatorExpression;

            var nullCoalescingExpression = new GrammarDefinition("NullCoalescingExpression");
            nullCoalescingExpression.Rule = conditionalOrExpression
                                      | nullCoalescingExpression
                                      + ToElement(OP_COALESCING)
                                      + conditionalOrExpression;
            nullCoalescingExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalExpression = new GrammarDefinition("ConditionalExpression",
                rule: nullCoalescingExpression
                      | nullCoalescingExpression
                      + ToElement(INTERR)
                      + expression + ToElement(COLON) + expression,
                createNode: node => node.Children.Count == 1
                    ? node.Children[0].Result
                    : new ConditionalExpression
                    {
                        Condition = (Expression) node.Children[0].Result,
                        OperatorToken = (AstToken) node.Children[1].Result,
                        TrueExpression = (Expression) node.Children[2].Result,
                        ColonToken = (AstToken) node.Children[3].Result,
                        FalseExpression = (Expression) node.Children[4].Result
                    });

            var assignmentOperator = new GrammarDefinition("AssignmentOperator",
                rule: ToElement(EQUALS)
                      | ToElement(OP_ADD_ASSIGN)
                      | ToElement(OP_SUB_ASSIGN)
                      | ToElement(OP_MULT_ASSIGN)
                      | ToElement(OP_DIV_ASSIGN)
                      | ToElement(OP_AND_ASSIGN)
                      | ToElement(OP_OR_ASSIGN)
                      | ToElement(OP_XOR_ASSIGN)
                      | ToElement(OP_SHIFT_LEFT_ASSIGN)
                      | ToElement(OP_SHIFT_RIGHT_ASSIGN));
            var assignmentExpression = new GrammarDefinition("AssignmentExpression",
                rule: unaryOperatorExpression
                      + assignmentOperator
                      + expression,
                createNode: node => new AssignmentExpression
                {
                    Target = (Expression) node.Children[0].Result,
                    Operator = CSharpLanguage.AssignmentOperatorFromString(((AstToken) node.Children[1].Children[0].Result).Value),
                    OperatorToken = (AstToken) node.Children[1].Children[0].Result,
                    Value = (Expression) node.Children[2].Result,
                });

            var fromClause = new GrammarDefinition("FromClause",
                rule: ToElement(FROM) + identifierInsideBody + ToElement(IN) + expression,
                createNode: node => new LinqFromClause
                {
                    FromKeyword = (AstToken) node.Children[0].Result,
                    VariableName = (Identifier) node.Children[1].Result,
                    InKeyword = (AstToken) node.Children[2].Result,
                    DataSource = (Expression) node.Children[3].Result
                });

            var letClause = new GrammarDefinition("LetClause",
                rule: ToElement(LET) + variableDeclarator,
                createNode: node => new LinqLetClause()
                {
                    LetKeyword = (AstToken) node.Children[0].Result,
                    Variable = (VariableDeclarator) node.Children[1].Result
                });

            var whereClause = new GrammarDefinition("WhereClause",
                rule: ToElement(WHERE) + expression,
                createNode: node => new LinqWhereClause()
                {
                    WhereKeyword = (AstToken) node.Children[0].Result,
                    Condition = (Expression) node.Children[1].Result
                });

            var orderingDirection = new GrammarDefinition("OrderingDirection",
                rule: null | ToElement(ASCENDING) | ToElement(DESCENDING));

            var ordering = new GrammarDefinition("Ordering",
                rule: expression + orderingDirection,
                createNode: node =>
                {
                    var result = new LinqOrdering();
                    result.Expression = (Expression) node.Children[0].Result;

                    if (node.Children[1].HasChildren)
                    {
                        var directionNode = node.Children[1].Children[0];
                        result.DirectionKeyword = (AstToken) directionNode.Result;
                        result.Direction = directionNode.Result != null
                            ? CSharpLanguage.OrderningDirectionFromString(result.DirectionKeyword.Value)
                            : LinqOrderingDirection.None;
                    }

                    return result;
                });

            var orderings = new GrammarDefinition("Orderings");
            orderings.Rule = ordering | orderings + ToElement(COMMA) + ordering;

            var orderByClause = new GrammarDefinition("OrderByClause",
                rule: ToElement(ORDERBY) + orderings,
                createNode: node =>
                {
                    var result = new LinqOrderByClause();
                    result.OrderByKeyword = (AstToken) node.Children[0].Result;
                    foreach (var subNode in node.Children[1].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Ordernings.Add((LinqOrdering) subNode);
                    }
                    return result;
                });

            var groupByClause = new GrammarDefinition("GroupByClause",
                rule: ToElement(GROUP) + expression + ToElement(BY) + expression,
                createNode: node => new LinqGroupByClause()
                {
                    GroupKeyword = (AstToken) node.Children[0].Result,
                    Expression = (Expression) node.Children[1].Result,
                    ByKeyword = (AstToken) node.Children[2].Result,
                    KeyExpression = (Expression) node.Children[3].Result
                });

            var selectClause = new GrammarDefinition("SelectClause",
                rule: ToElement(SELECT) + expression,
                createNode: node => new LinqSelectClause()
                {
                    SelectKeyword = (AstToken) node.Children[0].Result,
                    Target = (Expression) node.Children[1].Result
                });

            var queryBodyClause = new GrammarDefinition("QueryBodyClause",
                rule:
                fromClause
                | letClause
                | groupByClause
                | whereClause
                | orderByClause
                 );

            var queryBodyClauses = new GrammarDefinition("QueryBodyClauses");
            queryBodyClauses.Rule = queryBodyClause | queryBodyClauses + queryBodyClause;

            var queryBodyClausesOptional = new GrammarDefinition("QueryBodyClausesOptional",
                rule: null | queryBodyClauses);

            var linqExpression = new GrammarDefinition("LinqExpression",
                rule: fromClause + queryBodyClausesOptional + selectClause,
                createNode: node =>
                {
                    var result = new LinqExpression();
                    result.Clauses.Add((LinqClause) node.Children[0].Result);

                    if (node.Children[1].HasChildren)
                    {
                        result.Clauses.AddRange(node.Children[1].Children[0].GetAllListAstNodes().Cast<LinqClause>());
                    }

                    result.Clauses.Add((LinqClause) node.Children[2].Result);
                    return result;
                });

            expression.Rule = conditionalExpression
                              | linqExpression
                              | lambdaExpression
                              | assignmentExpression;

            #endregion

            #region Statements
            var statement = new GrammarDefinition("Statement");
            var embeddedStatement = new GrammarDefinition("EmbeddedStatement");

            var emptyStatement = new GrammarDefinition("EmptyStatement",
                rule: ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new EmptyStatement();
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[0].Result);
                    return result;
                });

            var labelStatement = new GrammarDefinition("LabelStatement",
                rule: identifierInsideBody + ToElement(COLON),
                createNode: node => new LabelStatement((Identifier) node.Children[0].Result)
                {
                    Colon = (AstToken) node.Children[1].Result
                });

            var expressionStatement = new GrammarDefinition("ExpressionStatement",
                rule: expression + ToElement(SEMICOLON)
                      | Error + ToElement(SEMICOLON)
                      | Error + ToElement(CLOSE_BRACE)
                      | expression + ToElement(CLOSE_BRACE), // Common mistake in C# is to forget the semicolon at the end of a statement.
                createNode: node =>
                {
                    var result = new ExpressionStatement(node.Children[0].Result as Expression);

                    var endingToken = (AstToken) node.Children[1].Result;
                    if (endingToken.GetTokenCode() == (int) SEMICOLON)
                    {
                        result.AddChild(AstNodeTitles.Semicolon, node.Children[1].Result);
                    }
                    else
                    {
                        node.Context.SyntaxErrors.Add(new SyntaxError(
                            node.Children[1].Range.End, 
                            "';' expected.", 
                            MessageSeverity.Error));
                        
                        node.Context.Lexer.PutBack((AstToken) endingToken);
                    }

                    return result;
                });

            blockStatement.Rule = ToElement(OPEN_BRACE)
                                  + statementListOptional
                                  + ToElement(CLOSE_BRACE);
            blockStatement.ComputeResult = node =>
            {
                var result = new BlockStatement();
                result.StartScope = node.Children[0].Result;
                if (node.Children[1].HasChildren)
                {
                    result.Statements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<Statement>());
                }
                result.EndScope = node.Children[2].Result;
                return result;
            };

            var variableDeclarationStatement = new GrammarDefinition("VariableDeclarationStatement",
                rule: variableDeclaration
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = node.Children[0].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[1].Result);
                    return result;
                });

            var ifElseStatement = new GrammarDefinition("IfElseStatement",
                rule: ToElement(IF) + parenthesizedExpression + embeddedStatement
                | ToElement(IF) + parenthesizedExpression + embeddedStatement + ToElement(ELSE) + embeddedStatement
                ,
                createNode: node =>
                {
                    var result = new IfElseStatement();
                    result.IfKeyword = (AstToken) node.Children[0].Result;

                    var parenthesized = (ParenthesizedExpression) node.Children[1].Result;
                    result.LeftParenthese = (AstToken) parenthesized.LeftParenthese.Remove();
                    result.Condition = (Expression) parenthesized.Expression?.Remove();
                    result.RightParenthese = (AstToken) parenthesized.RightParenthese.Remove();

                    result.TrueBlock = (Statement) node.Children[2].Result;

                    if (node.Children.Count > 3)
                    {
                        result.ElseKeyword = (AstToken) node.Children[3].Result;
                        result.FalseBlock = (Statement) node.Children[4].Result;
                        CheckForPossibleMistakenEmptyStatement(node.Children[4]);
                    }
                    else
                    {
                        CheckForPossibleMistakenEmptyStatement(node.Children[2]);
                    }

                    return result;
                });

            var switchLabel = new GrammarDefinition("SwitchLabel",
                rule: ToElement(CASE) + expression + ToElement(COLON)
                      | ToElement(DEFAULT_COLON) + ToElement(COLON),
                createNode: node =>
                {
                    var result = new SwitchCaseLabel();
                    result.CaseKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children.Count > 2)
                        result.Condition = (Expression) node.Children[1].Result;
                    result.Colon = (AstToken) node.Children[node.Children.Count - 1].Result;
                    return result;
                });

            var switchLabels = new GrammarDefinition("SwitchLabels");
            switchLabels.Rule = switchLabel | switchLabels + switchLabel;

            var switchSection = new GrammarDefinition("SwitchSection",
                rule: switchLabels + statementList,
                createNode: node =>
                {
                    var result = new SwitchSection();
                    result.Labels.AddRange(node.Children[0].GetAllListAstNodes<SwitchCaseLabel>());

                    result.Statements.AddRange(node.Children[1].GetAllListAstNodes<Statement>());

                    return result;
                });

            var switchSections = new GrammarDefinition("SwitchSections");
            switchSections.Rule = switchSection
                                  | switchSections + switchSection;

            var switchBlock = new GrammarDefinition("SwitchBlock",
                rule: ToElement(OPEN_BRACE)
                      + switchSections
                      + ToElement(CLOSE_BRACE));

            var switchStatement = new GrammarDefinition("SwitchStatement",
                rule: ToElement(SWITCH)
                      + ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + switchBlock,
                createNode: node =>
                {
                    var result = new SwitchStatement();
                    result.SwitchKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    result.Condition = (Expression) node.Children[2].Result;
                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    var switchBlockNode = node.Children[4];
                    result.StartScope = switchBlockNode.Children[0].Result;
                    result.Sections.AddRange(switchBlockNode.Children[1].GetAllListAstNodes<SwitchSection>());
                    result.EndScope = switchBlockNode.Children[2].Result;
                    return result;
                });

            var selectionStatement = new GrammarDefinition("SelectionStatement",
                rule: ifElseStatement
                      | switchStatement);

            var whileLoopStatement = new GrammarDefinition("WhileLoopStatement",
                rule: ToElement(WHILE)
                      + parenthesizedExpression
                      + embeddedStatement,
                createNode: node =>
                {
                    var bodyNode = node.Children[2];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    var conditionExpr = (ParenthesizedExpression) node.Children[1].Result;
                    return new WhileLoopStatement
                    {
                        WhileKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) conditionExpr.LeftParenthese.Remove(),
                        Condition = (Expression) conditionExpr.Expression.Remove(),
                        RightParenthese = (AstToken) conditionExpr.RightParenthese.Remove(),
                        Body = (Statement) bodyNode.Result
                    };
                });

            var doLoopStatement = new GrammarDefinition("DoLoopStatement",
                rule: ToElement(DO)
                      + embeddedStatement
                      + ToElement(WHILE)
                      + parenthesizedExpression
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var conditionExpr = (ParenthesizedExpression) node.Children[3].Result;
                    return new DoLoopStatement
                    {
                        DoKeyword = (AstToken) node.Children[0].Result,
                        Body = (Statement) node.Children[1].Result,
                        WhileKeyword = (AstToken) node.Children[2].Result,
                        LeftParenthese = (AstToken) conditionExpr.LeftParenthese.Remove(),
                        Condition = (Expression) conditionExpr.Expression.Remove(),
                        RightParenthese = (AstToken) conditionExpr.RightParenthese.Remove(),
                        Semicolon = (AstToken) node.Children[4].Result
                    };
                });

            var forLoopInitializer = new GrammarDefinition("ForLoopInitializer",
                rule: variableDeclaration
                     | null
                     // TODO: statement-expression-list
                     );

            var forLoopCondition = new GrammarDefinition("ForLoopCondition",
                rule: expression
                | null);

            var forLoopStatement = new GrammarDefinition("ForLoopStatement",
                rule: ToElement(FOR)
                + ToElement(OPEN_PARENS)
                + forLoopInitializer
                + ToElement(SEMICOLON)
                + expressionOptional
                + ToElement(SEMICOLON)
                + expressionOptional // TODO: statement-expression-list
                + ToElement(CLOSE_PARENS)
                + embeddedStatement,
                createNode: node =>
                {
                    var result = new ForLoopStatement();
                    result.ForKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;

                    if (node.Children[2].HasChildren)
                    {
                        var declaration = node.Children[2].Children[0].Result as VariableDeclarationStatement;
                        if (declaration != null)
                        {
                            result.Initializers.Add(declaration);
                        }
                        else
                        {
                            result.Initializers.AddRange(node.Children[2].GetAllListAstNodes<Expression>()
                                .Select(x => new ExpressionStatement(x)));
                        }
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[3].Result);

                    if (node.Children[4].HasChildren)
                        result.Condition = (Expression) node.Children[4].Result;

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[5].Result);

                    if (node.Children[6].HasChildren)
                    {
                        result.Iterators.AddRange(node.Children[6].Children[0].GetAllListAstNodes<Expression>()
                            .Select(x => new ExpressionStatement(x)));
                    }

                    result.RightParenthese = (AstToken) node.Children[7].Result;

                    var bodyNode = node.Children[8];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);
                    result.Body = (Statement) bodyNode.Result;

                    return result;
                });

            var foreachLoopStatement = new GrammarDefinition("ForEachLoopStatement",
                rule: ToElement(FOREACH)
                      + ToElement(OPEN_PARENS)
                      + typeReference
                      + identifierInsideBody
                      + ToElement(IN)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + embeddedStatement,
                createNode: node =>
                {
                    var bodyNode = node.Children[7];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new ForeachLoopStatement
                    {
                        ForeachKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        Type = (TypeReference) node.Children[2].Result,
                        Identifier = (Identifier) node.Children[3].Result,
                        InKeyword = (AstToken) node.Children[4].Result,
                        Target = (Expression) node.Children[5].Result,
                        RightParenthese = (AstToken) node.Children[6].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var loopStatement = new GrammarDefinition("LoopStatement",
                rule: whileLoopStatement
                      | doLoopStatement
                      | forLoopStatement
                      | foreachLoopStatement);

            var lockStatement = new GrammarDefinition("LockStatement",
                rule: ToElement(LOCK)
                      + ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + statement,
                createNode: node =>
                {
                    var bodyNode = node.Children[4];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new LockStatement
                    {
                        LockKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        LockObject = (Expression) node.Children[2].Result,
                        RightParenthese = (AstToken) node.Children[3].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var resourceAcquisition = new GrammarDefinition("ResourceAcquisition",
                rule: variableDeclaration | expression);

            var usingStatement = new GrammarDefinition("UsingStatement",
                rule: ToElement(USING)
                      + ToElement(OPEN_PARENS)
                      + resourceAcquisition
                      + ToElement(CLOSE_PARENS)
                      + statement,
                createNode: node =>
                {
                    var bodyNode = node.Children[4];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new UsingStatement()
                    {
                        UsingKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        DisposableObject = node.Children[2].Result,
                        RightParenthese = (AstToken) node.Children[3].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var breakStatement = new GrammarDefinition("BreakStatement",
                rule: ToElement(BREAK)
                      + ToElement(SEMICOLON),
                createNode: node => new BreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Semicolon = (AstToken) node.Children[1].Result
                });

            var continueStatement = new GrammarDefinition("ContinueStatement",
                rule: ToElement(CONTINUE)
                      + ToElement(SEMICOLON),
                createNode: node => new BreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Semicolon = (AstToken) node.Children[1].Result
                });

            var returnStatement = new GrammarDefinition("ReturnStatement",
                rule: ToElement(RETURN)
                      + expressionOptional
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new ReturnStatement();
                    result.ReturnKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children[1].HasChildren)
                        result.Value = (Expression) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var throwStatement = new GrammarDefinition("ThrowStatement",
                rule: ToElement(THROW)
                      + expressionOptional
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new ThrowStatement();
                    result.ThrowKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children[1].HasChildren)
                        result.Expression = (Expression) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var gotoStatement = new GrammarDefinition("GotoStatement",
                rule: ToElement(GOTO)
                      + identifierInsideBody
                      + ToElement(SEMICOLON),
                // TODO: goto case and goto default statements.
                createNode: node =>
                {
                    var result = new GotoStatement();
                    result.GotoKeyword = (AstToken) node.Children[0].Result;
                    result.LabelIdentifier = (Identifier) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var jumpStatement = new GrammarDefinition("JumpStatement",
                rule: breakStatement
                      | continueStatement
                      | gotoStatement
                      | returnStatement
                      | throwStatement);

            var yieldStatement = new GrammarDefinition("YieldStatement",
                rule: ToElement(YIELD)
                      + ToElement(RETURN)
                      + expression
                      + ToElement(SEMICOLON),
                createNode: node => new YieldStatement()
                {
                    YieldKeyword = (AstToken) node.Children[0].Result,
                    ReturnKeyword = (AstToken) node.Children[1].Result,
                    Value = (Expression) node.Children[2].Result
                });

            var yieldBreakStatement = new GrammarDefinition("YieldBreakStatement",
                rule: ToElement(YIELD)
                      + ToElement(BREAK)
                      + ToElement(SEMICOLON),
                createNode: node => new YieldBreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    BreakKeyword = (AstToken) node.Children[1].Result
                });

            var specificCatchClause = new GrammarDefinition("SpecificCatchClause",
                rule: ToElement(CATCH) + ToElement(OPEN_PARENS)
                    + namespaceOrTypeExpression + identifierInsideBodyOptional + ToElement(CLOSE_PARENS)
                    + blockStatement,
                createNode: node =>
                {
                    var result = new CatchClause();
                    result.CatchKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    result.ExceptionType = (TypeReference) node.Children[2].Result;

                    if (node.Children[3].HasChildren)
                        result.ExceptionIdentifier = (Identifier) node.Children[3].Result;

                    result.RightParenthese = (AstToken) node.Children[4].Result;
                    result.Body = (BlockStatement) node.Children[5].Result;
                    return result;
                });

            var generalCatchClause = new GrammarDefinition("GeneralCatchClause",
                rule: ToElement(CATCH) + blockStatement,
                createNode: node => new CatchClause
                {
                    CatchKeyword = (AstToken) node.Children[0].Result,
                    Body = (BlockStatement) node.Children[1].Result
                });

            var catchClause = new GrammarDefinition("CatchClause",
                rule: specificCatchClause | generalCatchClause);

            var catchClauses = new GrammarDefinition("CatchClauses");
            catchClauses.Rule = catchClause | catchClauses + catchClause;

            var finallyClause = new GrammarDefinition("FinallyClause",
                rule: ToElement(FINALLY) + blockStatement);

            var tryCatchStatement = new GrammarDefinition("TryCatchStatement",
                rule: ToElement(TRY) + blockStatement + catchClauses
                      | ToElement(TRY) + blockStatement + finallyClause
                      | ToElement(TRY) + blockStatement + catchClauses + finallyClause,
                createNode: node =>
                {
                    var result = new TryCatchStatement();
                    result.TryKeyword = (AstToken) node.Children[0].Result;
                    result.TryBlock = (BlockStatement) node.Children[1].Result;

                    ParserNode finallyClauseNode = null;
                    if (node.Children[2].GrammarElement == finallyClause)
                    {
                        finallyClauseNode = node.Children[2];
                    }
                    else
                    {
                        result.CatchClauses.AddRange(node.Children[2].GetAllListAstNodes<CatchClause>());
                    }

                    if (node.Children.Count == 4)
                        finallyClauseNode = node.Children[3];

                    if (finallyClauseNode != null)
                    {
                        result.FinallyKeyword = (AstToken) finallyClauseNode.Children[0].Result;
                        result.FinallyBlock = (BlockStatement) finallyClauseNode.Children[1].Result;
                    }

                    return result;
                });

            var unsafeStatement = new GrammarDefinition("UnsafeStatement",
                rule: ToElement(UNSAFE) + blockStatement,
                createNode: node => new UnsafeStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Body = (BlockStatement) node.Children[1].Result
                });

            var fixedStatement = new GrammarDefinition("FixedStatement",
                rule: ToElement(FIXED) + ToElement(OPEN_PARENS)
                + variableDeclaration + ToElement(CLOSE_PARENS) + embeddedStatement,
                createNode: node =>
                {
                    var result = new FixedStatement();
                    result.Keyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;

                    result.VariableDeclaration = (VariableDeclarationStatement) node.Children[2].Result;

                    result.RightParenthese = (AstToken) node.Children[3].Result;

                    var bodyNode = node.Children[4];
                    result.Body = (Statement) bodyNode.Result;
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return result;
                });

            embeddedStatement.Rule = emptyStatement
                                     | expressionStatement
                                     | blockStatement
                                     | selectionStatement
                                     | loopStatement
                                     | jumpStatement
                                     | lockStatement
                                     | usingStatement
                                     | yieldStatement
                                     | yieldBreakStatement
                                     | tryCatchStatement
                                     | unsafeStatement
                                     | fixedStatement
                ;


            statement.Rule = variableDeclarationStatement
                             | labelStatement
                             | embeddedStatement;
            ;
            #endregion

            #region Members

            var customAttribute = new GrammarDefinition("CustomAttribute",
                rule: namespaceOrTypeExpression
                | namespaceOrTypeExpression + ToElement(OPEN_PARENS) + argumentListOptional + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new CustomAttribute();
                    result.Type = ((IConvertibleToType) node.Children[0].Result).ToTypeReference();

                    if (node.Children.Count > 1)
                    {
                        result.LeftParenthese = (AstToken) node.Children[1].Result;

                        if (node.Children[2].HasChildren)
                        {
                            foreach (var child in node.Children[2].Children[0].GetAllListAstNodes())
                            {
                                if (child is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, child);
                                else
                                    result.Arguments.Add((Expression) child);
                            }
                        }

                        result.RightParenthese = (AstToken) node.Children[3].Result;

                    }
                    return result;
                });

            var customAttributeList = new GrammarDefinition("CustomAttributeList");
            customAttributeList.Rule = customAttribute | customAttributeList + ToElement(COMMA) + customAttribute;

            var customAttributePrefix = new GrammarDefinition("CustomAttributePrefix",
                rule: ToElement(ASSEMBLY) | ToElement(MODULE));

            var customAttributePrefixOptional = new GrammarDefinition("CustomAttributePrefixOptional",
                rule: null | customAttributePrefix + ToElement(COLON));

            var customAttributeSection = new GrammarDefinition("CustomAttributeSection",
                rule: ToElement(OPEN_BRACKET_EXPR) // HACK: use expression brackets instead to avoid conflicts.
                + customAttributePrefixOptional
                + customAttributeList 
                + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new CustomAttributeSection();
                    result.LeftBracket = (AstToken) node.Children[0].Result;

                    if (node.Children[1].Result != null)
                    {
                        result.VariantKeyword = (AstToken) node.Children[1].Result;
                        result.Variant = CSharpLanguage.SectionVariantFromString(result.VariantKeyword.Value);
                    }

                    foreach (var child in node.Children[2].GetAllListAstNodes())
                    {
                        if (child is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, child);
                        else
                            result.Attributes.Add((CustomAttribute) child);
                    }

                    result.RightBracket = (AstToken) node.Children[3].Result;
                    return result;
                });

            var customAttributeSectionList = new GrammarDefinition("CustomAttributeSectionList");
            customAttributeSectionList.Rule = customAttributeSection | customAttributeSectionList + customAttributeSection;

            var customAttributeSectionListOptional = new GrammarDefinition("CustomAttributeSectionListOptional",
                rule: null | customAttributeSectionList);

            var modifier = new GrammarDefinition("Modifier",
                rule: ToElement(PRIVATE)
                      | ToElement(PROTECTED)
                      | ToElement(INTERNAL)
                      | ToElement(PUBLIC)
                      | ToElement(STATIC)
                      | ToElement(ABSTRACT)
                      | ToElement(OVERRIDE)
                      | ToElement(PARTIAL)
                      | ToElement(CONST)
                      | ToElement(READONLY)
                      | ToElement(VIRTUAL)
                      | ToElement(SEALED)
                      | ToElement(UNSAFE)
                      | ToElement(FIXED)
                      | ToElement(ASYNC)
                      | ToElement(EXTERN),
                createNode: node => new ModifierElement(((AstToken) node.Children[0].Result).Value, node.Children[0].Range)
                {
                    Modifier = CSharpLanguage.ModifierFromString(((AstToken) node.Children[0].Result).Value)
                });

            var modifierList = new GrammarDefinition("ModifierList");
            modifierList.Rule = modifier | modifierList + modifier;
            var modifierListOptional = new GrammarDefinition("ModifierListOptional",
                rule: null | modifierList);

            var fieldDeclaration = new GrammarDefinition("FieldDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + variableDeclaratorList
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new FieldDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.FieldType = (TypeReference) node.Children[2].Result;

                    foreach (var subNode in node.Children[3].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Declarators.Add((VariableDeclarator) subNode);
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[4].Result);
                    return result;
                });

            var parameterModifier = new GrammarDefinition("ParameterModifier",
                rule: null
                      | ToElement(THIS)
                      | ToElement(REF)
                      | ToElement(OUT)
                      | ToElement(PARAMS));
            var parameterDeclaration = new GrammarDefinition("ParameterDeclaration",
                rule: customAttributeSectionListOptional
                      + parameterModifier
                      + typeReference
                      + variableDeclarator,
                createNode: node =>
                {
                    var result = new ParameterDeclaration();

                    if (node.Children[0].HasChildren)
                    {
                        result.CustomAttributeSections.AddRange(
                            node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());
                    }

                    result.ParameterModifierToken = (AstToken) (node.Children[1].HasChildren ? node.Children[1].Children[0].Result : null);
                    result.ParameterType = (TypeReference) node.Children[2].Result;
                    result.Declarator = (VariableDeclarator) node.Children[3].Result;
                    return result;
                });

            var parameterDeclarationList = new GrammarDefinition("ParameterDeclarationList");
            parameterDeclarationList.Rule = parameterDeclaration | parameterDeclarationList + ToElement(COMMA) + parameterDeclaration;
            var optionalParameterDeclarationList = new GrammarDefinition("OptionalParameterDeclarationList",
                rule: null | parameterDeclarationList);

            var constructorInitializerVariant = new GrammarDefinition("ConstructorInitializerVariant",
                rule: ToElement(THIS) | ToElement(BASE));
            var constructorInitializer = new GrammarDefinition("ConstructorInitializer",
                rule: constructorInitializerVariant
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new Members.ConstructorInitializer();
                    result.VariantToken = (AstToken) node.Children[0].Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    if (node.Children[2].HasChildren)
                    {
                        foreach (var subNode in node.Children[2].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Arguments.Add((Expression) subNode);
                        }
                    }
                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    return result;
                });

            var optionalConstructorInitializerList = new GrammarDefinition("OptionalConstructorInitializer",
                rule: null | ToElement(COLON) + constructorInitializer);

            var constructorDeclaration = new GrammarDefinition("ConstructorDeclaration",
                rule: customAttributeSectionListOptional
                        + modifierListOptional
                        + ToElement(IDENTIFIER)
                        + ToElement(OPEN_PARENS)
                        + optionalParameterDeclarationList
                        + ToElement(CLOSE_PARENS)
                        + optionalConstructorInitializerList
                        + blockStatement,
                createNode: node =>
                {
                    var result = new Members.ConstructorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.Identifier = ToIdentifier(node.Children[2].Result);
                    result.LeftParenthese = (AstToken) node.Children[3].Result;

                    if (node.Children[4].HasChildren)
                    {
                        foreach (var subNode in node.Children[4].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        result.Colon = (AstToken) node.Children[6].Children[0].Result;
                        result.Initializer = (Members.ConstructorInitializer) node.Children[6].Children[1].Result;
                    }

                    result.Body = (BlockStatement) node.Children[7].Result;
                    return result;
                });

            var conversionOperator = new GrammarDefinition("ConversionOperator",
                rule: ToElement(IMPLICIT)
                      | ToElement(EXPLICIT));

            var conversionOperatorDeclaration = new GrammarDefinition("ConversionOperatorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + conversionOperator
                      + ToElement(OPERATOR)
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + blockStatement,
                createNode: node =>
                {
                    var result = new OperatorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.Identifier = ToIdentifier(node.Children[2].Result);
                    result.OperatorType = CSharpLanguage.OperatorDeclarationTypeFromString(result.Identifier.Name);
                    result.OperatorKeyword = (AstToken) node.Children[3].Result;
                    result.ReturnType = ToTypeReference(ToIdentifier(node.Children[4].Result));
                    result.LeftParenthese = (AstToken)node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        foreach (var subNode in node.Children[6].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration)subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[7].Result;
                    result.Body = (BlockStatement) node.Children[8].Result;

                    return result;
                });

            var overloadableOperator = new GrammarDefinition("OverloadableOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS)
                      | ToElement(STAR)
                      | ToElement(DIV)
                      | ToElement(PERCENT)
                      | ToElement(BITWISE_AND)
                      | ToElement(BITWISE_OR)
                      | ToElement(CARRET)
                      | ToElement(OP_EQUALS)
                      | ToElement(OP_NOTEQUALS)
                      | ToElement(OP_GT)
                      | ToElement(OP_GE)
                      | ToElement(OP_LT)
                      | ToElement(OP_LE)
                      | ToElement(OP_SHIFT_LEFT)
                      | ToElement(OP_SHIFT_RIGHT)
                      | ToElement(TRUE)
                      | ToElement(FALSE)
                      | ToElement(BANG)
                      | ToElement(TILDE)
                      | ToElement(OP_INC)
                      | ToElement(OP_DEC));

            var arithmeticOperatorDeclaration = new GrammarDefinition("ArithmeticOperatorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(OPERATOR)
                      + overloadableOperator
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + blockStatement,
                createNode: node =>
                {
                    var result = new OperatorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.ReturnType = (TypeReference) node.Children[2].Result;
                    result.OperatorKeyword = (AstToken)node.Children[3].Result;
                    result.Identifier = ToIdentifier(node.Children[4].Result);

                    result.LeftParenthese = (AstToken)node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        foreach (var subNode in node.Children[6].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration)subNode);
                        }
                    }

                    result.RightParenthese = (AstToken)node.Children[7].Result;

                    result.OperatorType = CSharpLanguage.OperatorDeclarationTypeFromString(result.Identifier.Name);
                    if (result.Parameters.Count == 2)
                    {
                        if (result.OperatorType == OperatorDeclarationType.Positive)
                            result.OperatorType = OperatorDeclarationType.Add;
                        else if (result.OperatorType == OperatorDeclarationType.Negative)
                            result.OperatorType = OperatorDeclarationType.Subtract;
                    }

                    result.Body = (BlockStatement)node.Children[8].Result;

                    return result;
                });

            var operatorDeclaration = new GrammarDefinition("OperatorDeclaration",
                rule: conversionOperatorDeclaration | arithmeticOperatorDeclaration);

            var methodDeclarationBody = new GrammarDefinition("MethodDeclarationBody",
                rule: ToElement(SEMICOLON) | blockStatement);

            var methodDeclaration = new GrammarDefinition("MethodDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + methodDeclarationBody,
                createNode: node =>
                {
                    var result = new MethodDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.ReturnType = (TypeReference) node.Children[2].Result;
                    result.Identifier = ToIdentifier(node.Children[3].Result);
                    result.LeftParenthese = (AstToken) node.Children[4].Result;

                    if (node.Children[5].HasChildren)
                    {
                        foreach (var subNode in node.Children[5].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[6].Result;

                    var body = node.Children[7].Result;
                    if (body is AstToken)
                        result.AddChild(AstNodeTitles.Semicolon, (AstToken) body);
                    else
                        result.Body = (BlockStatement) body;
                    return result;
                });

            var eventDeclaration = new GrammarDefinition("EventDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + ToElement(EVENT)
                      + typeReference
                      + variableDeclaratorList
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new EventDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.EventKeyword = (AstToken) node.Children[2].Result;
                    result.EventType = (TypeReference) node.Children[3].Result;

                    foreach (var subNode in node.Children[4].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Declarators.Add((VariableDeclarator) subNode);
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[5].Result);
                    return result;
                });

            var accessorKeyword = new GrammarDefinition("AccessorKeyword",
                rule: ToElement(GET)
                | ToElement(SET));
            var accessorBody = new GrammarDefinition("AccessorBody",
                rule: ToElement(SEMICOLON)
                      | blockStatement);

            var accessorDeclaration = new GrammarDefinition("AccessorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + accessorKeyword
                      + accessorBody,
                createNode: node =>
                {
                    var result = new AccessorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.AccessorKeyword = (AstToken) node.Children[2].Children[0].Result;

                    var bodyNode = node.Children[3].Children[0].Result;
                    if (bodyNode is AstToken)
                        result.AddChild(AstNodeTitles.Semicolon, bodyNode);
                    else
                        result.Body = (BlockStatement) bodyNode;

                    return result;
                });

            var accessorDeclarationList = new GrammarDefinition("AccessorDeclarationList");
            accessorDeclarationList.Rule = accessorDeclaration | accessorDeclaration + accessorDeclaration;

            var propertyDeclaration = new GrammarDefinition("PropertyDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_BRACE)
                      + accessorDeclarationList
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new PropertyDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.PropertyType = (TypeReference) node.Children[2].Result;
                    result.Identifier = ToIdentifier(node.Children[3].Result);
                    result.StartScope = node.Children[4].Result;

                    foreach (var accessor in node.Children[5].Children)
                    {
                        var declaration = (AccessorDeclaration) accessor.Result;
                        // TODO: detect duplicate accessor declarations.
                        switch (declaration.AccessorKeyword.Value)
                        {
                            case "get":
                                result.Getter = declaration;
                                break;
                            case "set":
                                result.Setter = declaration;
                                break;
                        }
                    }

                    result.EndScope = node.Children[6].Result;
                    return result;
                });

            var memberDeclaration = new GrammarDefinition("MemberDeclaration");
            var memberDeclarationList = new GrammarDefinition("MemberDeclarationList");
            memberDeclarationList.Rule = memberDeclaration | memberDeclarationList + memberDeclaration;
            var memberDeclarationListOptional = new GrammarDefinition("MemberDeclarationListOptional");
            memberDeclarationListOptional.Rule = null | memberDeclarationList;

            var baseTypeList = new GrammarDefinition("BaseTypeList");
            baseTypeList.Rule = typeReference | baseTypeList + ToElement(COMMA) + typeReference;

            var optionalBaseTypeList = new GrammarDefinition("OptionalBaseTypeList");
            optionalBaseTypeList.Rule = null | ToElement(COLON) + baseTypeList;

            var typeVariantKeyword = new GrammarDefinition("TypeVariantKeyword",
                rule: ToElement(CLASS)
                      | ToElement(STRUCT)
                      | ToElement(INTERFACE)
                      | ToElement(ENUM));
            var typeDeclaration = new GrammarDefinition("TypeDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeVariantKeyword
                      + ToElement(IDENTIFIER)
                      + optionalBaseTypeList
                      + ToElement(OPEN_BRACE)
                      + memberDeclarationListOptional
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new TypeDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    var variantToken = (AstToken) node.Children[2].Children[0].Result;
                    result.TypeVariant = CSharpLanguage.TypeVariantFromString(variantToken.Value);
                    result.TypeVariantToken = variantToken;
                    result.Identifier = ToIdentifier(node.Children[3].Result);

                    if (node.Children[4].HasChildren)
                    {
                        result.AddChild(AstNodeTitles.Colon, node.Children[4].Children[0].Result);

                        foreach (var child in node.Children[4].Children[1].GetAllListAstNodes())
                        {
                            if (child is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, child);
                            else
                                result.BaseTypes.Add((TypeReference) child);
                        }
                    }

                    result.StartScope = node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        result.Members.AddRange(node.Children[6].Children[0].GetAllListAstNodes<MemberDeclaration>());
                    }

                    result.EndScope = node.Children[7].Result;
                    return result;
                });

            memberDeclaration.Rule = methodDeclaration
                                     | constructorDeclaration
                                     | operatorDeclaration
                                     | propertyDeclaration
                                     | eventDeclaration
                                     | fieldDeclaration
                                     | typeDeclaration
                                    ;

            var typeOrNamespaceDeclarationList = new GrammarDefinition("TypeOrNamespaceDeclarationList");
            var typeOrNamespaceDeclarationListOptional = new GrammarDefinition("TypeOrNamespaceDeclarationListOptional",
                rule: null | typeOrNamespaceDeclarationList);

            var namespaceDeclaration = new GrammarDefinition("NamespaceDeclaration",
                rule: ToElement(NAMESPACE)
                      + typeNameExpression
                      + ToElement(OPEN_BRACE)
                      + usingDirectiveListOptional
                      + typeOrNamespaceDeclarationListOptional
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new NamespaceDeclaration();
                    result.Keyword = (AstToken) node.Children[0].Result;
                    result.Identifier = ((IConvertibleToIdentifier) node.Children[1].Result).ToIdentifier();
                    result.StartScope = node.Children[2].Result;

                    if (node.Children[3].HasChildren)
                    {
                        result.UsingDirectives.AddRange(node.Children[3].Children[0].GetAllListAstNodes<UsingDirective>());
                    }

                    if (node.Children[4].HasChildren)
                    {
                        foreach (var subNode in node.Children[4].Children[0].GetAllListAstNodes())
                        {
                            var type = subNode as TypeDeclaration;
                            if (type != null)
                                result.Types.Add(type);
                            else
                                result.Namespaces.Add((NamespaceDeclaration) subNode);
                        }
                    }

                    result.EndScope = node.Children[5].Result;

                    return result;
                });

            var typeOrNamespaceDeclaration = new GrammarDefinition("TypeOrNamespaceDeclaration",
                rule: namespaceDeclaration
                      | typeDeclaration);
            typeOrNamespaceDeclarationList.Rule = typeOrNamespaceDeclaration
                                                  | typeOrNamespaceDeclarationList
                                                  + typeOrNamespaceDeclaration;

            #endregion

            #region Initialize definitions

            var variableInitializerList = new GrammarDefinition("VariableInitializerList");
            variableInitializerList.Rule = variableInitializer
                                           | variableInitializerList
                                           + ToElement(COMMA)
                                           + variableInitializer;
            var variableInitializerListOptional = new GrammarDefinition("VariableInitializerListOptional",
                rule: null | variableInitializerList);

            arrayInitializer.Rule = ToElement(OPEN_BRACE)
                                    + variableInitializerListOptional
                                    + ToElement(CLOSE_BRACE)
                                    | ToElement(OPEN_BRACE)
                                    + variableInitializerList
                                    + ToElement(COMMA)
                                    + ToElement(CLOSE_BRACE);

            arrayInitializer.ComputeResult = node =>
            {
                var result = new ArrayInitializer();
                result.OpeningBrace = node.Children[0].Result;

                ParserNode initializersNode = null;
                if (node.Children.Count == 4)
                {
                    initializersNode = node.Children[1];
                }
                else
                {
                    if (node.Children[1].HasChildren)
                        initializersNode = node.Children[1].Children[0];
                }

                if (initializersNode != null)
                {
                    foreach (var element in initializersNode.GetAllListAstNodes())
                    {
                        if (element is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, element);
                        else
                            result.Elements.Add((Expression) element);
                    }
                }

                if (node.Children.Count == 4)
                    result.AddChild(AstNodeTitles.ElementSeparator, node.Children[2].Result);
                result.ClosingBrace = node.Children[node.Children.Count - 1].Result;
                return result;
            };

            variableInitializer.Rule = expression
                                       | arrayInitializer
                ;

            var variableType = new GrammarDefinition("VariableType");
            variableType.Rule = typeNameExpression | variableType + rankSpecifier | variableType + ToElement(STAR);
            variableType.ComputeResult = node =>
            {
                var type = ToTypeReference((IConvertibleToType) node.Children[0].Result);
                if (node.Children.Count > 1)
                {
                    var specifier = node.Children[1].Result as ArrayTypeRankSpecifier;
                    if (specifier != null)
                    {
                        type = new ArrayTypeReference(type, specifier);
                    }
                    else
                    {
                        type = new PointerTypeReference(type)
                        {
                            PointerToken = (AstToken) node.Children[1].Result
                        };
                    }
                }
                return type;
            };

            // Types are recognized as expressions to prevent a conflict in the grammar.
            // TODO: also support array and pointer types.

            variableDeclaration.Rule =
                variableType
                + variableDeclaratorList;
            
            variableDeclaration.ComputeResult = node =>
            {
                var result = new VariableDeclarationStatement();
                result.VariableType = ToTypeReference((IConvertibleToType)node.Children[0].Result);

                foreach (var subNode in node.Children[1].GetAllListAstNodes())
                {
                    if (subNode is AstToken)
                        result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                    else
                        result.Declarators.Add((VariableDeclarator) subNode);
                }

                return result;
            };

            statementList.Rule = statement | statementList + statement;

            #endregion

            #region Root compilation unit

            var usingNamespaceDirective = new GrammarDefinition("UsingNamespaceDirective",
                rule: ToElement(USING)
                      + namespaceOrTypeExpression
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new UsingNamespaceDirective();

                    result.UsingKeyword = (AstToken) node.Children[0].Result;
                    result.NamespaceIdentifier = ((IConvertibleToIdentifier) node.Children[1].Result).ToIdentifier();
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);

                    return result;
                });

            var usingAliasDirective = new GrammarDefinition("UsingAliasDirective",
                rule: ToElement(USING)
                      + ToElement(IDENTIFIER)
                      + ToElement(EQUALS)
                      + typeReference
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new UsingAliasDirective
                    {
                        UsingKeyword = (AstToken) node.Children[0].Result,
                        AliasIdentifier = ToIdentifier(node.Children[1].Result),
                        OperatorToken = (AstToken) node.Children[2].Result,
                        TypeImport = (TypeReference) node.Children[3].Result
                    };
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[4].Result);
                    return result;
                });

            var usingDirective = new GrammarDefinition("UsingNamespaceDirective",
                rule: usingNamespaceDirective | usingAliasDirective);

            var usingDirectiveList = new GrammarDefinition("UsingDirectiveList");
            usingDirectiveList.Rule = usingDirective | usingDirectiveList + usingDirective;
            usingDirectiveListOptional.Rule = null | usingDirectiveList;

            var compilationUnit = new GrammarDefinition("CompilationUnit",
                rule: usingDirectiveListOptional
                + typeOrNamespaceDeclarationListOptional,
                createNode: node =>
                {
                    var result = new CompilationUnit();

                    if (node.Children[0].HasChildren)
                    {
                        result.UsingDirectives.AddRange(node.Children[0].Children[0].GetAllListAstNodes<UsingDirective>());
                    }

                    if (node.Children[1].HasChildren)
                    {
                        foreach (var subNode in node.Children[1].Children[0].GetAllListAstNodes())
                        {
                            var typeDecl = subNode as TypeDeclaration;
                            if (typeDecl == null)
                                result.Namespaces.Add((NamespaceDeclaration) subNode);
                            else
                                result.Types.Add(typeDecl);
                        }
                    }

                    return result;
                });

            #endregion

            RootDefinitions.Add(DefaultRoot = compilationUnit);
            RootDefinitions.Add(MemberDeclarationRule = memberDeclaration);
            RootDefinitions.Add(StatementRule = statement);
        }
コード例 #58
0
            public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
            {
                base.VisitParameterDeclaration (parameterDeclaration);

                var resolveResult = ctx.Resolve (parameterDeclaration) as LocalResolveResult;
                CollectIssues (parameterDeclaration, parameterDeclaration.Parent, resolveResult);
            }
コード例 #59
0
        public ClassDefinition GetContextFieldDeclaration()
        {
            Field field;
            Field field2;
            ParameterDeclaration      declaration;
            MemberReferenceExpression expression;
            ReferenceExpression       expression2;
            BinaryExpression          expression3;
            ReferenceExpression       expression4;
            ReferenceExpression       expression5;
            MemberReferenceExpression expression6;
            BinaryExpression          expression7;
            Block           block;
            Constructor     constructor;
            ClassDefinition definition;
            Type            type        = this._evaluationContext.GetType();
            Type            type2       = this._evaluationContext.ScriptContainer.GetType();
            ClassDefinition definition1 = definition = new ClassDefinition(LexicalInfo.Empty);
            string          text1       = definition.Name = "_";

            TypeMember[]  items      = new TypeMember[3];
            Field         field1     = field = new Field(LexicalInfo.Empty);
            int           num1       = (int)(field.Modifiers = TypeMemberModifiers.Static | TypeMemberModifiers.Public);
            string        text2      = field.Name = "ScriptContainer";
            TypeReference reference1 = field.Type = TypeReference.Lift(type2);
            int           num2       = (int)(field.IsVolatile = false);

            items[0] = field;
            Field         field3     = field2 = new Field(LexicalInfo.Empty);
            string        text3      = field2.Name = "EvaluationContext";
            TypeReference reference4 = field2.Type = TypeReference.Lift(type);
            int           num3       = (int)(field2.IsVolatile = false);

            items[1] = field2;
            Constructor constructor1 = constructor = new Constructor(LexicalInfo.Empty);
            string      text4        = constructor.Name = "constructor";

            ParameterDeclaration[] parameters   = new ParameterDeclaration[1];
            ParameterDeclaration   declaration1 = declaration = new ParameterDeclaration(LexicalInfo.Empty);
            string        text5      = declaration.Name = "context";
            TypeReference reference5 = declaration.Type = TypeReference.Lift(type);

            parameters[0] = declaration;
            ParameterDeclarationCollection collection1 = constructor.Parameters = ParameterDeclarationCollection.FromArray(false, parameters);
            Block block1 = block = new Block(LexicalInfo.Empty);

            Statement[]      statementArray1 = new Statement[2];
            BinaryExpression expression1     = expression3 = new BinaryExpression(LexicalInfo.Empty);
            int num4 = (int)(expression3.Operator = BinaryOperatorType.Assign);
            MemberReferenceExpression expression14 = expression = new MemberReferenceExpression(LexicalInfo.Empty);
            string text6 = expression.Name = "EvaluationContext";
            SelfLiteralExpression     expression15 = expression.Target = new SelfLiteralExpression(LexicalInfo.Empty);
            MemberReferenceExpression expression16 = expression3.Left = expression;
            ReferenceExpression       expression17 = expression2 = new ReferenceExpression(LexicalInfo.Empty);
            string text7 = expression2.Name = "context";
            ReferenceExpression expression18 = expression3.Right = expression2;

            statementArray1[0] = Statement.Lift(expression3);
            BinaryExpression expression19 = expression7 = new BinaryExpression(LexicalInfo.Empty);
            int num5 = (int)(expression7.Operator = BinaryOperatorType.Assign);
            ReferenceExpression expression20 = expression4 = new ReferenceExpression(LexicalInfo.Empty);
            string text8 = expression4.Name = "ScriptContainer";
            ReferenceExpression       expression21 = expression7.Left = expression4;
            MemberReferenceExpression expression22 = expression6 = new MemberReferenceExpression(LexicalInfo.Empty);
            string text9 = expression6.Name = "ScriptContainer";
            ReferenceExpression expression23 = expression5 = new ReferenceExpression(LexicalInfo.Empty);
            string text10 = expression5.Name = "context";
            ReferenceExpression       expression24 = expression6.Target = expression5;
            MemberReferenceExpression expression25 = expression7.Right = expression6;

            statementArray1[1] = Statement.Lift(expression7);
            StatementCollection collection2 = block.Statements = StatementCollection.FromArray(statementArray1);
            Block block3 = constructor.Body = block;

            items[2] = constructor;
            TypeMemberCollection collection3 = definition.Members = TypeMemberCollection.FromArray(items);

            return(definition);
        }
コード例 #60
0
ファイル: CSharpParser.cs プロジェクト: 0xb1dd1e/NRefactory
			void AddParameter(AstNode parent, AParametersCollection parameters)
			{
				if (parameters == null)
					return;
				var paramLocation = LocationsBag.GetLocations(parameters);
				
				for (int i = 0; i < parameters.Count; i++) {
					var p = (Parameter)parameters.FixedParameters [i];
					if (p == null)
						continue;
					var location = LocationsBag.GetLocations(p);
					var parameterDeclarationExpression = new ParameterDeclaration();
					AddAttributeSection(parameterDeclarationExpression, p);
					switch (p.ModFlags) {
						case Parameter.Modifier.OUT:
							parameterDeclarationExpression.ParameterModifier = ParameterModifier.Out;
							if (location != null)
								parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.OutModifierRole), ParameterDeclaration.OutModifierRole);
							break;
						case Parameter.Modifier.REF:
							parameterDeclarationExpression.ParameterModifier = ParameterModifier.Ref;
							if (location != null)
								parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.RefModifierRole), ParameterDeclaration.RefModifierRole);
							break;
						case Parameter.Modifier.PARAMS:
							parameterDeclarationExpression.ParameterModifier = ParameterModifier.Params;
							if (location != null)
								parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ParamsModifierRole), ParameterDeclaration.ParamsModifierRole);
							break;
						default:
							if (p.HasExtensionMethodModifier) {
								parameterDeclarationExpression.ParameterModifier = ParameterModifier.This;
								if (location != null) {
									parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ThisModifierRole), ParameterDeclaration.ThisModifierRole);
								}
							}
							break;
					}
					if (p.TypeExpression != null) // lambdas may have no types (a, b) => ...
						parameterDeclarationExpression.AddChild(ConvertToType(p.TypeExpression), Roles.Type);
					if (p.Name != null)
						parameterDeclarationExpression.AddChild(Identifier.Create(p.Name, Convert(p.Location)), Roles.Identifier);
					if (p.HasDefaultValue) {
						if (location != null && location.Count > 1)
							parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Assign), Roles.Assign);
						parameterDeclarationExpression.AddChild((Expression)p.DefaultValue.Accept(this), Roles.Expression);
					}
					parent.AddChild(parameterDeclarationExpression, Roles.Parameter);
					if (paramLocation != null && i < paramLocation.Count) {
						parent.AddChild(new CSharpTokenNode(Convert(paramLocation [i]), Roles.Comma), Roles.Comma);
					}
				}
			}