Esempio n. 1
0
        public void SwitchWithGotoDefault()
        {
            SwitchStatement @switch = new SwitchStatement
            {
                SwitchSections =
                {
                    new SwitchSection { // case 0:
                        CaseLabels = { new CaseLabel(new PrimitiveExpression(0)) },
                        Statements = { new GotoDefaultStatement()                }
                    },
                    new SwitchSection { // default:
                        CaseLabels = { new CaseLabel()                           },
                        Statements =
                        {
                            new ExpressionStatement(new AssignmentExpression(new IdentifierExpression("a"), new PrimitiveExpression(1))),
                            new BreakStatement()
                        }
                    }
                }
            };

            SwitchSection case0          = @switch.SwitchSections.ElementAt(0);
            SwitchSection defaultSection = @switch.SwitchSections.ElementAt(1);

            DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(@switch);

            da.Analyze("a");
            Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(@switch));
            Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(case0.Statements.First()));
            Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(defaultSection.Statements.First()));
            Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(defaultSection.Statements.Last()));
            Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(defaultSection.Statements.Last()));
            Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(@switch));
        }
Esempio n. 2
0
 public virtual void VisitSwitchSection(SwitchSection switchSection)
 {
     if (ThrowException)
     {
         throw (Exception)CreateException(switchSection);
     }
 }
            public override void VisitSwitchSection(SwitchSection switchSection)
            {
                base.VisitSwitchSection(switchSection);

                if (switchSection.CaseLabels.Count < 2)
                {
                    return;
                }

                if (!switchSection.CaseLabels.Any(label => label.Expression.IsNull))
                {
                    return;
                }

                foreach (var caseLabel in switchSection.CaseLabels)
                {
                    if (caseLabel.Expression.IsNull)
                    {
                        continue;
                    }
                    AddIssue(new CodeIssue(
                                 caseLabel,
                                 ctx.TranslateString("Redundant case label"),
                                 string.Format(ctx.TranslateString("Remove 'case {0}'"), caseLabel.Expression),
                                 scipt => {
                        scipt.Remove(caseLabel);
                    }
                                 )
                    {
                        IssueMarker = IssueMarker.GrayOut
                    });
                }
            }
        public override AstVisitAction VisitSwitchStatement(SwitchStatementAst switchStatementAst)
        {
            var condition = VisitSyntaxNode(switchStatementAst.Condition);

            var sections = new List <SwitchSection>();

            foreach (var clause in switchStatementAst.Clauses)
            {
                var cond = VisitSyntaxNode(clause.Item1);
                var body = VisitSyntaxNode(clause.Item2);

                var block = new Block(body, new Break());

                var section = new SwitchSection(new[] { cond }, new[] { block });

                sections.Add(section);
            }

            if (switchStatementAst.Default != null)
            {
                var body = VisitSyntaxNode(switchStatementAst.Default) as Block;

                var statements = body.Statements.ToList();
                statements.Add(new Break());

                var section = new SwitchSection(new[] { new IdentifierName("default") }, new[] { new Block(statements) });
                sections.Add(section);
            }


            _currentNode = new SwitchStatement(condition, sections);

            return(AstVisitAction.SkipChildren);
        }
Esempio n. 5
0
        static bool CollectSwitchSections(ICollection <SwitchSection> result, RefactoringContext context,
                                          IfElseStatement ifStatement, Expression switchExpr)
        {
            // if
            var section = new SwitchSection();

            if (!CollectCaseLabels(section.CaseLabels, context, ifStatement.Condition, switchExpr))
            {
                return(false);
            }
            CollectSwitchSectionStatements(section.Statements, context, ifStatement.TrueStatement);
            result.Add(section);

            if (ifStatement.FalseStatement.IsNull)
            {
                return(true);
            }

            // else if
            var falseStatement = ifStatement.FalseStatement as IfElseStatement;

            if (falseStatement != null)
            {
                return(CollectSwitchSections(result, context, falseStatement, switchExpr));
            }

            // else (default label)
            var defaultSection = new SwitchSection();

            defaultSection.CaseLabels.Add(new CaseLabel());
            CollectSwitchSectionStatements(defaultSection.Statements, context, ifStatement.FalseStatement);
            result.Add(defaultSection);

            return(true);
        }
Esempio n. 6
0
            public override void VisitSwitchSection(SwitchSection switchSection)
            {
                base.VisitSwitchSection(switchSection);

                if (switchSection.CaseLabels.Count < 2)
                {
                    return;
                }

                var lastLabel = switchSection.CaseLabels.LastOrNullObject();

                if (!lastLabel.Expression.IsNull)
                {
                    return;
                }
                AddIssue(switchSection.FirstChild.StartLocation, lastLabel.StartLocation,
                         ctx.TranslateString("Remove redundant 'case' label"), scipt => {
                    foreach (var label in switchSection.CaseLabels)
                    {
                        if (label != lastLabel)
                        {
                            scipt.Remove(label);
                        }
                    }
                });
            }
Esempio n. 7
0
        public override object VisitSwitchSection(SwitchSection switchSection, object data)
        {
            if (policy.IndentCaseBody)
            {
                curIndent.Level++;
            }

            foreach (CaseLabel label in switchSection.CaseLabels)
            {
                FixStatementIndentation(label.StartLocation);
            }
            if (policy.IndentSwitchBody)
            {
                curIndent.Level++;
            }

            foreach (ICSharpNode stmt in switchSection.Statements)
            {
                stmt.AcceptVisitor(this, null);
            }
            if (policy.IndentSwitchBody)
            {
                curIndent.Level--;
            }

            if (policy.IndentCaseBody)
            {
                curIndent.Level--;
            }
            return(null);
        }
Esempio n. 8
0
        public override AstNode VisitSwitchSection(SwitchSection switchSection, ICecilArgumentsResolver argumentsResolver)
        {
            switchSection.Statements.ForEach(s => s.AcceptVisitor(this, argumentsResolver));
            switchSection.CaseLabels.ForEach(c => c.AcceptVisitor(this, argumentsResolver));

            return(switchSection);
        }
Esempio n. 9
0
 public virtual void VisitSwitchSection(SwitchSection switchSection)
 {
     if (this.ThrowException)
     {
         throw (System.Exception) this.CreateException(switchSection);
     }
 }
Esempio n. 10
0
            public override void VisitSwitchSection(SwitchSection switchSection)
            {
                base.VisitSwitchSection(switchSection);

                var parent = switchSection.Parent as SwitchStatement;

                if (parent == null)
                {
                    return;
                }

                foreach (var curLabel in switchSection.CaseLabels)
                {
                    if (curLabel.Expression.IsNull)
                    {
                        continue;
                    }
                    var curValue = ctx.Resolve(curLabel.Expression).ConstantValue;
                    if (curValue == null)
                    {
                        continue;
                    }
                    foreach (var sect in parent.SwitchSections)
                    {
                        if (sect.CaseLabels.Any(label => label != curLabel && Equals(curValue, ctx.Resolve(label.Expression).ConstantValue)))
                        {
                            AddIssue(new CodeIssue(curLabel, string.Format(ctx.TranslateString("Duplicate case label value '{0}'"), curValue)));
                            break;
                        }
                    }
                }
            }
Esempio n. 11
0
 public JNode VisitSwitchSection(SwitchSection node)
 {
     return(new JSwitchSection
     {
         Labels = node.CaseLabels.Select(t => (JSwitchLabel)Visit(t)).ToList(),
         Statements = node.Statements.Select(VisitStatement).ToList(),
     });
 }
Esempio n. 12
0
 public override object VisitSwitchSection(SwitchSection switchSection, object data)
 {
     foreach (CaseLabel switchLabel in switchSection.SwitchLabels)
     {
         switchLabel.Parent = switchSection;
     }
     return(base.VisitSwitchSection(switchSection, data));
 }
            public override object VisitSwitchSection(SwitchSection switchSection, object data)
            {
                if(switchSection.CaseLabels.Any(a => a.Expression.IsNull))
                {
                    UnlockWith(switchSection);
                }

                return base.VisitSwitchSection(switchSection, data);
            }
Esempio n. 14
0
        public override void VisitSwitchSection(SwitchSection switchSection)
        {
            base.VisitSwitchSection(switchSection);

            if (!IsDefaultCase(switchSection))
            {
                BranchesCounter++;
            }
        }
Esempio n. 15
0
 public SwitchBlock(IEmitter emitter, SwitchSection switchSection, string varName, bool isFirst, bool isEnd)
     : base(emitter, switchSection)
 {
     this.Emitter       = emitter;
     this.SwitchSection = switchSection;
     varName_           = varName;
     isFirst_           = isFirst;
     isEnd_             = isEnd;
 }
Esempio n. 16
0
        public void InvalidVBSwitchStatementTest()
        {
            SwitchStatement switchStmt = ParseUtil.ParseStatement <SwitchStatement>("Select Case a\n Case \n End Select", true);

            Assert.AreEqual("a", ((IdentifierExpression)switchStmt.SwitchExpression).Identifier);
            SwitchSection sec = switchStmt.SwitchSections[0];

            Assert.AreEqual(0, sec.SwitchLabels.Count);
        }
Esempio n. 17
0
        protected void VisitSwitchSection()
        {
            SwitchSection switchSection = this.SwitchSection;

            switchSection.CaseLabels.ToList().ForEach(l => l.AcceptVisitor(this.Emitter));
            this.Indent();
            switchSection.Statements.ToList().ForEach(s => s.AcceptVisitor(this.Emitter));
            this.Outdent();
        }
 public override object Visit(SwitchSection node, object obj)
 {
     if (node.Location == ((AstNode)obj).Location || found)
     {
         found = true;
         return(this.table);
     }
     return(base.Visit(node, obj));
 }
            public override object VisitSwitchSection(SwitchSection switchSection, object data)
            {
                if (switchSection.CaseLabels.Any(a => a.Expression.IsNull))
                {
                    UnlockWith(switchSection);
                }

                return(base.VisitSwitchSection(switchSection, data));
            }
Esempio n. 20
0
 public SwitchBlock(IEmitter emitter, SwitchSection switchSection, string varName, bool isFirst, bool isEnd)
     : base(emitter, switchSection)
 {
     this.Emitter = emitter;
     this.SwitchSection = switchSection;
     varName_ = varName;
     isFirst_ = isFirst;
     isEnd_ = isEnd;
 }
Esempio n. 21
0
        /// <summary>
        /// Visits a <see cref="SwitchSection"/>, keeping track of the variables declared in <see cref="SwitchSection.Locals"/>.
        /// </summary>
        /// <param name="node">The expression to visit.</param>
        /// <returns>The result of visiting the expression.</returns>
        protected internal override SwitchSection VisitSwitchSection(SwitchSection node)
        {
            PushScope(node.Locals);

            var res = base.VisitSwitchSection(node);

            PopScope(node.Locals);

            return(res);
        }
Esempio n. 22
0
 public override object VisitSwitchSection(SwitchSection switchSection, object data)
 {
     if (language == SupportedLanguage.VBNet)
     {
         return(VisitBlockStatement(switchSection, data));
     }
     else
     {
         return(base.VisitSwitchSection(switchSection, data));
     }
 }
Esempio n. 23
0
        public Ust VisitSwitchBlockStatementGroup(JavaParser.SwitchBlockStatementGroupContext context)
        {
            Expression[] caseLabels = context.switchLabel().Select(label => (Expression)Visit(label))
                                      .Where(l => l != null).ToArray();
            Statement[] statements = context.blockStatement().Select(s => (Statement)Visit(s))
                                     .Where(s => s != null).ToArray();

            var result = new SwitchSection(caseLabels, statements, context.GetTextSpan());

            return(result);
        }
Esempio n. 24
0
        public virtual void VisitSwitchSection(SwitchSection node)
        {
            foreach (var label in node.Labels)
            {
                label.Accept(this);
            }

            foreach (var statement in node.Statements)
            {
                statement.Accept(this);
            }
        }
Esempio n. 25
0
        protected void VisitSwitchSection()
        {
            SwitchSection switchSection = this.SwitchSection;

            switchSection.CaseLabels.ToList().ForEach(l => l.AcceptVisitor(this.Emitter));
            this.Indent();

            var children = switchSection.Children.Where(c => c.Role == Roles.EmbeddedStatement || c.Role == Roles.Comment);

            children.ToList().ForEach(s => s.AcceptVisitor(this.Emitter));
            this.Outdent();
        }
Esempio n. 26
0
        public virtual object Visit(SwitchSection switchSection, object data)
        {
            Debug.Assert(switchSection != null);
            Debug.Assert(switchSection.SwitchLabels != null);

            foreach (CaseLabel label in switchSection.SwitchLabels)
            {
                Debug.Assert(label != null);
                label.AcceptVisitor(this, data);
            }
            return(switchSection.AcceptChildren(this, data));
        }
Esempio n. 27
0
        public override Ust VisitSwitchSection(SwitchSectionSyntax node)
        {
            var caseLabels = node.Labels.Select(s => (Expression)VisitAndReturnNullIfError(s)).ToArray();
            var statements = node.Statements.Select(s => (Statement)VisitAndReturnNullIfError(s)).ToArray();

            var result = new SwitchSection(
                caseLabels,
                statements,
                node.GetTextSpan());

            return(result);
        }
Esempio n. 28
0
 public override object VisitSwitchSection(SwitchSection switchSection, object data)
 {
     // Check if a 'break' should be auto inserted.
     if (switchSection.Children.Count == 0 ||
         !(switchSection.Children[switchSection.Children.Count - 1] is BreakStatement ||
           switchSection.Children[switchSection.Children.Count - 1] is ContinueStatement ||
           switchSection.Children[switchSection.Children.Count - 1] is ThrowStatement ||
           switchSection.Children[switchSection.Children.Count - 1] is ReturnStatement))
     {
         switchSection.Children.Add(new BreakStatement());
     }
     return(base.VisitSwitchSection(switchSection, data));
 }
Esempio n. 29
0
        public override int GetHashCode()
        {
            if (IsBlock)
            {
                return(Block.GetHashCode());
            }

            if (IsSwitchSection)
            {
                return(SwitchSection.GetHashCode());
            }

            return(0);
        }
Esempio n. 30
0
        public StatementContainer WithStatements(SyntaxList <StatementSyntax> statements)
        {
            if (IsBlock)
            {
                return(new StatementContainer(Block.WithStatements(statements)));
            }

            if (IsSwitchSection)
            {
                return(new StatementContainer(SwitchSection.WithStatements(statements)));
            }

            return(default(StatementContainer));
        }
Esempio n. 31
0
        public StatementContainer RemoveNode(SyntaxNode node, SyntaxRemoveOptions options)
        {
            if (IsBlock)
            {
                return(new StatementContainer(Block.RemoveNode(node, options)));
            }

            if (IsSwitchSection)
            {
                return(new StatementContainer(SwitchSection.RemoveNode(node, options)));
            }

            return(this);
        }
Esempio n. 32
0
        public StatementContainer ReplaceNode(SyntaxNode oldNode, SyntaxNode newNode)
        {
            if (IsBlock)
            {
                return(new StatementContainer(Block.ReplaceNode(oldNode, newNode)));
            }

            if (IsSwitchSection)
            {
                return(new StatementContainer(SwitchSection.ReplaceNode(oldNode, newNode)));
            }

            return(this);
        }
Esempio n. 33
0
			public override void VisitSwitchSection (SwitchSection switchSection)
			{
				base.VisitSwitchSection (switchSection);

				if (switchSection.CaseLabels.Count <2)
					return;

				var lastLabel = switchSection.CaseLabels.LastOrNullObject ();
				if (!lastLabel.Expression.IsNull)
					return;
				AddIssue (switchSection.FirstChild.StartLocation, lastLabel.StartLocation,
					ctx.TranslateString ("Remove redundant 'case' label"), scipt => {
						foreach (var label in switchSection.CaseLabels) {
							if (label != lastLabel)
								scipt.Remove (label);
						}
					});
			}
Esempio n. 34
0
		public override void VisitSwitchSection(SwitchSection switchSection)
		{
			if (policy.IndentSwitchBody) {
				curIndent.Push(IndentType.Block);
			}
			
			foreach (CaseLabel label in switchSection.CaseLabels) {
				FixStatementIndentation(label.StartLocation);
				label.AcceptVisitor(this);
			}
			if (policy.IndentCaseBody) {
				curIndent.Push(IndentType.Block);
			}
			
			foreach (var stmt in switchSection.Statements) {
				if (stmt is BreakStatement && !policy.IndentBreakStatements && policy.IndentCaseBody) {
					curIndent.Pop();
					FixStatementIndentation(stmt.StartLocation);
					stmt.AcceptVisitor(this);
					curIndent.Push(IndentType.Block);
					continue;
				}
				FixStatementIndentation(stmt.StartLocation);
				stmt.AcceptVisitor(this);
			}
			if (policy.IndentCaseBody) {
				curIndent.Pop ();
			}
			
			if (policy.IndentSwitchBody) {
				curIndent.Pop ();
			}
		}
 public virtual void VisitSwitchSection(SwitchSection switchSection)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(switchSection);
     }
 }
Esempio n. 36
0
 public abstract StringBuilder VisitSwitchSection(SwitchSection switchSection, int data);
Esempio n. 37
0
 public override void VisitSwitchSection(SwitchSection switchSection)
 {
     //new SwitchBlock(this, switchSection).Emit();
     throw new System.NotSupportedException();
 }
Esempio n. 38
0
	void EmbeddedStatement(
#line  2755 "VBNET.ATG" 
out Statement statement) {

#line  2757 "VBNET.ATG" 
		Statement embeddedStatement = null;
		statement = null;
		Expression expr = null;
		string name = String.Empty;
		List<Expression> p = null;
		
		if (la.kind == 107) {
			lexer.NextToken();

#line  2763 "VBNET.ATG" 
			ExitType exitType = ExitType.None; 
			switch (la.kind) {
			case 195: {
				lexer.NextToken();

#line  2765 "VBNET.ATG" 
				exitType = ExitType.Sub; 
				break;
			}
			case 114: {
				lexer.NextToken();

#line  2767 "VBNET.ATG" 
				exitType = ExitType.Function; 
				break;
			}
			case 171: {
				lexer.NextToken();

#line  2769 "VBNET.ATG" 
				exitType = ExitType.Property; 
				break;
			}
			case 95: {
				lexer.NextToken();

#line  2771 "VBNET.ATG" 
				exitType = ExitType.Do; 
				break;
			}
			case 111: {
				lexer.NextToken();

#line  2773 "VBNET.ATG" 
				exitType = ExitType.For; 
				break;
			}
			case 203: {
				lexer.NextToken();

#line  2775 "VBNET.ATG" 
				exitType = ExitType.Try; 
				break;
			}
			case 216: {
				lexer.NextToken();

#line  2777 "VBNET.ATG" 
				exitType = ExitType.While; 
				break;
			}
			case 182: {
				lexer.NextToken();

#line  2779 "VBNET.ATG" 
				exitType = ExitType.Select; 
				break;
			}
			default: SynErr(273); break;
			}

#line  2781 "VBNET.ATG" 
			statement = new ExitStatement(exitType); 
		} else if (la.kind == 203) {
			TryStatement(
#line  2782 "VBNET.ATG" 
out statement);
		} else if (la.kind == 76) {
			lexer.NextToken();

#line  2783 "VBNET.ATG" 
			ContinueType continueType = ContinueType.None; 
			if (la.kind == 95 || la.kind == 111 || la.kind == 216) {
				if (la.kind == 95) {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.Do; 
				} else if (la.kind == 111) {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.For; 
				} else {
					lexer.NextToken();

#line  2783 "VBNET.ATG" 
					continueType = ContinueType.While; 
				}
			}

#line  2783 "VBNET.ATG" 
			statement = new ContinueStatement(continueType); 
		} else if (la.kind == 200) {
			lexer.NextToken();
			if (StartOf(29)) {
				Expr(
#line  2785 "VBNET.ATG" 
out expr);
			}

#line  2785 "VBNET.ATG" 
			statement = new ThrowStatement(expr); 
		} else if (la.kind == 180) {
			lexer.NextToken();
			if (StartOf(29)) {
				Expr(
#line  2787 "VBNET.ATG" 
out expr);
			}

#line  2787 "VBNET.ATG" 
			statement = new ReturnStatement(expr); 
		} else if (la.kind == 196) {
			lexer.NextToken();
			Expr(
#line  2789 "VBNET.ATG" 
out expr);
			EndOfStmt();
			Block(
#line  2789 "VBNET.ATG" 
out embeddedStatement);
			Expect(100);
			Expect(196);

#line  2790 "VBNET.ATG" 
			statement = new LockStatement(expr, embeddedStatement); 
		} else if (la.kind == 174) {
			lexer.NextToken();
			Identifier();

#line  2792 "VBNET.ATG" 
			name = t.val; 
			if (la.kind == 25) {
				lexer.NextToken();
				if (StartOf(37)) {
					ArgumentList(
#line  2793 "VBNET.ATG" 
out p);
				}
				Expect(26);
			}

#line  2795 "VBNET.ATG" 
			statement = new RaiseEventStatement(name, p);
			
		} else if (la.kind == 218) {
			WithStatement(
#line  2798 "VBNET.ATG" 
out statement);
		} else if (la.kind == 43) {
			lexer.NextToken();

#line  2800 "VBNET.ATG" 
			Expression handlerExpr = null; 
			Expr(
#line  2801 "VBNET.ATG" 
out expr);
			Expect(12);
			Expr(
#line  2801 "VBNET.ATG" 
out handlerExpr);

#line  2803 "VBNET.ATG" 
			statement = new AddHandlerStatement(expr, handlerExpr);
			
		} else if (la.kind == 178) {
			lexer.NextToken();

#line  2806 "VBNET.ATG" 
			Expression handlerExpr = null; 
			Expr(
#line  2807 "VBNET.ATG" 
out expr);
			Expect(12);
			Expr(
#line  2807 "VBNET.ATG" 
out handlerExpr);

#line  2809 "VBNET.ATG" 
			statement = new RemoveHandlerStatement(expr, handlerExpr);
			
		} else if (la.kind == 216) {
			lexer.NextToken();
			Expr(
#line  2812 "VBNET.ATG" 
out expr);
			EndOfStmt();
			Block(
#line  2813 "VBNET.ATG" 
out embeddedStatement);
			Expect(100);
			Expect(216);

#line  2815 "VBNET.ATG" 
			statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);
			
		} else if (la.kind == 95) {
			lexer.NextToken();

#line  2820 "VBNET.ATG" 
			ConditionType conditionType = ConditionType.None;
			
			if (la.kind == 209 || la.kind == 216) {
				WhileOrUntil(
#line  2823 "VBNET.ATG" 
out conditionType);
				Expr(
#line  2823 "VBNET.ATG" 
out expr);
				EndOfStmt();
				Block(
#line  2824 "VBNET.ATG" 
out embeddedStatement);
				Expect(138);

#line  2827 "VBNET.ATG" 
				statement = new DoLoopStatement(expr, 
				                               embeddedStatement, 
				                               conditionType == ConditionType.While ? ConditionType.DoWhile : conditionType, 
				                               ConditionPosition.Start);
				
			} else if (la.kind == 1 || la.kind == 11) {
				EndOfStmt();
				Block(
#line  2834 "VBNET.ATG" 
out embeddedStatement);
				Expect(138);
				if (la.kind == 209 || la.kind == 216) {
					WhileOrUntil(
#line  2835 "VBNET.ATG" 
out conditionType);
					Expr(
#line  2835 "VBNET.ATG" 
out expr);
				}

#line  2837 "VBNET.ATG" 
				statement = new DoLoopStatement(expr, embeddedStatement, conditionType, ConditionPosition.End);
				
			} else SynErr(274);
		} else if (la.kind == 111) {
			lexer.NextToken();

#line  2842 "VBNET.ATG" 
			Expression group = null;
			TypeReference typeReference;
			string        typeName;
			Location startLocation = t.Location;
			
			if (la.kind == 97) {
				lexer.NextToken();
				LoopControlVariable(
#line  2849 "VBNET.ATG" 
out typeReference, out typeName);
				Expect(125);
				Expr(
#line  2850 "VBNET.ATG" 
out group);
				EndOfStmt();
				Block(
#line  2851 "VBNET.ATG" 
out embeddedStatement);
				Expect(149);
				if (StartOf(29)) {
					Expr(
#line  2852 "VBNET.ATG" 
out expr);
				}

#line  2854 "VBNET.ATG" 
				statement = new ForeachStatement(typeReference, 
				                                typeName,
				                                group, 
				                                embeddedStatement, 
				                                expr);
				statement.StartLocation = startLocation;
				statement.EndLocation   = t.EndLocation;
				
				
			} else if (StartOf(38)) {

#line  2865 "VBNET.ATG" 
				Expression start = null;
				Expression end = null;
				Expression step = null;
				Expression variableExpr = null;
				Expression nextExpr = null;
				List<Expression> nextExpressions = null;
				
				if (
#line  2872 "VBNET.ATG" 
IsLoopVariableDeclaration()) {
					LoopControlVariable(
#line  2873 "VBNET.ATG" 
out typeReference, out typeName);
				} else {

#line  2875 "VBNET.ATG" 
					typeReference = null; typeName = null; 
					SimpleExpr(
#line  2876 "VBNET.ATG" 
out variableExpr);
				}
				Expect(10);
				Expr(
#line  2878 "VBNET.ATG" 
out start);
				Expect(201);
				Expr(
#line  2878 "VBNET.ATG" 
out end);
				if (la.kind == 190) {
					lexer.NextToken();
					Expr(
#line  2878 "VBNET.ATG" 
out step);
				}
				EndOfStmt();
				Block(
#line  2879 "VBNET.ATG" 
out embeddedStatement);
				Expect(149);
				if (StartOf(29)) {
					Expr(
#line  2882 "VBNET.ATG" 
out nextExpr);

#line  2884 "VBNET.ATG" 
					nextExpressions = new List<Expression>();
					nextExpressions.Add(nextExpr);
					
					while (la.kind == 12) {
						lexer.NextToken();
						Expr(
#line  2887 "VBNET.ATG" 
out nextExpr);

#line  2887 "VBNET.ATG" 
						nextExpressions.Add(nextExpr); 
					}
				}

#line  2890 "VBNET.ATG" 
				statement = new ForNextStatement {
				TypeReference = typeReference,
				VariableName = typeName, 
				LoopVariableExpression = variableExpr,
				Start = start, 
				End = end, 
				Step = step, 
				EmbeddedStatement = embeddedStatement, 
				NextExpressions = nextExpressions
				};
				
			} else SynErr(275);
		} else if (la.kind == 105) {
			lexer.NextToken();
			Expr(
#line  2903 "VBNET.ATG" 
out expr);

#line  2903 "VBNET.ATG" 
			statement = new ErrorStatement(expr); 
		} else if (la.kind == 176) {
			lexer.NextToken();

#line  2905 "VBNET.ATG" 
			bool isPreserve = false; 
			if (la.kind == 169) {
				lexer.NextToken();

#line  2905 "VBNET.ATG" 
				isPreserve = true; 
			}
			ReDimClause(
#line  2906 "VBNET.ATG" 
out expr);

#line  2908 "VBNET.ATG" 
			ReDimStatement reDimStatement = new ReDimStatement(isPreserve);
			statement = reDimStatement;
			SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression);
			
			while (la.kind == 12) {
				lexer.NextToken();
				ReDimClause(
#line  2912 "VBNET.ATG" 
out expr);

#line  2913 "VBNET.ATG" 
				SafeAdd(reDimStatement, reDimStatement.ReDimClauses, expr as InvocationExpression); 
			}
		} else if (la.kind == 104) {
			lexer.NextToken();
			Expr(
#line  2917 "VBNET.ATG" 
out expr);

#line  2919 "VBNET.ATG" 
			EraseStatement eraseStatement = new EraseStatement();
			if (expr != null) { SafeAdd(eraseStatement, eraseStatement.Expressions, expr);}
			
			while (la.kind == 12) {
				lexer.NextToken();
				Expr(
#line  2922 "VBNET.ATG" 
out expr);

#line  2922 "VBNET.ATG" 
				if (expr != null) { SafeAdd(eraseStatement, eraseStatement.Expressions, expr); }
			}

#line  2923 "VBNET.ATG" 
			statement = eraseStatement; 
		} else if (la.kind == 191) {
			lexer.NextToken();

#line  2925 "VBNET.ATG" 
			statement = new StopStatement(); 
		} else if (
#line  2927 "VBNET.ATG" 
la.kind == Tokens.If) {
			Expect(122);

#line  2928 "VBNET.ATG" 
			Location ifStartLocation = t.Location; 
			Expr(
#line  2928 "VBNET.ATG" 
out expr);
			if (la.kind == 199) {
				lexer.NextToken();
			}
			if (la.kind == 1 || la.kind == 11) {
				EndOfStmt();
				Block(
#line  2931 "VBNET.ATG" 
out embeddedStatement);

#line  2933 "VBNET.ATG" 
				IfElseStatement ifStatement = new IfElseStatement(expr, embeddedStatement);
				ifStatement.StartLocation = ifStartLocation;
				Location elseIfStart;
				
				while (la.kind == 99 || 
#line  2939 "VBNET.ATG" 
IsElseIf()) {
					if (
#line  2939 "VBNET.ATG" 
IsElseIf()) {
						Expect(98);

#line  2939 "VBNET.ATG" 
						elseIfStart = t.Location; 
						Expect(122);
					} else {
						lexer.NextToken();

#line  2940 "VBNET.ATG" 
						elseIfStart = t.Location; 
					}

#line  2942 "VBNET.ATG" 
					Expression condition = null; Statement block = null; 
					Expr(
#line  2943 "VBNET.ATG" 
out condition);
					if (la.kind == 199) {
						lexer.NextToken();
					}
					EndOfStmt();
					Block(
#line  2944 "VBNET.ATG" 
out block);

#line  2946 "VBNET.ATG" 
					ElseIfSection elseIfSection = new ElseIfSection(condition, block);
					elseIfSection.StartLocation = elseIfStart;
					elseIfSection.EndLocation = t.Location;
					elseIfSection.Parent = ifStatement;
					ifStatement.ElseIfSections.Add(elseIfSection);
					
				}
				if (la.kind == 98) {
					lexer.NextToken();
					EndOfStmt();
					Block(
#line  2955 "VBNET.ATG" 
out embeddedStatement);

#line  2957 "VBNET.ATG" 
					ifStatement.FalseStatement.Add(embeddedStatement);
					
				}
				Expect(100);
				Expect(122);

#line  2961 "VBNET.ATG" 
				ifStatement.EndLocation = t.Location;
				statement = ifStatement;
				
			} else if (StartOf(39)) {

#line  2966 "VBNET.ATG" 
				IfElseStatement ifStatement = new IfElseStatement(expr);
				ifStatement.StartLocation = ifStartLocation;
				
				SingleLineStatementList(
#line  2969 "VBNET.ATG" 
ifStatement.TrueStatement);
				if (la.kind == 98) {
					lexer.NextToken();
					if (StartOf(39)) {
						SingleLineStatementList(
#line  2972 "VBNET.ATG" 
ifStatement.FalseStatement);
					}
				}

#line  2974 "VBNET.ATG" 
				ifStatement.EndLocation = t.Location; statement = ifStatement; 
			} else SynErr(276);
		} else if (la.kind == 182) {
			lexer.NextToken();
			if (la.kind == 61) {
				lexer.NextToken();
			}
			Expr(
#line  2977 "VBNET.ATG" 
out expr);
			EndOfStmt();

#line  2978 "VBNET.ATG" 
			List<SwitchSection> selectSections = new List<SwitchSection>();
			Statement block = null;
			
			while (la.kind == 61) {

#line  2982 "VBNET.ATG" 
				List<CaseLabel> caseClauses = null; Location caseLocation = la.Location; 
				lexer.NextToken();
				CaseClauses(
#line  2983 "VBNET.ATG" 
out caseClauses);
				if (
#line  2983 "VBNET.ATG" 
IsNotStatementSeparator()) {
					lexer.NextToken();
				}
				EndOfStmt();

#line  2985 "VBNET.ATG" 
				SwitchSection selectSection = new SwitchSection(caseClauses);
				selectSection.StartLocation = caseLocation;
				
				Block(
#line  2988 "VBNET.ATG" 
out block);

#line  2990 "VBNET.ATG" 
				selectSection.Children = block.Children;
				selectSection.EndLocation = t.EndLocation;
				selectSections.Add(selectSection);
				
			}

#line  2996 "VBNET.ATG" 
			statement = new SwitchStatement(expr, selectSections);
			
			Expect(100);
			Expect(182);
		} else if (la.kind == 157) {

#line  2999 "VBNET.ATG" 
			OnErrorStatement onErrorStatement = null; 
			OnErrorStatement(
#line  3000 "VBNET.ATG" 
out onErrorStatement);

#line  3000 "VBNET.ATG" 
			statement = onErrorStatement; 
		} else if (la.kind == 119) {

#line  3001 "VBNET.ATG" 
			GotoStatement goToStatement = null; 
			GotoStatement(
#line  3002 "VBNET.ATG" 
out goToStatement);

#line  3002 "VBNET.ATG" 
			statement = goToStatement; 
		} else if (la.kind == 179) {

#line  3003 "VBNET.ATG" 
			ResumeStatement resumeStatement = null; 
			ResumeStatement(
#line  3004 "VBNET.ATG" 
out resumeStatement);

#line  3004 "VBNET.ATG" 
			statement = resumeStatement; 
		} else if (StartOf(38)) {

#line  3007 "VBNET.ATG" 
			Expression val = null;
			AssignmentOperatorType op;
			
			bool mustBeAssignment = la.kind == Tokens.Plus  || la.kind == Tokens.Minus ||
			                        la.kind == Tokens.Not   || la.kind == Tokens.Times;
			
			SimpleExpr(
#line  3013 "VBNET.ATG" 
out expr);
			if (StartOf(40)) {
				AssignmentOperator(
#line  3015 "VBNET.ATG" 
out op);
				Expr(
#line  3015 "VBNET.ATG" 
out val);

#line  3015 "VBNET.ATG" 
				expr = new AssignmentExpression(expr, op, val); 
			} else if (la.kind == 1 || la.kind == 11 || la.kind == 98) {

#line  3016 "VBNET.ATG" 
				if (mustBeAssignment) Error("error in assignment."); 
			} else SynErr(277);

#line  3019 "VBNET.ATG" 
			// a field reference expression that stands alone is a
			// invocation expression without parantheses and arguments
			if(expr is MemberReferenceExpression || expr is IdentifierExpression) {
				expr = new InvocationExpression(expr);
			}
			statement = new ExpressionStatement(expr);
			
		} else if (la.kind == 60) {
			lexer.NextToken();
			SimpleExpr(
#line  3026 "VBNET.ATG" 
out expr);

#line  3026 "VBNET.ATG" 
			statement = new ExpressionStatement(expr); 
		} else if (la.kind == 211) {
			lexer.NextToken();

#line  3028 "VBNET.ATG" 
			Statement block;  
			if (
#line  3029 "VBNET.ATG" 
Peek(1).kind == Tokens.As) {

#line  3030 "VBNET.ATG" 
				LocalVariableDeclaration resourceAquisition = new LocalVariableDeclaration(Modifiers.None); 
				VariableDeclarator(
#line  3031 "VBNET.ATG" 
resourceAquisition.Variables);
				while (la.kind == 12) {
					lexer.NextToken();
					VariableDeclarator(
#line  3033 "VBNET.ATG" 
resourceAquisition.Variables);
				}
				Block(
#line  3035 "VBNET.ATG" 
out block);

#line  3037 "VBNET.ATG" 
				statement = new UsingStatement(resourceAquisition, block);
				
			} else if (StartOf(29)) {
				Expr(
#line  3039 "VBNET.ATG" 
out expr);
				Block(
#line  3040 "VBNET.ATG" 
out block);

#line  3041 "VBNET.ATG" 
				statement = new UsingStatement(new ExpressionStatement(expr), block); 
			} else SynErr(278);
			Expect(100);
			Expect(211);
		} else if (StartOf(41)) {
			LocalDeclarationStatement(
#line  3044 "VBNET.ATG" 
out statement);
		} else SynErr(279);
	}
Esempio n. 39
0
		IEnumerable<Statement> TransformNode(ILNode node)
		{
			if (node is ILLabel) {
				yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
			} else if (node is ILExpression) {
				List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
				AstNode codeExpr = TransformExpression((ILExpression)node);
				if (codeExpr != null) {
					codeExpr = codeExpr.WithAnnotation(ilRanges);
					if (codeExpr is Ast.Expression) {
						yield return new Ast.ExpressionStatement { Expression = (Ast.Expression)codeExpr };
					} else if (codeExpr is Ast.Statement) {
						yield return (Ast.Statement)codeExpr;
					} else {
						throw new Exception();
					}
				}
			} else if (node is ILWhileLoop) {
				ILWhileLoop ilLoop = (ILWhileLoop)node;
				WhileStatement whileStmt = new WhileStatement() {
					Condition = ilLoop.Condition != null ? (Expression)TransformExpression(ilLoop.Condition) : new PrimitiveExpression(true),
					EmbeddedStatement = TransformBlock(ilLoop.BodyBlock)
				};
				yield return whileStmt;
			} else if (node is ILCondition) {
				ILCondition conditionalNode = (ILCondition)node;
				bool hasFalseBlock = conditionalNode.FalseBlock.EntryGoto != null || conditionalNode.FalseBlock.Body.Count > 0;
				yield return new Ast.IfElseStatement {
					Condition = (Expression)TransformExpression(conditionalNode.Condition),
					TrueStatement = TransformBlock(conditionalNode.TrueBlock),
					FalseStatement = hasFalseBlock ? TransformBlock(conditionalNode.FalseBlock) : null
				};
			} else if (node is ILSwitch) {
				ILSwitch ilSwitch = (ILSwitch)node;
				SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition) };
				foreach (var caseBlock in ilSwitch.CaseBlocks) {
					SwitchSection section = new SwitchSection();
					if (caseBlock.Values != null) {
						section.CaseLabels.AddRange(caseBlock.Values.Select(i => new CaseLabel() { Expression = AstBuilder.MakePrimitive(i, ilSwitch.Condition.InferredType) }));
					} else {
						section.CaseLabels.Add(new CaseLabel());
					}
					section.Statements.Add(TransformBlock(caseBlock));
					switchStmt.SwitchSections.Add(section);
				}
				yield return switchStmt;
			} else if (node is ILTryCatchBlock) {
				ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
				var tryCatchStmt = new Ast.TryCatchStatement();
				tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
				foreach (var catchClause in tryCatchNode.CatchBlocks) {
					if (catchClause.ExceptionVariable == null
					    && (catchClause.ExceptionType == null || catchClause.ExceptionType.MetadataType == MetadataType.Object))
					{
						tryCatchStmt.CatchClauses.Add(new Ast.CatchClause { Body = TransformBlock(catchClause) });
					} else {
						tryCatchStmt.CatchClauses.Add(
							new Ast.CatchClause {
								Type = AstBuilder.ConvertType(catchClause.ExceptionType),
								VariableName = catchClause.ExceptionVariable == null ? null : catchClause.ExceptionVariable.Name,
								Body = TransformBlock(catchClause)
							});
					}
				}
				if (tryCatchNode.FinallyBlock != null)
					tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock);
				if (tryCatchNode.FaultBlock != null) {
					CatchClause cc = new CatchClause();
					cc.Body = TransformBlock(tryCatchNode.FaultBlock);
					cc.Body.Add(new ThrowStatement()); // rethrow
					tryCatchStmt.CatchClauses.Add(cc);
				}
				yield return tryCatchStmt;
			} else if (node is ILFixedStatement) {
				ILFixedStatement fixedNode = (ILFixedStatement)node;
				FixedStatement fixedStatement = new FixedStatement();
				foreach (ILExpression initializer in fixedNode.Initializers) {
					Debug.Assert(initializer.Code == ILCode.Stloc);
					ILVariable v = (ILVariable)initializer.Operand;
					fixedStatement.Variables.Add(
						new VariableInitializer {
							Name = v.Name,
							Initializer = (Expression)TransformExpression(initializer.Arguments[0])
						}.WithAnnotation(v));
				}
				fixedStatement.Type = AstBuilder.ConvertType(((ILVariable)fixedNode.Initializers[0].Operand).Type);
				fixedStatement.EmbeddedStatement = TransformBlock(fixedNode.BodyBlock);
				yield return fixedStatement;
			} else if (node is ILBlock) {
				yield return TransformBlock((ILBlock)node);
			} else {
				throw new Exception("Unknown node type");
			}
		}
Esempio n. 40
0
 public SwitchBlock(IEmitter emitter, SwitchSection switchSection)
     : base(emitter, switchSection)
 {
     this.Emitter = emitter;
     this.SwitchSection = switchSection;
 }
Esempio n. 41
0
        public override StringBuilder VisitSwitchSection(SwitchSection switchSection, int data)
        {
            var result = new StringBuilder();

            foreach (var label in switchSection.CaseLabels)
            {
                result.Append(Indent(label, label.AcceptVisitor(this, data)));
                result.Append(Environment.NewLine);
            }

            result.Append(Environment.NewLine).Append("{");

            foreach (var stmt in switchSection.Statements)
                result.Append(Environment.NewLine).Append(Indent(stmt, stmt.AcceptVisitor(this, data)));

            result.Append(Environment.NewLine).Append("}");

            return result;
        }
Esempio n. 42
0
		public override object VisitSwitchSection(SwitchSection switchSection, object data)
		{
			if (language == SupportedLanguage.VBNet) {
				return VisitBlockStatement(switchSection, data);
			} else {
				return base.VisitSwitchSection(switchSection, data);
			}
		}
Esempio n. 43
0
		public virtual void VisitSwitchSection(SwitchSection switchSection)
		{
			StartNode(switchSection);
			bool first = true;
			int count = 0;
			foreach (var label in switchSection.CaseLabels) {
				if (count-- <= 0) {
					cancellationToken.ThrowIfCancellationRequested();
					count = CANCEL_CHECK_LOOP_COUNT;
				}
				if (!first) {
					NewLine();
				}
				label.AcceptVisitor(this);
				first = false;
			}
			bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
			if (policy.IndentCaseBody && !isBlock) {
				writer.Indent();
			}
			
			if (!isBlock)
				NewLine();

			count = 0;
			foreach (var statement in switchSection.Statements) {
				if (count-- <= 0) {
					cancellationToken.ThrowIfCancellationRequested();
					count = CANCEL_CHECK_LOOP_COUNT;
				}
				statement.AcceptVisitor(this);
			}
			
			if (policy.IndentCaseBody && !isBlock) {
				writer.Unindent();
			}
			
			EndNode(switchSection);
		}
		IEnumerable<Statement> TransformNode(ILNode node)
		{
			if (node is ILLabel) {
				yield return new LabelStatement { Label = ((ILLabel)node).Name };
			} else if (node is ILExpression) {
				List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
				AstNode codeExpr = TransformExpression((ILExpression)node);
				if (codeExpr != null) {
					codeExpr = codeExpr.WithAnnotation(ilRanges);
					if (codeExpr is Expression) {
						yield return new ExpressionStatement { Expression = (Expression)codeExpr };
					} else if (codeExpr is Statement) {
						yield return (Statement)codeExpr;
					} else {
						throw new Exception();
					}
				}
			} else if (node is ILWhileLoop) {
				ILWhileLoop ilLoop = (ILWhileLoop)node;
				WhileStatement whileStmt = new WhileStatement() {
					Condition = ilLoop.Condition != null ? (Expression)TransformExpression(ilLoop.Condition) : new PrimitiveExpression(true),
					EmbeddedStatement = TransformBlock(ilLoop.BodyBlock)
				};
				yield return whileStmt;
			} else if (node is ILCondition) {
				ILCondition conditionalNode = (ILCondition)node;
				bool hasFalseBlock = conditionalNode.FalseBlock.EntryGoto != null || conditionalNode.FalseBlock.Body.Count > 0;
				yield return new IfElseStatement {
					Condition = (Expression)TransformExpression(conditionalNode.Condition),
					TrueStatement = TransformBlock(conditionalNode.TrueBlock),
					FalseStatement = hasFalseBlock ? TransformBlock(conditionalNode.FalseBlock) : null
				};
			} else if (node is ILSwitch) {
				ILSwitch ilSwitch = (ILSwitch)node;
				if (TypeAnalysis.IsBoolean(ilSwitch.Condition.InferredType) && (
					from cb in ilSwitch.CaseBlocks
					where cb.Values != null
					from val in cb.Values
					select val
				).Any(val => val != 0 && val != 1))
				{
					// If switch cases contain values other then 0 and 1, force the condition to be non-boolean
					ilSwitch.Condition.ExpectedType = typeSystem.Int32;
				}
				SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition) };
				foreach (var caseBlock in ilSwitch.CaseBlocks) {
					SwitchSection section = new SwitchSection();
					if (caseBlock.Values != null) {
						section.CaseLabels.AddRange(caseBlock.Values.Select(i => new CaseLabel() { Expression = AstBuilder.MakePrimitive(i, ilSwitch.Condition.ExpectedType ?? ilSwitch.Condition.InferredType) }));
					} else {
						section.CaseLabels.Add(new CaseLabel());
					}
					section.Statements.Add(TransformBlock(caseBlock));
					switchStmt.SwitchSections.Add(section);
				}
				yield return switchStmt;
			} else if (node is ILTryCatchBlock) {
				ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
				var tryCatchStmt = new TryCatchStatement();
				tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
				foreach (var catchClause in tryCatchNode.CatchBlocks) {
					CatchClause clause = new CatchClause { Body = TransformBlock(catchClause) };
					if (catchClause.ExceptionVariable != null
					    || (catchClause.ExceptionType != null && !catchClause.ExceptionType.IsCorLibType("System", "Object")))
					{
						clause.Type = AstBuilder.ConvertType(catchClause.ExceptionType);
						clause.VariableName = catchClause.ExceptionVariable == null ? null : catchClause.ExceptionVariable.Name;
						clause.AddAnnotation(catchClause.ExceptionVariable);
					}
					if (catchClause.FilterBlock != null) {
						clause.Filter = new FilterClause { 
							Expression = new LambdaExpression { 
								Body = TransformBlock(catchClause.FilterBlock) 
							}.WithAnnotation(new FilterClauseAnnotation())
						};
					}
					tryCatchStmt.CatchClauses.Add(clause);
				}
				if (tryCatchNode.FinallyBlock != null)
					tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock);
				if (tryCatchNode.FaultBlock != null) {
					CatchClause cc = new CatchClause();
					cc.Body = TransformBlock(tryCatchNode.FaultBlock);
					cc.Body.Add(new ThrowStatement()); // rethrow
					tryCatchStmt.CatchClauses.Add(cc);
				}
				yield return tryCatchStmt;
			} else if (node is ILFixedStatement) {
				ILFixedStatement fixedNode = (ILFixedStatement)node;
				FixedStatement fixedStatement = new FixedStatement();
				foreach (ILExpression initializer in fixedNode.Initializers) {
					Debug.Assert(initializer.Code == ILCode.Stloc);
					ILVariable v = (ILVariable)initializer.Operand;
					fixedStatement.Variables.Add(
						new VariableInitializer {
							Name = v.Name,
							Initializer = (Expression)TransformExpression(initializer.Arguments[0])
						}.WithAnnotation(v));
				}
				fixedStatement.Type = AstBuilder.ConvertType(((ILVariable)fixedNode.Initializers[0].Operand).Type);
				fixedStatement.EmbeddedStatement = TransformBlock(fixedNode.BodyBlock);
				yield return fixedStatement;
			} else if (node is ILBlock) {
				yield return TransformBlock((ILBlock)node);
			} else {
				throw new Exception("Unknown node type");
			}
		}
Esempio n. 45
0
		public void VisitSwitchSection(SwitchSection switchSection)
		{
			StartNode(switchSection);
			bool first = true;
			foreach (var label in switchSection.CaseLabels) {
				if (!first) {
					NewLine();
				}
				label.AcceptVisitor(this);
				first = false;
			}
			bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
			if (policy.IndentCaseBody && !isBlock) {
				formatter.Indent();
			}
			
			if (!isBlock)
				NewLine();
			
			foreach (var statement in switchSection.Statements) {
				statement.AcceptVisitor(this);
			}
			
			if (policy.IndentCaseBody && !isBlock) {
				formatter.Unindent();
			}
			
			EndNode(switchSection);
		}
Esempio n. 46
0
        // 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);
        }
Esempio n. 47
0
//-----------------------------------------------------------------------------
// Parse a Switch-case statement
// --> 'switch' '(' exp ')' '{' body '}'
// body -> section +
//-----------------------------------------------------------------------------
    protected Statement ParseSwitchStatement()
    {
        ReadExpectedToken(Token.Type.cSwitch);
        
        ReadExpectedToken(Token.Type.cLParen);
        Exp expTest = ParseExp();
        ReadExpectedToken(Token.Type.cRParen);
        
        ReadExpectedToken(Token.Type.cLCurly);
    
        // Parse sections
        ArrayList al = new ArrayList();
        
        Token t = m_lexer.PeekNextToken();
        while(t.TokenType != Token.Type.cRCurly)
        {
            SwitchSection section = ParseSwitchSection();    
            al.Add(section);        
            t = m_lexer.PeekNextToken();
        }
        ReadExpectedToken(Token.Type.cRCurly);
    
        
        SwitchSection [] sections = new SwitchSection[al.Count];
        for(int i = 0; i < sections.Length; i++)
            sections[i] = (SwitchSection) al[i];
            
        Statement s = new SwitchStatement(expTest, sections);
        
        return s;
    }
Esempio n. 48
0
		public void VisitSwitchSection(SwitchSection switchSection)
		{
			StartNode(switchSection);
			bool first = true;
			foreach (var label in switchSection.CaseLabels) {
				if (!first) {
					NewLine();
				}
				label.AcceptVisitor(this);
				first = false;
			}
			if (policy.IndentCaseBody) {
				formatter.Indent();
			}
			
			foreach (var statement in switchSection.Statements) {
				NewLine();
				statement.AcceptVisitor(this);
			}
			
			if (policy.IndentCaseBody) {
				formatter.Unindent();
			}
			
			EndNode(switchSection);
		}
Esempio n. 49
0
//-----------------------------------------------------------------------------    
// section -> ('case' exp ':')+ statement
//           |'default' ':' statement    
//-----------------------------------------------------------------------------
    protected SwitchSection ParseSwitchSection()
    {
        Token t = m_lexer.PeekNextToken();
        SwitchSection c;
        
        // Handle 'default' label
        if (t.TokenType == Token.Type.cDefault)
        {
            ConsumeNextToken();
            ReadExpectedToken(Token.Type.cColon);
            //Statement s = ParseStatement();
            Statement s = ParseStatementList();
            c = new SwitchSection(s);
        }
        
        else {
            // Handle 'case' label
            ArrayList al = new ArrayList();
            
            while (t.TokenType == Token.Type.cCase)
            {
                ConsumeNextToken();
                Exp e = ParseExp();
                ReadExpectedToken(Token.Type.cColon);
                al.Add(e);
                t = m_lexer.PeekNextToken();
            }
            
            //Statement stmt = ParseStatement();
            Statement s = ParseStatementList();
            
            Exp [] eList = new Exp[al.Count];
            for(int i = 0; i < eList.Length; i++)
                eList[i] = (Exp) al[i];
            
            c = new SwitchSection(eList, s);
        }
        return c;
    }
Esempio n. 50
0
        public void VisitSwitchSection(SwitchSection switchSection)
        {
            Formatter.StartNode(switchSection);

            WriteNodes(switchSection.Labels, true);
            Formatter.WriteLine();
            Formatter.Indent();
            WriteNodes(switchSection.Statements, true);
            Formatter.Unindent();

            Formatter.EndNode();
        }
Esempio n. 51
0
		IEnumerable<Statement> TransformNode(ILNode node)
		{
			if (node is ILLabel) {
				yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
			} else if (node is ILExpression) {
				List<ILRange> ilRanges = ((ILExpression)node).GetILRanges();
				AstNode codeExpr = TransformExpression((ILExpression)node);
				if (codeExpr != null) {
					codeExpr = codeExpr.WithAnnotation(ilRanges);
					if (codeExpr is Ast.Expression) {
						yield return new Ast.ExpressionStatement { Expression = (Ast.Expression)codeExpr };
					} else if (codeExpr is Ast.Statement) {
						yield return (Ast.Statement)codeExpr;
					} else {
						throw new Exception();
					}
				}
			} else if (node is ILWhileLoop) {
				ILWhileLoop ilLoop = (ILWhileLoop)node;
				WhileStatement whileStmt = new WhileStatement() {
					Condition = ilLoop.Condition != null ? (Expression)TransformExpression(ilLoop.Condition) : new PrimitiveExpression(true),
					EmbeddedStatement = TransformBlock(ilLoop.BodyBlock)
				};
				yield return whileStmt;
			} else if (node is ILCondition) {
				ILCondition conditionalNode = (ILCondition)node;
				bool hasFalseBlock = conditionalNode.FalseBlock.EntryGoto != null || conditionalNode.FalseBlock.Body.Count > 0;
				yield return new Ast.IfElseStatement {
					Condition = (Expression)TransformExpression(conditionalNode.Condition),
					TrueStatement = TransformBlock(conditionalNode.TrueBlock),
					FalseStatement = hasFalseBlock ? TransformBlock(conditionalNode.FalseBlock) : null
				};
			} else if (node is ILSwitch) {
				ILSwitch ilSwitch = (ILSwitch)node;
				SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition) };
				foreach (var caseBlock in ilSwitch.CaseBlocks) {
					SwitchSection section = new SwitchSection();
					if (caseBlock.Values != null) {
						section.CaseLabels.AddRange(caseBlock.Values.Select(i => new CaseLabel() { Expression = AstBuilder.MakePrimitive(i, ilSwitch.Condition.InferredType) }));
					} else {
						section.CaseLabels.Add(new CaseLabel());
					}
					section.Statements.Add(TransformBlock(caseBlock));
					switchStmt.SwitchSections.Add(section);
				}
				yield return switchStmt;
			} else if (node is ILTryCatchBlock) {
				ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
				var tryCatchStmt = new Ast.TryCatchStatement();
				tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
				foreach (var catchClause in tryCatchNode.CatchBlocks) {
					tryCatchStmt.CatchClauses.Add(
						new Ast.CatchClause {
							Type = AstBuilder.ConvertType(catchClause.ExceptionType),
							VariableName = catchClause.ExceptionVariable == null ? null : catchClause.ExceptionVariable.Name,
							Body = TransformBlock(catchClause)
						});
				}
				if (tryCatchNode.FinallyBlock != null)
					tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock);
				if (tryCatchNode.FaultBlock != null) {
					CatchClause cc = new CatchClause();
					cc.Body = TransformBlock(tryCatchNode.FaultBlock);
					cc.Body.Add(new ThrowStatement()); // rethrow
					tryCatchStmt.CatchClauses.Add(cc);
				}
				yield return tryCatchStmt;
			} else if (node is ILBlock) {
				yield return TransformBlock((ILBlock)node);
			} else if (node is ILComment) {
				yield return new CommentStatement(((ILComment)node).Text).WithAnnotation(((ILComment)node).ILRanges);
			} else {
				throw new Exception("Unknown node type");
			}
		}
Esempio n. 52
0
			public override object Visit(Switch switchStatement)
			{
				var result = new SwitchStatement();
				
				var location = LocationsBag.GetLocations(switchStatement);
				result.AddChild(new CSharpTokenNode(Convert(switchStatement.loc), SwitchStatement.SwitchKeywordRole), SwitchStatement.SwitchKeywordRole);
				if (location != null)
					result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
				if (switchStatement.Expr != null)
					result.AddChild((Expression)switchStatement.Expr.Accept(this), Roles.Expression);
				if (location != null && location.Count > 1)
					result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
				if (location != null && location.Count > 2)
					result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LBrace), Roles.LBrace);
				SwitchSection newSection = null;
				bool lastWasCase = false, added = true;
				if (switchStatement.Block != null) {
					foreach (var child in switchStatement.Block.Statements) {
						var statement = child.Accept(this);
						var caseLabel = statement as CaseLabel;
						if (caseLabel != null) {
							if (!lastWasCase) {
								newSection = new SwitchSection();
								added = false;
							}
							newSection.AddChild(caseLabel, SwitchSection.CaseLabelRole);
							lastWasCase = true;
						} else {
							if (lastWasCase) {
								result.AddChild(newSection, SwitchStatement.SwitchSectionRole);
								lastWasCase = false;
								added = true;
							}
							newSection.AddChild((Statement)statement, Roles.EmbeddedStatement);
						}
					}
				}
				if (!added)
					result.AddChild(newSection, SwitchStatement.SwitchSectionRole);

				if (location != null && location.Count > 3) {
					result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RBrace), Roles.RBrace);
				} else {
					// parser error, set end node to max value.
					result.AddChild(new ErrorNode(), Roles.Error);
				}
				
				return result;
			}
			public override object Visit (Switch switchStatement)
			{
				var result = new SwitchStatement ();
				
				var location = LocationsBag.GetLocations (switchStatement);
				result.AddChild (new CSharpTokenNode (Convert (switchStatement.loc), SwitchStatement.SwitchKeywordRole), SwitchStatement.SwitchKeywordRole);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location [0]), Roles.LPar), Roles.LPar);
				if (switchStatement.Expr != null)
					result.AddChild ((Expression)switchStatement.Expr.Accept (this), Roles.Expression);
				if (location != null && location.Count > 1)
					result.AddChild (new CSharpTokenNode (Convert (location [1]), Roles.RPar), Roles.RPar);
				if (location != null && location.Count > 2)
					result.AddChild (new CSharpTokenNode (Convert (location [2]), Roles.LBrace), Roles.LBrace);
				if (switchStatement.Sections != null) {
					foreach (var section in switchStatement.Sections) {
						var newSection = new SwitchSection ();
						if (section.Labels != null) {
							foreach (var caseLabel in section.Labels) {
								var newLabel = new CaseLabel ();
								if (caseLabel.Label != null) {
									newLabel.AddChild (new CSharpTokenNode (Convert (caseLabel.Location), CaseLabel.CaseKeywordRole), CaseLabel.CaseKeywordRole);
									if (caseLabel.Label != null)
										newLabel.AddChild ((Expression)caseLabel.Label.Accept (this), Roles.Expression);
									var colonLocation = LocationsBag.GetLocations (caseLabel);
									if (colonLocation != null)
										newLabel.AddChild (new CSharpTokenNode (Convert (colonLocation [0]), Roles.Colon), Roles.Colon);
								} else {
									newLabel.AddChild (new CSharpTokenNode (Convert (caseLabel.Location), CaseLabel.DefaultKeywordRole), CaseLabel.DefaultKeywordRole);
									newLabel.AddChild (new CSharpTokenNode (new TextLocation (caseLabel.Location.Row, caseLabel.Location.Column + "default".Length), Roles.Colon), Roles.Colon);
								}
								newSection.AddChild (newLabel, SwitchSection.CaseLabelRole);
							}
						}
						
						var blockStatement = section.Block;
						var bodyBlock = new BlockStatement ();
						int curLocal = 0;
						AddBlockChildren (bodyBlock, blockStatement, ref curLocal);
						foreach (var statement in bodyBlock.Statements) {
							statement.Remove ();
							newSection.AddChild (statement, Roles.EmbeddedStatement);
							
						}
						result.AddChild (newSection, SwitchStatement.SwitchSectionRole);
					}
				}
				
				if (location != null && location.Count > 3) {
					result.AddChild (new CSharpTokenNode (Convert (location [3]), Roles.RBrace), Roles.RBrace);
				} else {
					// parser error, set end node to max value.
					result.AddChild (new ErrorNode (), Roles.Error);
				}
				
				return result;
			}
Esempio n. 54
0
		IEnumerable<Statement> TransformNode(ILNode node)
		{
			if (node is ILLabel) {
				yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name }.WithAnnotation(node.ILRanges);
			} else if (node is ILExpression) {
				AstNode codeExpr = TransformExpression((ILExpression)node);
				if (codeExpr != null) {
					if (codeExpr is Ast.Expression) {
						yield return new Ast.ExpressionStatement { Expression = (Ast.Expression)codeExpr };
					} else if (codeExpr is Ast.Statement) {
						yield return (Ast.Statement)codeExpr;
					} else {
						throw new Exception();
					}
				}
			} else if (node is ILWhileLoop) {
				ILWhileLoop ilLoop = (ILWhileLoop)node;
				Expression expr;
				WhileStatement whileStmt = new WhileStatement() {
					Condition = expr = ilLoop.Condition != null ? (Expression)TransformExpression(ilLoop.Condition) : new PrimitiveExpression(true),
					EmbeddedStatement = TransformBlock(ilLoop.BodyBlock)
				};
				expr.AddAnnotation(ilLoop.ILRanges);
				yield return whileStmt;
			} else if (node is ILCondition) {
				ILCondition conditionalNode = (ILCondition)node;
				bool hasFalseBlock = conditionalNode.FalseBlock.EntryGoto != null || conditionalNode.FalseBlock.Body.Count > 0;
				BlockStatement trueStmt;
				var ifElseStmt = new Ast.IfElseStatement {
					Condition = (Expression)TransformExpression(conditionalNode.Condition),
					TrueStatement = trueStmt = TransformBlock(conditionalNode.TrueBlock),
					FalseStatement = hasFalseBlock ? TransformBlock(conditionalNode.FalseBlock) : null
				};
				ifElseStmt.Condition.AddAnnotation(conditionalNode.ILRanges);
				if (ifElseStmt.FalseStatement == null)
					trueStmt.HiddenEnd = NRefactoryExtensions.CreateHidden(conditionalNode.FalseBlock.GetSelfAndChildrenRecursiveILRanges(), trueStmt.HiddenEnd);
				yield return ifElseStmt;
			} else if (node is ILSwitch) {
				ILSwitch ilSwitch = (ILSwitch)node;
				if (ilSwitch.Condition.InferredType.GetElementType() == ElementType.Boolean && (
					from cb in ilSwitch.CaseBlocks
					where cb.Values != null
					from val in cb.Values
					select val
				).Any(val => val != 0 && val != 1))
				{
					// If switch cases contain values other then 0 and 1, force the condition to be non-boolean
					ilSwitch.Condition.ExpectedType = corLib.Int32;
				}
				SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition) };
				switchStmt.Expression.AddAnnotation(ilSwitch.ILRanges);
				switchStmt.HiddenEnd = NRefactoryExtensions.CreateHidden(ilSwitch.EndILRanges, switchStmt.HiddenEnd);
				foreach (var caseBlock in ilSwitch.CaseBlocks) {
					SwitchSection section = new SwitchSection();
					if (caseBlock.Values != null) {
						section.CaseLabels.AddRange(caseBlock.Values.Select(i => new CaseLabel() { Expression = AstBuilder.MakePrimitive(i, (ilSwitch.Condition.ExpectedType ?? ilSwitch.Condition.InferredType).ToTypeDefOrRef()) }));
					} else {
						section.CaseLabels.Add(new CaseLabel());
					}
					section.Statements.Add(TransformBlock(caseBlock));
					switchStmt.SwitchSections.Add(section);
				}
				yield return switchStmt;
			} else if (node is ILTryCatchBlock) {
				ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
				var tryCatchStmt = new Ast.TryCatchStatement();
				tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
				tryCatchStmt.TryBlock.HiddenStart = NRefactoryExtensions.CreateHidden(tryCatchNode.ILRanges, tryCatchStmt.TryBlock.HiddenStart);
				foreach (var catchClause in tryCatchNode.CatchBlocks) {
					if (catchClause.ExceptionVariable == null
					    && (catchClause.ExceptionType == null || catchClause.ExceptionType.GetElementType() == ElementType.Object))
					{
						tryCatchStmt.CatchClauses.Add(new Ast.CatchClause { Body = TransformBlock(catchClause) }.WithAnnotation(catchClause.StlocILRanges));
					} else {
						tryCatchStmt.CatchClauses.Add(
							new Ast.CatchClause {
								Type = AstBuilder.ConvertType(catchClause.ExceptionType),
								VariableNameToken = catchClause.ExceptionVariable == null ? null : Identifier.Create(catchClause.ExceptionVariable.Name).WithAnnotation(catchClause.ExceptionVariable.IsParameter ? TextTokenType.Parameter : TextTokenType.Local),
								Body = TransformBlock(catchClause)
							}.WithAnnotation(catchClause.ExceptionVariable).WithAnnotation(catchClause.StlocILRanges));
					}
				}
				if (tryCatchNode.FinallyBlock != null)
					tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock);
				if (tryCatchNode.FaultBlock != null) {
					CatchClause cc = new CatchClause();
					cc.Body = TransformBlock(tryCatchNode.FaultBlock);
					cc.Body.Add(new ThrowStatement()); // rethrow
					tryCatchStmt.CatchClauses.Add(cc);
				}
				yield return tryCatchStmt;
			} else if (node is ILFixedStatement) {
				ILFixedStatement fixedNode = (ILFixedStatement)node;
				FixedStatement fixedStatement = new FixedStatement();
				for (int i = 0; i < fixedNode.Initializers.Count; i++) {
					var initializer = fixedNode.Initializers[i];
					Debug.Assert(initializer.Code == ILCode.Stloc);
					ILVariable v = (ILVariable)initializer.Operand;
					VariableInitializer vi;
					fixedStatement.Variables.Add(vi =
						new VariableInitializer {
							NameToken = Identifier.Create(v.Name).WithAnnotation(v.IsParameter ? TextTokenType.Parameter : TextTokenType.Local),
							Initializer = (Expression)TransformExpression(initializer.Arguments[0])
						}.WithAnnotation(v));
					vi.AddAnnotation(ILRange.OrderAndJoin(initializer.GetSelfAndChildrenRecursiveILRanges()));
					if (i == 0)
						vi.AddAnnotation(ILRange.OrderAndJoin(fixedNode.ILRanges));
				}
				fixedStatement.Type = AstBuilder.ConvertType(((ILVariable)fixedNode.Initializers[0].Operand).Type);
				fixedStatement.EmbeddedStatement = TransformBlock(fixedNode.BodyBlock);
				yield return fixedStatement;
			} else if (node is ILBlock) {
				yield return TransformBlock((ILBlock)node);
			} else {
				throw new Exception("Unknown node type");
			}
		}
Esempio n. 55
0
	void SwitchSections(
#line  1665 "cs.ATG" 
List<SwitchSection> switchSections) {

#line  1667 "cs.ATG" 
		SwitchSection switchSection = new SwitchSection();
		CaseLabel label;
		
		SwitchLabel(
#line  1671 "cs.ATG" 
out label);

#line  1671 "cs.ATG" 
		SafeAdd(switchSection, switchSection.SwitchLabels, label); 

#line  1672 "cs.ATG" 
		compilationUnit.BlockStart(switchSection); 
		while (StartOf(32)) {
			if (la.kind == 55 || la.kind == 63) {
				SwitchLabel(
#line  1674 "cs.ATG" 
out label);

#line  1675 "cs.ATG" 
				if (label != null) {
				if (switchSection.Children.Count > 0) {
					// open new section
					compilationUnit.BlockEnd(); switchSections.Add(switchSection);
					switchSection = new SwitchSection();
					compilationUnit.BlockStart(switchSection);
				}
				SafeAdd(switchSection, switchSection.SwitchLabels, label);
				}
				
			} else {
				Statement();
			}
		}

#line  1687 "cs.ATG" 
		compilationUnit.BlockEnd(); switchSections.Add(switchSection); 
	}
 IEnumerable<Statement> TransformNode(ILNode node)
 {
     if (node is ILLabel) {
         yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
     } else if (node is ILExpression) {
         List<ILRange> ilRanges = ((ILExpression)node).GetILRanges();
         AstNode codeExpr = TransformExpression((ILExpression)node);
         if (codeExpr != null) {
             codeExpr = codeExpr.WithAnnotation(ilRanges);
             if (codeExpr is Ast.Expression) {
                 yield return new Ast.ExpressionStatement { Expression = (Ast.Expression)codeExpr };
             } else if (codeExpr is Ast.Statement) {
                 yield return (Ast.Statement)codeExpr;
             } else {
                 throw new Exception();
             }
         }
     } else if (node is ILWhileLoop) {
         ILWhileLoop ilLoop = (ILWhileLoop)node;
         if (ilLoop.PreLoopLabel != null)
             yield return TransformNode(ilLoop.PreLoopLabel).Single();
         WhileStatement whileStmt = new WhileStatement() {
             Condition = ilLoop.Condition != null ? MakeBranchCondition(ilLoop.Condition) : new PrimitiveExpression(true),
             EmbeddedStatement = TransformBlock(ilLoop.BodyBlock)
         };
         yield return whileStmt;
         if (ilLoop.PostLoopGoto != null)
             yield return (Statement)TransformExpression(ilLoop.PostLoopGoto);
     } else if (node is ILCondition) {
         ILCondition conditionalNode = (ILCondition)node;
         yield return new Ast.IfElseStatement {
             Condition = MakeBranchCondition(conditionalNode.Condition),
             TrueStatement = TransformBlock(conditionalNode.TrueBlock),
             FalseStatement = TransformBlock(conditionalNode.FalseBlock)
         };
     } else if (node is ILSwitch) {
         ILSwitch ilSwitch = (ILSwitch)node;
         SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition.Arguments[0]) };
         for (int i = 0; i < ilSwitch.CaseBlocks.Count; i++) {
             SwitchSection section = new SwitchSection();
             section.CaseLabels.Add(new CaseLabel() { Expression = new PrimitiveExpression(i) });
             section.Statements.Add(TransformBlock(ilSwitch.CaseBlocks[i]));
             switchStmt.SwitchSections.Add(section);
         }
         yield return switchStmt;
         if (ilSwitch.DefaultGoto != null)
             yield return (Statement)TransformExpression(ilSwitch.DefaultGoto);
     } else if (node is ILTryCatchBlock) {
         ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
         var tryCatchStmt = new Ast.TryCatchStatement();
         tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
         foreach (var catchClause in tryCatchNode.CatchBlocks) {
             tryCatchStmt.CatchClauses.Add(
                 new Ast.CatchClause {
                     Type = AstBuilder.ConvertType(catchClause.ExceptionType),
                     VariableName = catchClause.ExceptionVariable == null ? null : catchClause.ExceptionVariable.Name,
                     Body = TransformBlock(catchClause)
                 });
         }
         if (tryCatchNode.FinallyBlock != null)
             tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock);
         yield return tryCatchStmt;
     } else if (node is ILBlock) {
         yield return TransformBlock((ILBlock)node);
     } else if (node is ILComment) {
         yield return new CommentStatement(((ILComment)node).Text).WithAnnotation(((ILComment)node).ILRanges);
     } else {
         throw new Exception("Unknown node type");
     }
 }
		public virtual void VisitSwitchSection (SwitchSection switchSection)
		{
			VisitChildren (switchSection);
		}
Esempio n. 58
0
 public SwitchStatement(
     Exp expTest,
     SwitchSection [] sections
 )
 {
     m_expTest = expTest;
     m_sections = sections;
     
     m_proxy = null;
 }
Esempio n. 59
0
        protected void VisitAsyncSwitchSection(SwitchSection switchSection, bool writeElse, string switchKey)
        {
            var list = switchSection.CaseLabels.ToList();

            list.Sort((l1, l2) =>
            {
                if (l1.Expression.IsNull)
                {
                    return 1;
                }

                if (l2.Expression.IsNull)
                {
                    return -1;
                }

                return 0;
            });

            if (writeElse)
            {
                this.WriteElse();
            }

            if (list.Any(l => l.Expression.IsNull))
            {
                if (!writeElse)
                {
                    this.WriteElse();
                }
            }
            else
            {
                this.WriteIf();
                this.WriteOpenParentheses();

                var oldValue = this.Emitter.ReplaceAwaiterByVar;
                this.Emitter.ReplaceAwaiterByVar = true;
                bool writeOr = false;

                foreach (var label in list)
                {
                    if (writeOr)
                    {
                        this.WriteSpace();
                        this.Write("||");
                        this.WriteSpace();
                    }

                    this.Write(switchKey + " === ");
                    label.Expression.AcceptVisitor(this.Emitter);

                    writeOr = true;
                }

                this.WriteCloseParentheses();
                this.Emitter.ReplaceAwaiterByVar = oldValue;
            }

            if (switchSection.Statements.Count() == 1 && switchSection.Statements.First() is BlockStatement)
            {
                this.Emitter.IgnoreBlock = switchSection.Statements.First();
            }

            int startCount = this.Emitter.AsyncBlock.Steps.Count;
            IAsyncStep thisStep = null;
            this.WriteSpace();
            this.BeginBlock();
            this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");
            var writer = this.SaveWriter();
            var bodyStep = this.Emitter.AsyncBlock.AddAsyncStep();

            switchSection.Statements.AcceptVisitor(this.Emitter);

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                thisStep = this.Emitter.AsyncBlock.Steps.Last();
            }

            if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true))
            {
                this.WriteNewLine();
            }

            this.EndBlock();
            this.WriteNewLine();
        }
		public override object VisitSwitchSection(SwitchSection switchSection, object data)
		{
			// Check if a 'break' should be auto inserted.
			if (switchSection.Children.Count == 0 ||
			    !(switchSection.Children[switchSection.Children.Count - 1] is BreakStatement ||
			      switchSection.Children[switchSection.Children.Count - 1] is ContinueStatement ||
			      switchSection.Children[switchSection.Children.Count - 1] is ThrowStatement ||
			      switchSection.Children[switchSection.Children.Count - 1] is ReturnStatement))
			{
				switchSection.Children.Add(new BreakStatement());
			}
			return base.VisitSwitchSection(switchSection, data);
		}