public UnifiedElement VisitSwitchStatement( SwitchStatement stmt, object data) { var uExpr = stmt.Expression.TryAcceptForExpression(this); var caseCollection = UnifiedSet <UnifiedCase> .Create(); foreach (var sec in stmt.SwitchSections) { var body = sec.Statements .Select(s => s.TryAcceptForExpression(this)) .ToBlock(); var lastIx = sec.CaseLabels.Count - 1; Func <UnifiedExpression, int, UnifiedCase> func = (expr, ix) => { return((ix == lastIx) ? UnifiedCase.Create(expr, body) : UnifiedCase.Create(expr)); }; var cases = sec.CaseLabels .Select(lbl => lbl.Expression.TryAcceptForExpression(this)) .Select(func); foreach (var c in cases) { caseCollection.Add(c); } } return(UnifiedSwitch.Create(uExpr, caseCollection)); }
public static UnifiedExpression CreateCase(XElement node) { Contract.Requires(node != null); Contract.Requires(node.Name() == "case"); return(UnifiedSwitch.Create( CreateExpresion(node.NthElement(0)), node.Elements().Skip(1) .SelectMany(CreateWhenAndDefault) .ToSet() )); }
private static IEnumerable <UnifiedExpression> CreateSwitchStatement(SwitchStatement statement) { var cases = statement.CodeList.Cast <SwitchCaseBase>().Select( sc => UnifiedCase.Create( CreatePhrase(sc.CaseLabel), CreateStatementCollection(sc.Statements))) .ToSet(); cases.Add(UnifiedCase.CreateDefault(CreateStatementCollection(statement.ElseCase.Statements))); yield return(UnifiedSwitch.Create(CreatePhrase(statement.Expression), cases)); }
public static UnifiedExpression CreateSelectionStatement(XElement node) { Contract.Requires(node != null); Contract.Requires(node.Name() == "selection_statement"); /* * selection_statement * : 'if' '(' expression ')' statement (options {k=1; backtrack=false;}:'else' statement)? | 'switch' '(' expression ')' statement */ // TODO switch文のstatementについて、{}がないと単一のstatementしか取得できないため対応を考える // TODO switchNest.c switch (node.FirstElement().Value) { case "if": var statements = node.Elements("statement"); var trueBlock = CreateStatement(statements.ElementAt(0)); // statementが2つある場合はelse文がある if (statements.Count() == 2) { return (UnifiedIf.Create( CreateExpression(node.NthElement(2)).First(), trueBlock.ToBlock(), CreateStatement(statements.ElementAt(1)). ToBlock())); } return (UnifiedIf.Create( CreateExpression(node.NthElement(2)).First(), trueBlock.ToBlock())); case "switch": // statementの中身を解析して、この関数内で直接UnifiedCaseを生成します。 // labeled_statementから辿って、このノードに到達するまでにlabeled_statementがなければ、 // そのlabeled_statementはこのノードのケース文です var cases = UnifiedSet <UnifiedCase> .Create(); var labels = node.DescendantsAndSelf("labeled_statement") // Ignore label statements for goto .Where(e => e.FirstElement().Name != "IDENTIFIER") // Ignore label statements of nested switches .Where( e => !e.AncestorsUntil(node).Any( e2 => e2.Name == "selection_statement" && e2.Value.StartsWith("switch"))); foreach (var e in labels) { cases.Add(CreateCaseOrDefault(e)); } return (UnifiedSwitch.Create( CreateExpression(node.NthElement(2)).First(), cases)); default: throw new InvalidOperationException(); } }