예제 #1
0
        static void Main(string[] args)
        {
#if !REGEN
            Console.WriteLine("Simple Expression Evaluator");
            Console.WriteLine("Hit Enter on a new line to exit.");
            var parser = new ExprParser();
            while (true)
            {
                Console.Write(">");
                var line = Console.ReadLine();
                if (string.IsNullOrEmpty(line))
                {
                    return;
                }
                var pc = ParseContext.Create(line);
                parser.Restart(pc);
                var ptree = parser.ParseSubtree();
                // parse subtree will not read the whole
                // text, just the subtree so in order to
                // validate the *entire* input we must read
                // the rest.
                while (parser.Read())
                {
                    switch (parser.NodeType)
                    {
                    case LLNodeType.Error:
                        Console.Error.WriteLine("Error: " + parser.Value);
                        break;
                    }
                }

                // check if there's an error currently.
                switch (parser.NodeType)
                {
                case LLNodeType.Error:
                    Console.Error.WriteLine("Error in line after expression");
                    break;
                }

                Console.WriteLine(ptree);
                Console.WriteLine();
                try
                {
                    Console.WriteLine("Evaluation: {0} = {1}", line, Eval(ptree));
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("Evaluation error: " + ex.Message);
                }
            }
#endif
        }
예제 #2
0
        static void _ReadAttributes(IDictionary <string, object> attrs, EbnfParser parser)
        {
            parser.Read();
            while (EbnfParser.attribute == parser.SymbolId)
            {
                parser.Read();
                var id = parser.Value;
                parser.Read();
                object val = true;
                if (EbnfParser.eq == parser.SymbolId)
                {
                    parser.Read();
                    parser.Read();
                    switch (parser.SymbolId)
                    {
                    case EbnfParser.identifier:

                        if ("null" == parser.Value)
                        {
                            val = null;
                        }
                        else if ("true" == parser.Value)
                        {
                            val = true;
                        }
                        else if ("false" == parser.Value)
                        {
                            val = false;
                        }
                        else
                        {
                            throw new ExpectingException("Expecting true, false, or null.");
                        }
                        break;

                    case EbnfParser.integer:
                        val = int.Parse(parser.Value);
                        break;

                    case EbnfParser.literal:
                        val = ParseContext.Create(parser.Value).ParseJsonString();
                        break;
                    }
                    parser.Read();
                }
                attrs.Add(id, val);
                if (EbnfParser.comma == parser.SymbolId)
                {
                    parser.Read();
                }
            }
        }
예제 #3
0
        static IList <EbnfMessage> _TryParseProduction(ParseNode pn, out KeyValuePair <string, EbnfProduction> result)
        {
            Debug.Assert(EbnfParser.production == pn.SymbolId, "Not positioned on production");
            var    msgs = new List <EbnfMessage>();
            string name = pn.Children[0].Value;

            if ("production" == name)
            {
                Debugger.Break();
            }
            var prod = new EbnfProduction();

            prod.SetLocationInfo(pn.Line, pn.Column, pn.Position);
            var i = 0;

            if (EbnfParser.lt == pn.Children[1].SymbolId)
            {
                i = 2;
                while (EbnfParser.gt != pn.Children[i].SymbolId)
                {
                    var attrnode = pn.Children[i];
                    var attrname = attrnode.Children[0].Value;
                    var attrval  = (object)true;
                    if (3 == attrnode.Children.Count)
                    {
                        var s = attrnode.Children[2].Children[0].Value;
                        if (!ParseContext.Create(s).TryParseJsonValue(out attrval))
                        {
                            attrval = null;
                        }
                    }
                    prod.Attributes.Add(attrname, attrval);
                    ++i;
                    if (EbnfParser.comma == pn.Children[i].SymbolId)
                    {
                        ++i;
                    }
                }
                ++i;
            }
            ++i;
            EbnfExpression e;

            _TryParseExpressions(pn, i, out e);
            prod.Expression = e;

            result = new KeyValuePair <string, EbnfProduction>(name, prod);
            return(msgs);
        }
예제 #4
0
        static void Main(string[] args)
        {
            var file = @"..\..\..\ebnf.ebnf";
            var doc  = EbnfDocument.ReadFrom(file);

            doc.Prepare();
            var cfg = doc.ToCfg();

            cfg.PrepareLL1();
            var    lexer = doc.ToLexer(cfg);
            string filestring;

            using (var sr = File.OpenText(file))
                filestring = sr.ReadToEnd();
            LLParser parser = cfg.ToLL1Parser(lexer);

            parser.Restart(ParseContext.Create(filestring));
            Console.WriteLine(parser.ParseSubtree());
            var sw = new Stopwatch();

            sw.Restart();
            for (var i = 0; i < 100; ++i)
            {
                parser.Restart(ParseContext.Create(filestring));
                while (parser.Read())
                {
                    ;
                }
            }
            sw.Stop();
            Console.WriteLine("Runtime Parser: {0}", sw.Elapsed / 100);

            parser = new EbnfParser();
            sw.Restart();
            for (var i = 0; i < 100; ++i)
            {
                parser.Restart(ParseContext.Create(filestring));
                while (parser.Read())
                {
                    ;
                }
            }
            sw.Stop();
            Console.WriteLine("Generated Parser: {0}", sw.Elapsed / 100);
        }
예제 #5
0
        static void _RunMatch()
        {
            var test = "foo123_ _bar";

            var word = CharFA <string> .Repeat(
                CharFA <string> .Set(new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z') }),
                1, -1
                , "Word");

            var         dfaWord      = word.ToDfa();
            var         dfaTableWord = word.ToDfaStateTable();
            CharFAMatch match;
            var         pc = ParseContext.Create(test);

            Console.WriteLine("Matching words with an NFA:");
            while (null != (match = word.Match(pc)))
            {
                Console.WriteLine("Found match at {0}: {1}", match.Position, match.Value);
            }
            Console.WriteLine();
            pc = ParseContext.Create(test);
            Console.WriteLine("Matching words with a DFA:");
            while (null != (match = dfaWord.MatchDfa(pc)))
            {
                Console.WriteLine("Found match at {0}: {1}", match.Position, match.Value);
            }
            Console.WriteLine();
            pc = ParseContext.Create(test);
            Console.WriteLine("Matching words with a DFA state table:");
            while (null != (match = CharFA <string> .MatchDfa(dfaTableWord, pc)))
            {
                Console.WriteLine("Found match at {0}: {1}", match.Position, match.Value);
            }
            Console.WriteLine();
            pc = ParseContext.Create(test);
            Console.WriteLine("Matching words with a compiled DFA:");
            while (null != (match = Match(pc)))
            {
                Console.WriteLine("Found match at {0}: {1}", match.Position, match.Value);
            }
            Console.WriteLine();
        }
예제 #6
0
        public IEnumerable <string> ExpandMatchingStepPatternWithAllPossibleParameter(SpecflowStepInfo stepDefinitionInfo, string partialStepText, string fullStepText)
        {
            var matchedText = string.Empty;

            if (partialStepText.Length > 0)
            {
                var result = stepDefinitionInfo.RegexForPartialMatch?.Match(ParseContext.Create(partialStepText), successOnAnyState: true);
                if (result == null || result.Position != 0)
                {
                    return(EmptyList <string> .Enumerable);
                }
                matchedText = result.Value;
            }

            var tokenizedStepPattern = TokenizeStepPattern(stepDefinitionInfo.Pattern).ToList();
            var captureValues        = RetrieveParameterValues(stepDefinitionInfo, partialStepText, fullStepText, tokenizedStepPattern);

            var stringBuilder = new StringBuilder();
            var results       = new List <string>();

            BuildAllPossibleSteps(matchedText, stringBuilder, results, tokenizedStepPattern.ToArray(), captureValues, 0, 0);
            return(results);
        }
예제 #7
0
 public static EbnfDocument ReadFrom(TextReader reader) => _Parse(ParseContext.Create(reader));
예제 #8
0
        static void _RunLexer()
        {
            var digits = CharFA <string> .Repeat(
                CharFA <string> .Set("0123456789"),
                1, -1
                , "Digits");

            var word = CharFA <string> .Repeat(
                CharFA <string> .Set(new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z') }),
                1, -1
                , "Word");

            var whitespace = CharFA <string> .Repeat(
                CharFA <string> .Set(" \t\r\n\v\f"),
                1, -1
                , "Whitespace");

            var lexer = CharFA <string> .ToLexer(digits, word, whitespace);

            var lexerDfa = lexer.ToDfa();

            lexerDfa.TrimDuplicates();
            // we use a symbol table with the DFA state table to map ids back to strings
            var symbolTable = new string[] { "Digits", "Word", "Whitespace", "#ERROR" };
            // make sure to pass the symbol table if you're using one
            var dfaTable = lexer.ToDfaStateTable(symbolTable);
            var test     = "foo123_ _bar";

            Console.WriteLine("Lex using the NFA");
            // create a parse context over our test string
            var pc = ParseContext.Create(test);

            // while not end of input
            while (-1 != pc.Current)
            {
                // clear the capture so that we don't keep appending the token data
                pc.ClearCapture();
                // lex the next token
                var acc = lexer.Lex(pc, "#ERROR");
                // write the result
                Console.WriteLine("{0}: {1}", acc, pc.GetCapture());
            }
            Console.WriteLine();
            Console.WriteLine("Lex using the DFA");
            // create a new parse context over our test string
            // because our old parse context is now past the end
            pc = ParseContext.Create(test);
            while (-1 != pc.Current)
            {
                pc.ClearCapture();
                // lex using the DFA. This works exactly like
                // the previous Lex method except that it's
                // optimized for DFA traversal.
                // DO NOT use this with an NFA. It won't work
                // but won't error (can't check for perf reasons)
                var acc = lexerDfa.LexDfa(pc, "#ERROR");
                // write the result
                Console.WriteLine("{0}: {1}", acc, pc.GetCapture());
            }
            Console.WriteLine();
            Console.WriteLine("Lex using the DFA state table");
            pc = ParseContext.Create(test);
            while (-1 != pc.Current)
            {
                pc.ClearCapture();
                // Lex using our DFA table. This is a little different
                // because it's a static method that takes CharDfaEntry[]
                // as its first parameter. It also uses symbol ids instead
                // of the actual symbol. You must map them back using the
                // symbol table you created earlier.
                var acc = CharFA <string> .LexDfa(dfaTable, pc, 3);

                // when we write this, we map our symbol id back to the
                // symbol using our symbol table
                Console.WriteLine("{0}: {1}", symbolTable[acc], pc.GetCapture());
            }
            Console.WriteLine();
            Console.WriteLine("Lex using our compiled lex method");
            pc = ParseContext.Create(test);
            while (-1 != pc.Current)
            {
                pc.ClearCapture();
                // Lex using our compiledDFA. Like the table driven lex
                // this also uses symbol ids instead of the actual symbol.
                var acc = Lex(pc);
                // when we write this, we map our symbol id back to the
                // symbol using our symbol table
                Console.WriteLine("{0}: {1}", symbolTable[acc], pc.GetCapture());
            }
            Console.WriteLine();
        }
예제 #9
0
 public static Cfg ReadFrom(TextReader reader) => _Parse(ParseContext.Create(reader));
예제 #10
0
 public static Cfg Parse(IEnumerable <char> @string) => _Parse(ParseContext.Create(@string));
예제 #11
0
파일: CharFA.cs 프로젝트: iplayfast/fa
 /// <summary>
 /// Parses a regular expresion from the specified <see cref="TextReader"/>
 /// </summary>
 /// <param name="reader">The text reader</param>
 /// <param name="accepting">The symbol reported when accepting the specified expression</param>
 /// <returns>A new machine that matches the regular expression</returns>
 public static CharFA <TAccept> ReadFrom(TextReader reader, TAccept accept = default(TAccept)) => _Parse(ParseContext.Create(reader), accept);
예제 #12
0
        static IList <EbnfMessage> _TryParseExpression(ParseNode pn, out EbnfExpression result)
        {
            result = null;
            Debug.Assert(EbnfParser.expression == pn.SymbolId, "Not positioned on expression");
            var msgs = new List <EbnfMessage>();

            if (1 == pn.Children.Count)
            {
                var c = pn.Children[0];
                if (EbnfParser.symbol == c.SymbolId)
                {
                    ParseContext pc;
                    var          cc = c.Children[0];
                    //TODO: parse the regular expressions and literals to make sure they're valid.
                    switch (cc.SymbolId)
                    {
                    case EbnfParser.identifier:
                        result = new EbnfRefExpression(cc.Value);
                        return(msgs);

                    case EbnfParser.regex:
                        pc = ParseContext.Create(cc.Value);
                        pc.EnsureStarted();
                        pc.Advance();
                        pc.TryReadUntil('\'', '\\', false);
                        result = new EbnfRegexExpression(pc.GetCapture());
                        return(msgs);

                    case EbnfParser.literal:
                        pc = ParseContext.Create(cc.Value);
                        pc.EnsureStarted();
                        pc.Advance();
                        pc.TryReadUntil('\"', '\\', false);
                        result = new EbnfLiteralExpression(pc.GetCapture());
                        return(msgs);

                    case EbnfParser.lbrace:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        result = new EbnfRepeatExpression(result);
                        if (EbnfParser.rbracePlus == c.Children[c.Children.Count - 1].SymbolId)
                        {
                            ((EbnfRepeatExpression)result).IsOptional = false;
                        }
                        return(msgs);

                    case EbnfParser.lbracket:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        result = new EbnfOptionalExpression(result);
                        return(msgs);

                    case EbnfParser.lparen:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        return(msgs);

                    default:
                        break;
                    }
                }
            }
            return(msgs);
        }
예제 #13
0
 /// <summary>
 /// Parses a regular expresion from the specified string
 /// </summary>
 /// <param name="string">The string</param>
 /// <param name="accepting">The symbol reported when accepting the specified expression</param>
 /// <returns>A new expression that represents the regular expression</returns>
 public static RegexExpression Parse(IEnumerable <char> @string)
 => Parse(ParseContext.Create(@string));
예제 #14
0
        void Colorize()
        {
#if PARSER
            if (_colorizing)
            {
                return;
            }
            _colorizing = true;
            var text = EditBox.Text;
            var sel  = EditBox.SelectionStart;
            EditBox.Clear();
            var sb = new StringBuilder();
            sb.Append("{\\rtf1");
            sb.Append(RtfUtility.ToColorTable(
                          Color.Black,
                          Color.DarkGreen,
                          Color.DarkRed,
                          Color.DarkOliveGreen,
                          Color.Blue,
                          Color.DarkCyan,
                          Color.BlueViolet,
                          Color.DarkGray));
            var p    = new EbnfParser(ParseContext.Create(text));
            var pos  = 0L;
            var cols = new Stack <int>();
            cols.Push(0);
            while (p.Read())
            {
                switch (p.NodeType)
                {
                case LLNodeType.NonTerminal:
                    switch (p.SymbolId)
                    {
                    case EbnfParser.attribute:
                        cols.Push(3);
                        break;

                    case EbnfParser.symbol:
                    case EbnfParser.expressions:
                        cols.Push(4);
                        break;

                    default:
                        cols.Push(0);
                        break;
                    }
                    break;

                case LLNodeType.EndNonTerminal:
                    cols.Pop();
                    break;

                case LLNodeType.Terminal:
                case LLNodeType.Error:
                    if (p.Position > pos)
                    {
                        sb.Append("\\cf1 ");
                        sb.Append(RtfUtility.Escape(text.Substring((int)pos, (int)(p.Position - pos))));
                    }
                    if (LLNodeType.Error == p.NodeType)
                    {
                        sb.Append("\\cf2");
                    }
                    else
                    {
                        sb.Append("\\cf");

                        switch (p.SymbolId)
                        {
                        case EbnfParser.literal:
                            sb.Append(5);
                            break;

                        case EbnfParser.regex:
                            sb.Append(6);
                            break;


                        default:
                            sb.Append(cols.Peek());
                            break;
                        }
                    }
                    sb.Append(RtfUtility.Escape(p.Value));
                    pos = p.Position + p.Value.Length;
                    break;
                }
            }
            sb.Append("}");
            System.Diagnostics.Debug.WriteLine(sb.ToString());
            EditBox.Rtf            = sb.ToString();
            EditBox.SelectionStart = sel;
            _colorizing            = false;
#endif
        }
예제 #15
0
파일: CharFA.cs 프로젝트: iplayfast/fa
 /// <summary>
 /// Parses a regular expresion from the specified string
 /// </summary>
 /// <param name="string">The string</param>
 /// <param name="accepting">The symbol reported when accepting the specified expression</param>
 /// <returns>A new machine that matches the regular expression</returns>
 public static CharFA <TAccept> Parse(IEnumerable <char> @string, TAccept accept = default(TAccept)) => _Parse(ParseContext.Create(@string), accept);
예제 #16
0
 public static XbnfDocument Parse(IEnumerable <char> @string)
 => Parse(ParseContext.Create(@string));
예제 #17
0
파일: LexDocument.cs 프로젝트: wushian/pck
        internal static LexDocument Parse(ParseContext pc)
        {
            var result = new LexDocument();

            while (-1 != pc.Current)
            {
                var line     = pc.Line;
                var column   = pc.Column;
                var position = pc.Position;
                LexNode.SkipCommentsAndWhitespace(pc);
                while ('\n' == pc.Current)
                {
                    pc.Advance();
                    LexNode.SkipCommentsAndWhitespace(pc);
                }
                var id = LexNode.ParseIdentifier(pc);
                if (string.IsNullOrEmpty(id))
                {
                    pc.Advance();
                    LexNode.SkipCommentsAndWhitespace(pc);
                    continue;
                }
                LexNode.SkipCommentsAndWhitespace(pc);

                pc.Expecting(':', '-', '=');
                if (':' == pc.Current)                 // attribute set
                {
                    pc.Advance();
                    var d = new LexAttributeList();
                    while (-1 != pc.Current && '\n' != pc.Current)
                    {
                        var attr = LexAttribute.Parse(pc);
                        d.Add(attr);

                        LexNode.SkipCommentsAndWhitespace(pc);
                        pc.Expecting('\n', ',', -1);
                        if (',' == pc.Current)
                        {
                            pc.Advance();
                        }
                    }
                    result.AttributeSets.Add(id, d);
                    LexNode.SkipCommentsAndWhitespace(pc);
                }
                else if ('=' == pc.Current)
                {
                    pc.Advance();
                    LexNode.SkipCommentsAndWhitespace(pc);
                    pc.Expecting('\'');
                    pc.Advance();
                    var l = pc.CaptureBuffer.Length;
                    pc.TryReadUntil('\'', '\\', false);
                    pc.Expecting('\'');
                    pc.Advance();
                    var rx = pc.GetCapture(l);
                    // make sure to capture the line numbers properly:
                    var rpc = ParseContext.Create(rx);
                    rpc.EnsureStarted();
                    rpc.SetLocation(pc.Line, pc.Column, pc.Position);
                    var rule = new LexRule(id, RegexExpression.Parse(rpc));
                    rule.SetLocation(line, column, position);
                    result.Rules.Add(rule);
                }
                else if ('-' == pc.Current)
                {
                    pc.TrySkipUntil('\n', true);
                }
                LexNode.SkipCommentsAndWhitespace(pc);
                if ('\n' == pc.Current)
                {
                    pc.Advance();
                }
            }
            return(result);
        }