private void Assert(GlobNode node, GlobNodeType type)
 {
     if (node.Type != type)
     {
         throw new InvalidOperationException();
     }
 }
 public GlobNode(GlobNodeType type, GlobNode child)
 {
     this.Type     = type;
     this.Text     = null;
     this.Children = new List <GlobNode> {
         child
     };
 }
        public static string Process(GlobNode node)
        {
            if (node.Type != GlobNodeType.Tree)
            {
                throw new InvalidOperationException();
            }

            return(ProcessTree(node));
        }
        private GlobNode ParseIdentifier()
        {
            if (this._currentToken.Kind == TokenKind.Identifier)
            {
                var identifier = new GlobNode(GlobNodeType.Identifier, this._currentToken.Spelling);
                this.AcceptIt();
                return(identifier);
            }

            throw new Exception("Unable to parse Identifier");
        }
        private void Compile()
        {
            if (_root != null)
            {
                return;
            }

            var parser = new GlobParser(this.Pattern);

            _root = parser.Parse();

            //TODO: this is basically cheating and probably not efficient but it works for now.
            _regex = new Regex(GlobToRegexVisitor.Process(_root) + (this.Pattern.EndsWith("*") ? "" : "$"), RegexOptions.Compiled);
        }
        private static string ProcessRoot(GlobNode node)
        {
            if (node.Children.Count > 0) //windows root
            {
                return(Regex.Escape(node.Children[0].Text + ":"));
            }

            if (!string.IsNullOrEmpty(node.Text)) // CWD
            {
                return(Regex.Escape(node.Text));
            }


            return(string.Empty);
        }
        private static string ProcessSegment(GlobNode node)
        {
            switch (node.Type)
            {
            case GlobNodeType.Root:
                return(ProcessRoot(node));

            case GlobNodeType.DirectoryWildcard:
                return(ProcessDirectoryWildcard(node));

            case GlobNodeType.PathSegment:
                return(ProcessPathSegment(node));

            default:
                throw new InvalidOperationException();
            }
        }
        private static string ProcessSubSegment(GlobNode node)
        {
            switch (node.Type)
            {
            case GlobNodeType.Identifier:
                return(ProcessIdentifier(node));

            case GlobNodeType.CharacterSet:
                return(ProcessCharacterSet(node));

            case GlobNodeType.LiteralSet:
                return(ProcessLiteralSet(node));

            case GlobNodeType.CharacterWildcard:
                return(ProcessCharacterWildcard(node));

            case GlobNodeType.WildcardString:
                return(ProcessWildcardString(node));
            }
            throw new NotImplementedException();
        }
 private static string ProcessDirectoryWildcard(GlobNode node)
 {
     return(".*");
 }
 private static string ProcessIdentifier(GlobNode node)
 {
     return(Regex.Escape(node.Text));
 }
 private static string ProcessCharacterSet(GlobNode node)
 {
     return("[" + ProcessIdentifier(node.Children.First()) + "]");
 }
 private static string ProcessLiteralSet(GlobNode node)
 {
     return("(" + string.Join(",", node.Children.Select(ProcessIdentifier)) + ")");
 }
 private static string ProcessCharacterWildcard(GlobNode node)
 {
     return(@"[^/]{1}");
 }
 private static string ProcessWildcardString(GlobNode node)
 {
     return(@"[^/]*");
 }
 private static string ProcessPathSegment(GlobNode node)
 {
     return(string.Join("", node.Children.Select(ProcessSubSegment)));
 }
 private static string ProcessTree(GlobNode node)
 {
     return(string.Join("/", node.Children.Select(ProcessSegment)));
 }