コード例 #1
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        static void _Concat(CharFA <TAccept> lhs, CharFA <TAccept> rhs)
        {
            var f = lhs.FirstAcceptingState;

            f.EpsilonTransitions.Add(rhs);
            f.IsAccepting = false;
        }
コード例 #2
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates a new FA that is a concatenation of two other FA expressions
        /// </summary>
        /// <param name="exprs">The FAs to concatenate</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that is the concatenation of the specified FAs</returns>
        public static CharFA <TAccept> Concat(IEnumerable <CharFA <TAccept> > exprs, TAccept accept = default(TAccept))
        {
            CharFA <TAccept> left = null;
            var right             = left;

            foreach (var val in exprs)
            {
                if (null == val)
                {
                    continue;
                }
                var nval = val.Clone();
                if (null == left)
                {
                    left = nval;
                    continue;
                }
                else if (null == right)
                {
                    right = nval;
                }
                else
                {
                    _Concat(right, nval);
                }

                _Concat(left, right);
            }
            right.FirstAcceptingState.AcceptSymbol = accept;
            return(left);
        }
コード例 #3
0
ファイル: Main.cs プロジェクト: iplayfast/fa
        private void RenderTimer_Tick(object sender, EventArgs e)
        {
            RenderTimer.Enabled = false;
            CharFA <string> fa = null;

            try
            {
                fa = CharFA <string> .Parse(Regex.Text, "Accept");
            }
            catch (Exception ex)
            {
                Status.Text = string.Format("Error Parsing Regex: {0}", ex.Message);
            }
            if (null != fa)
            {
                // mark our states for displaying the DFA later
                foreach (var ffa in fa.FillClosure())
                {
                    ffa.Tag = ffa;
                }

                try
                {
                    var kvp = fa.Lex(Input.Text.GetEnumerator(), "#ERROR");
                    if (kvp.Value.Length != Input.Text.Length)
                    {
                        Status.Text = string.Format("Input error at {0}", kvp.Value.Length);
                    }
                    else
                    {
                        Status.Text = "Successfully Lexed.";
                    }
                }
                catch (Exception eex)
                {
                    Status.Text = string.Format("Input error: {0}", eex.Message);
                }
                var options = new CharFA <string> .DotGraphOptions();

                options.DebugString = Input.Text;
                var dfa = fa.ToDfa();
                dfa.TrimDuplicates();
                try
                {
                    using (var stm = fa.RenderToStream("jpg", false, options))
                        NfaGraph.Image = Image.FromStream(stm);
                } catch
                {
                }
                options.StatePrefix    = @"Q";
                options.DebugSourceNfa = fa;
                try
                {
                    using (var stm = dfa.RenderToStream("jpg", false, options))
                        DfaGraph.Image = Image.FromStream(stm);
                }
                catch { }
            }
        }
コード例 #4
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates a new FA that matches the specified FA expression or empty
        /// </summary>
        /// <param name="expr">The expression to make optional</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that will match the specified expression or empty</returns>
        public static CharFA <TAccept> Optional(CharFA <TAccept> expr, TAccept accept = default(TAccept))
        {
            var result = expr.Clone();
            var f      = result.FirstAcceptingState;

            f.AcceptSymbol = accept;
            result.EpsilonTransitions.Add(f);
            return(result);
        }
コード例 #5
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates an FA that will match any one of a set of a characters
        /// </summary>
        /// <param name="ranges">The set ranges of characters that will be matched</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>An FA that will match the specified set</returns>
        public static CharFA <TAccept> Set(IEnumerable <CharRange> ranges, TAccept accept = default(TAccept))
        {
            var result = new CharFA <TAccept>();
            var final  = new CharFA <TAccept>(true, accept);

            foreach (var ch in CharRange.ExpandRanges(ranges))
            {
                result.Transitions.Add(ch, final);
            }
            return(result);
        }
コード例 #6
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates an FA that will match any one of a set of a characters
        /// </summary>
        /// <param name="set">The set of characters that will be matched</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>An FA that will match the specified set</returns>
        public static CharFA <TAccept> Set(IEnumerable <char> set, TAccept accept = default(TAccept))
        {
            var result = new CharFA <TAccept>();
            var final  = new CharFA <TAccept>(true, accept);

            foreach (var ch in set)
            {
                result.Transitions.Add(ch, final);
            }
            return(result);
        }
コード例 #7
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates a new FA that will match a repetition of one or more of the specified FA expression
        /// </summary>
        /// <param name="expr">The expression to repeat</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that matches the specified FA one or more times</returns>
        public static CharFA <TAccept> Repeat(CharFA <TAccept> expr, TAccept accept = default(TAccept))
        {
            var result = new CharFA <TAccept>();
            var final  = new CharFA <TAccept>(true, accept);
            var e      = expr.Clone();
            var afa    = e.FirstAcceptingState;

            afa.IsAccepting = false;
            afa.EpsilonTransitions.Add(final);
            afa.EpsilonTransitions.Add(result);
            result.EpsilonTransitions.Add(e);
            return(result);
        }
コード例 #8
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates an FA that matches a literal string
        /// </summary>
        /// <param name="string">The string to match</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA machine that will match this literal</returns>
        public static CharFA <TAccept> Literal(IEnumerable <char> @string, TAccept accept = default(TAccept))
        {
            var result  = new CharFA <TAccept>();
            var current = result;

            foreach (var ch in @string)
            {
                current.IsAccepting = false;
                var fa = new CharFA <TAccept>(true, accept);
                current.Transitions.Add(ch, fa);
                current = fa;
            }
            return(result);
        }
コード例 #9
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        /// <summary>
        /// Creates a new FA that matches any one of the FA expressions passed
        /// </summary>
        /// <param name="exprs">The expressions to match</param>
        /// <param name="accept">The symbol to accept</param>
        /// <returns>A new FA that will match the union of the FA expressions passed</returns>
        public static CharFA <TAccept> Or(IEnumerable <CharFA <TAccept> > exprs, TAccept accept = default(TAccept))
        {
            var result = new CharFA <TAccept>();
            var final  = new CharFA <TAccept>(true, accept);

            foreach (var fa in exprs)
            {
                var nfa = fa.Clone();
                result.EpsilonTransitions.Add(nfa);
                var nffa = nfa.FirstAcceptingState;
                nffa.IsAccepting = false;
                nffa.EpsilonTransitions.Add(final);
            }
            return(result);
        }
コード例 #10
0
        static void Main(string[] args)
        {
            var nfa = CharFA <string> .Parse("hello|world!", "success!");

            var dfa  = nfa.ToDfa();
            var opts = new CharFA <string> .DotGraphOptions();

            opts.DebugSourceNfa = nfa;
            opts.DebugString    = "he";
            dfa.TrimDuplicates();
            dfa.RenderToFile(@"..\..\..\helloworld.jpg", opts);
            Console.WriteLine(dfa);

            var tok = dfa.Lex("helloworld".GetEnumerator(), "#ERROR");

            Console.WriteLine("{0}: {1}", tok.Key, new string(tok.Value));
        }
コード例 #11
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
        static CharFA <TAccept> _Parse(ParseContext pc, TAccept accept)
        {
            CharFA <TAccept> result = new CharFA <TAccept>(true, accept);

            CharFA <TAccept> f, next;
            int ch;

            pc.EnsureStarted();
            var current = result;

            while (true)
            {
                switch (pc.Current)
                {
                case -1:
                    return(result);

                case '.':
                    pc.Advance();
                    f = current.FirstAcceptingState as CharFA <TAccept>;

                    current = Set(new CharRange[] { new CharRange(char.MinValue, char.MaxValue) }, accept);
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    f.IsAccepting = false;
                    f.EpsilonTransitions.Add(current);
                    break;

                case '\\':
                    if (-1 != (ch = _ParseEscape(pc)))
                    {
                        next = null;
                        switch (pc.Current)
                        {
                        case '*':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Kleene(next, accept);
                            pc.Advance();
                            break;

                        case '+':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Repeat(next, accept);
                            pc.Advance();
                            break;

                        case '?':
                            next = new CharFA <TAccept>();
                            next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            next = Optional(next, accept);
                            pc.Advance();
                            break;

                        default:
                            current             = current.FirstAcceptingState as CharFA <TAccept>;
                            current.IsAccepting = false;
                            current.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                            break;
                        }
                        if (null != next)
                        {
                            current             = current.FirstAcceptingState as CharFA <TAccept>;
                            current.IsAccepting = false;
                            current.EpsilonTransitions.Add(next);
                            current = next;
                        }
                    }
                    else
                    {
                        pc.Expecting();                              // throw an error
                        return(null);                                // doesn't execute
                    }
                    break;

                case ')':
                    return(result);

                case '(':
                    pc.Advance();
                    pc.Expecting();
                    f       = current.FirstAcceptingState as CharFA <TAccept>;
                    current = _Parse(pc, accept);
                    pc.Expecting(')');
                    pc.Advance();
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    var ff = f.FirstAcceptingState;
                    ff.EpsilonTransitions.Add(current);
                    ff.IsAccepting = false;
                    break;

                case '|':
                    if (-1 != pc.Advance())
                    {
                        current = _Parse(pc, accept);
                        result  = Or(new CharFA <TAccept>[] { result as CharFA <TAccept>, current as CharFA <TAccept> }, accept);
                    }
                    else
                    {
                        current = current.FirstAcceptingState as CharFA <TAccept>;
                        result  = Optional(result, accept);
                    }
                    break;

                case '[':
                    pc.ClearCapture();
                    pc.Advance();
                    pc.Expecting();
                    bool not = false;
                    if ('^' == pc.Current)
                    {
                        not = true;
                        pc.Advance();
                        pc.Expecting();
                    }
                    pc.TryReadUntil(']', '\\', false);
                    pc.Expecting(']');
                    pc.Advance();

                    var r = (!not && "." == pc.Capture) ?
                            new CharRange[] { new CharRange(char.MinValue, char.MaxValue) } :
                    _ParseRanges(pc.Capture, true);
                    if (not)
                    {
                        r = CharRange.NotRanges(r);
                    }
                    f       = current.FirstAcceptingState as CharFA <TAccept>;
                    current = Set(r, accept);
                    switch (pc.Current)
                    {
                    case '*':
                        current = Kleene(current, accept);
                        pc.Advance();
                        break;

                    case '+':
                        current = Repeat(current, accept);
                        pc.Advance();
                        break;

                    case '?':
                        current = Optional(current, accept);
                        pc.Advance();
                        break;
                    }
                    f.IsAccepting = false;
                    f.EpsilonTransitions.Add(current);
                    break;

                default:
                    ch = pc.Current;
                    pc.Advance();
                    next = null;
                    switch (pc.Current)
                    {
                    case '*':
                        next = new CharFA <TAccept>();
                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Kleene(next, accept);
                        pc.Advance();
                        break;

                    case '+':
                        next = new CharFA <TAccept>();
                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Repeat(next, accept);
                        pc.Advance();
                        break;

                    case '?':
                        next = new CharFA <TAccept>();

                        next.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        next = Optional(next, accept);
                        pc.Advance();
                        break;

                    default:
                        current             = current.FirstAcceptingState as CharFA <TAccept>;
                        current.IsAccepting = false;
                        current.Transitions.Add((char)ch, new CharFA <TAccept>(true, accept));
                        break;
                    }
                    if (null != next)
                    {
                        current             = current.FirstAcceptingState as CharFA <TAccept>;
                        current.IsAccepting = false;
                        current.EpsilonTransitions.Add(next);
                        current = next;
                    }
                    break;
                }
            }
        }
コード例 #12
0
ファイル: CharFA.cs プロジェクト: iplayfast/fa
 /// <summary>
 /// Creates a new FA that will match a repetition of zero or more of the specified FA expressions
 /// </summary>
 /// <param name="expr">The expression to repeat</param>
 /// <param name="accept">The symbol to accept</param>
 /// <returns>A new FA that matches the specified FA zero or more times</returns>
 public static CharFA <TAccept> Kleene(CharFA <TAccept> expr, TAccept accept = default(TAccept))
 {
     return(Optional(Repeat(expr), accept));
 }