public FA ToFA(int match) { Ast ast = this; if (ast.IsLazy) { throw new NotSupportedException("The AST node cannot be lazy"); } switch (ast.Kind) { case Ast.Alt: return(FA.Or(_ToFAs(ast.Exprs, match), match)); case Ast.Cat: if (1 == ast.Exprs.Length) { return(ast.Exprs[0].ToFA(match)); } return(FA.Concat(_ToFAs(ast.Exprs, match), match)); case Ast.Dot: return(FA.Set(new int[] { 0, 0xd7ff, 0xe000, 0x10ffff }, match)); case Ast.Lit: return(FA.Literal(new int[] { ast.Value }, match)); case Ast.NSet: var pairs = RangeUtility.ToPairs(ast.Ranges); RangeUtility.NormalizeRangeList(pairs); var pairl = new List <KeyValuePair <int, int> >(RangeUtility.NotRanges(pairs)); return(FA.Set(RangeUtility.FromPairs(pairl), match)); case Ast.NUCode: pairs = RangeUtility.ToPairs(CharacterClasses.UnicodeCategories[ast.Value]); RangeUtility.NormalizeRangeList(pairs); pairl = new List <KeyValuePair <int, int> >(RangeUtility.NotRanges(pairs)); return(FA.Set(RangeUtility.FromPairs(pairl), match)); case Ast.Opt: return(FA.Optional(ast.Exprs[0].ToFA(match), match)); case Ast.Plus: return(FA.Repeat(ast.Exprs[0].ToFA(match), 1, 0, match)); case Ast.Rep: return(FA.Repeat(ast.Exprs[0].ToFA(match), ast.Min, ast.Max, match)); case Ast.Set: return(FA.Set(ast.Ranges, match)); case Ast.Star: return(FA.Repeat(ast.Exprs[0].ToFA(match), 0, 0, match)); case Ast.UCode: return(FA.Set(CharacterClasses.UnicodeCategories[ast.Value], match)); default: throw new NotImplementedException(); } }