Пример #1
0
        /// <summary>
        /// ESRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var expr = gen.CreateNewProduction("expr", false);

            // Terminals
            //var id = gen.CreateNewProduction("id");
            var num = gen.CreateNewProduction("num");
            //var str = gen.CreateNewProduction("str");
            var plus     = gen.CreateNewProduction("plus");
            var minus    = gen.CreateNewProduction("minus");
            var multiple = gen.CreateNewProduction("multiple");
            var divide   = gen.CreateNewProduction("divide");
            //var loop = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");

            //var pp_open = gen.CreateNewProduction("pp_open"); // [
            //var pp_close = gen.CreateNewProduction("pp_close"); // ]
            //var equal = gen.CreateNewProduction("equal");
            //var to = gen.CreateNewProduction("to");
            //var scolon = gen.CreateNewProduction("scolon");
            //var comma = gen.CreateNewProduction("comma");
            //var _foreach = gen.CreateNewProduction("foreach");
            //var _if = gen.CreateNewProduction("if");
            //var _else = gen.CreateNewProduction("else");

            expr |= num + ParserAction.Create(x => x.UserContents = double.Parse(x.Contents));
            expr |= expr + plus + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents + (double)x.Childs[2].UserContents);
            expr |= expr + minus + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents - (double)x.Childs[2].UserContents);
            expr |= expr + multiple + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents * (double)x.Childs[2].UserContents);
            expr |= expr + divide + expr + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents / (double)x.Childs[2].UserContents);
            expr |= minus + expr + ParserAction.Create(x => x.UserContents = -(double)x.Childs[1].UserContents);
            expr |= op_open + expr + op_close + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);

            // right associativity, -
            gen.PushConflictSolver(false, new Tuple <ParserProduction, int>(expr, 5));
            // left associativity, *, /
            gen.PushConflictSolver(true, multiple, divide);
            // left associativity, +, -
            gen.PushConflictSolver(true, plus, minus);

            try
            {
                gen.PushStarts(expr);
                gen.PrintProductionRules();
                gen.GenerateLALR();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateShiftReduceParserInstance());
        }
Пример #2
0
        static ShiftReduceParser CreateJSonParser()
        {
            var gen = new ParserGenerator();

            var JSON     = gen.CreateNewProduction("JSON", false);
            var ARRAY    = gen.CreateNewProduction("ARRAY", false);
            var OBJECT   = gen.CreateNewProduction("OBJECT", false);
            var MEMBERS  = gen.CreateNewProduction("MEMBERS", false);
            var PAIR     = gen.CreateNewProduction("PAIR", false);
            var ELEMENTS = gen.CreateNewProduction("ELEMENTS", false);
            var VALUE    = gen.CreateNewProduction("VALUE", false);

            var object_starts = gen.CreateNewProduction("object_starts");
            var object_ends   = gen.CreateNewProduction("object_ends");
            var comma         = gen.CreateNewProduction("comma");
            var v_pair        = gen.CreateNewProduction("v_pair");
            var array_starts  = gen.CreateNewProduction("array_starts");
            var array_ends    = gen.CreateNewProduction("array_ends");
            var v_true        = gen.CreateNewProduction("v_true");
            var v_false       = gen.CreateNewProduction("v_false");
            var v_null        = gen.CreateNewProduction("v_null");
            var v_string      = gen.CreateNewProduction("v_string");
            var v_number      = gen.CreateNewProduction("v_number");

            JSON    |= OBJECT + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            JSON    |= ARRAY + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            OBJECT  |= object_starts + object_ends + ParserAction.Create(x => x.UserContents = new json_object());
            OBJECT  |= object_starts + MEMBERS + object_ends + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);
            MEMBERS |= PAIR + ParserAction.Create(x => {
                var jo = new json_object();
                jo.keyvalue.Add(new KeyValuePair <string, json_value>(x.Childs[0].Childs[0].Contents, x.Childs[0].Childs[2].UserContents as json_value));
                x.UserContents = jo;
            });
            MEMBERS |= PAIR + comma + MEMBERS + ParserAction.Create(x => {
                var jo = x.Childs[2].UserContents as json_object;
                jo.keyvalue.Insert(0, new KeyValuePair <string, json_value>(x.Childs[0].Childs[0].Contents, x.Childs[0].Childs[2].UserContents as json_value));
                x.UserContents = jo;
            });
            PAIR     |= v_string + v_pair + VALUE + ParserAction.Create(x => { });
            ARRAY    |= array_starts + array_ends + ParserAction.Create(x => x.UserContents = new json_array());
            ARRAY    |= array_starts + ELEMENTS + array_ends + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);
            ELEMENTS |= VALUE + ParserAction.Create(x => {
                var ja = new json_array();
                ja.array.Add(x.Childs[0].UserContents as json_value);
                x.UserContents = ja;
            });
            ELEMENTS |= VALUE + comma + ELEMENTS + ParserAction.Create(x => {
                var ja = x.Childs[2].UserContents as json_array;
                ja.array.Insert(0, x.Childs[0].UserContents as json_value);
                x.UserContents = ja;
            });
            VALUE |= v_string + ParserAction.Create(x => x.UserContents = new json_string {
                str = x.Contents
            });
            VALUE |= v_number + ParserAction.Create(x => x.UserContents = new json_numeric {
                numstr = x.Contents
            });
            VALUE |= OBJECT + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            VALUE |= ARRAY + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
            VALUE |= v_true + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_true
            });
            VALUE |= v_false + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_false
            });
            VALUE |= v_null + ParserAction.Create(x => x.UserContents = new json_state {
                type = json_token.v_null
            });

            gen.PushStarts(JSON);
            gen.PrintProductionRules();
            gen.Generate();
            gen.PrintStates();
            gen.PrintTable();

#if false
            Console.WriteLine(gen.GlobalPrinter.ToString());
            Console.WriteLine(gen.CreateExtendedShiftReduceParserInstance().ToCSCode("json_parser"));
#endif

            return(gen.CreateExtendedShiftReduceParserInstance());
        }
Пример #3
0
        static void ProcessPGSample()
        {
            var gen = new ParserGenerator();

            // Non-Terminals
            var E = gen.CreateNewProduction("E", false);
            //var T = gen.CreateNewProduction("T", false);
            //var F = gen.CreateNewProduction("F", false);
            //var func = gen.CreateNewProduction("func", false);
            //var arguments = gen.CreateNewProduction("args", false);

            // Terminals
            var plus     = gen.CreateNewProduction("+");   // +
            var minus    = gen.CreateNewProduction("-");   // -
            var multiple = gen.CreateNewProduction("*");   // *
            var divide   = gen.CreateNewProduction("/");   // /
            //var id = gen.CreateNewProduction("id");             // [_$a-zA-Z][_$a-zA-Z0-9]*
            var op_open  = gen.CreateNewProduction("(");   // (
            var op_close = gen.CreateNewProduction(")");   // )
            var num      = gen.CreateNewProduction("num"); // [0-9]+

            //var split = gen.CreateNewProduction("split");       // ,

            //exp |= exp + plus + term;
            //exp |= exp + minus + term;
            //exp |= term;
            //term |= term + multiple + factor;
            //term |= term + divide + factor;
            //term |= factor;
            //factor |= op_open + exp + op_close;
            //factor |= num;
            //factor |= id;
            //factor |= func;
            //func |= id + op_open + arguments + op_close;
            //arguments |= id;
            //arguments |= arguments + split + id;
            //arguments |= ParserGenerator.EmptyString;

            E |= E + plus + E + ParserAction.Create(x => { });;
            E |= E + minus + E + ParserAction.Create(x => { });;
            E |= E + multiple + E + ParserAction.Create(x => { });;
            E |= E + divide + E + ParserAction.Create(x => { });;
            E |= minus + E + ParserAction.Create(x => { });;
            E |= op_open + E + op_close + ParserAction.Create(x => { });;
            E |= num + ParserAction.Create(x => { });;

            gen.PushConflictSolver(false, new Tuple <ParserProduction, int>(E, 4));
            gen.PushConflictSolver(true, multiple, divide);
            gen.PushConflictSolver(true, plus, minus);

            gen.PushStarts(E);
            gen.PrintProductionRules();
            gen.GenerateLALR2();
            gen.PrintStates();
            gen.PrintTable();

            Console.Instance.WriteLine(gen.GlobalPrinter.ToString());
            Console.Instance.WriteLine(gen.CreateShiftReduceParserInstance().ToCSCode("Calculator"));

            //////////////////////////////////////////////////////

            //var scanner_gen = new ScannerGenerator();
            //
            //scanner_gen.PushRule("", @"[\r\n ]");  // Skip characters
            //scanner_gen.PushRule("+", @"\+");
            //scanner_gen.PushRule("-", @"\-");
            //scanner_gen.PushRule("*", @"\*");
            //scanner_gen.PushRule("/", @"\/");
            //scanner_gen.PushRule("(", @"\(");
            //scanner_gen.PushRule(")", @"\)");
            //scanner_gen.PushRule("num", @"[0-9]+(\.[0-9]+)?([Ee][\+\-]?[0-9]+)?");
            //scanner_gen.Generate();
            //var ss = scanner_gen.CreateScannerInstance();
            //var pp = gen.CreateShiftReduceParserInstance();
            //
            //Action<string, string, int, int> insert = (string x, string y, int a, int b) =>
            //{
            //    pp.Insert(x, y);
            //    if (pp.Error()) throw new Exception($"[COMPILER] Parser error! L:{a}, C:{b}");
            //    while (pp.Reduce())
            //    {
            //        var l = pp.LatestReduce();
            //        Console.Instance.Write(l.Production.PadLeft(8) + " => ");
            //        Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Production)));
            //        Console.Instance.Write(l.Production.PadLeft(8) + " => ");
            //        Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents)));
            //        pp.Insert(x, y);
            //        if (pp.Error()) throw new Exception($"[COMPILER] Parser error! L:{a}, C:{b}");
            //    }
            //};
            //
            //try
            //{
            //    int ll = 0;
            //    var line = "5-(4+2*3-1)/(6+-5)";
            //        ss.AllocateTarget(line.Trim());
            //
            //        while (ss.Valid())
            //        {
            //            var tk = ss.Next();
            //            if (ss.Error())
            //                throw new Exception("[COMPILER] Tokenize error! '" + tk + "'");
            //            insert(tk.Item1, tk.Item2, ll, tk.Item4);
            //        }
            //
            //    if (pp.Error()) throw new Exception();
            //    insert("$", "$", -1, -1);
            //
            //    var tree = pp.Tree;
            //    CALtoCS.PrintTree(tree.root, "", true);
            //}
            //catch (Exception e)
            //{
            //    Console.Instance.WriteLine(e.Message);
            //}
        }
Пример #4
0
        /// <summary>
        /// SRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ExtendedShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var script   = gen.CreateNewProduction("script", false);
            var line     = gen.CreateNewProduction("line", false);
            var lines    = gen.CreateNewProduction("lines", false);
            var expr     = gen.CreateNewProduction("expr", false);
            var block    = gen.CreateNewProduction("block", false);
            var iblock   = gen.CreateNewProduction("iblock", false);
            var index    = gen.CreateNewProduction("index", false);
            var variable = gen.CreateNewProduction("variable", false);
            var argument = gen.CreateNewProduction("argument", false);
            var function = gen.CreateNewProduction("function", false);
            var runnable = gen.CreateNewProduction("runnable", false);

            // Terminals
            var name     = gen.CreateNewProduction("name");
            var _const   = gen.CreateNewProduction("const"); // number | string
            var loop     = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");
            var pp_open  = gen.CreateNewProduction("pp_open");  // [
            var pp_close = gen.CreateNewProduction("pp_close"); // ]
            var equal    = gen.CreateNewProduction("equal");
            var to       = gen.CreateNewProduction("to");
            var scolon   = gen.CreateNewProduction("scolon");
            var comma    = gen.CreateNewProduction("comma");
            var plus     = gen.CreateNewProduction("plus");     // +
            var minus    = gen.CreateNewProduction("minus");    // -
            var multiple = gen.CreateNewProduction("multiple"); // *
            var divide   = gen.CreateNewProduction("divide");   // /
            var _foreach = gen.CreateNewProduction("foreach");
            var _if      = gen.CreateNewProduction("if");
            var _else    = gen.CreateNewProduction("else");

            script |= lines + ParserAction.Create((m, f, b, x) => {
                var module = new LPModule();
                var sfunc  = module.CreateFunction("start");
                var bb     = sfunc.CreateBasicBlock();
                x.Childs[0].Action(module, sfunc, bb, x.Childs[0]);
                x.UserContents = module;
            });
            script |= ParserGenerator.EmptyString + ParserAction.Create((m, f, b, x) => {
                x.UserContents = new LPModule();
            });

            block |= pp_open + iblock + pp_close + ParserAction.Create((m, f, b, x) => { });
            block |= line + ParserAction.Create((m, f, b, x) => { });

            iblock |= block + ParserAction.Create((m, f, b, x) => { });
            iblock |= lines + ParserAction.Create((m, f, b, x) => { });
            iblock |= ParserGenerator.EmptyString + ParserAction.Create((m, f, b, x) => { });

            line |= expr + ParserAction.Create((m, f, b, x) => { });

            lines |= expr + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
            });
            lines |= expr + lines + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
                x.Childs[1].Action(m, f, b, x.Childs[1]);
            });

            expr |= function + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x.Childs[0]);
            });
            expr |= name + equal + index + ParserAction.Create((m, f, b, x) => { });
            expr |= runnable + ParserAction.Create((m, f, b, x) => { });

            function |= name + op_open + op_close + ParserAction.Create((m, f, b, x) => {
                var caller      = m.CreateFunction(x.Childs[0].Contents);
                caller.IsExtern = true;
                var ci          = LPCallOperator.Create(caller, new List <LPUser>());
                b.Insert(ci);
                x.UserContents = ci;
            });
            function |= name + op_open + argument + op_close + ParserAction.Create((m, f, b, x) => {
                var caller      = m.CreateFunction(x.Childs[0].Contents);
                caller.IsExtern = true;
                x.Childs[2].Action(m, f, b, x);
                var ci = LPCallOperator.Create(caller, x.Childs[2].UserContents as List <LPUser>);
                b.Insert(ci);
                x.UserContents = ci;
            });

            argument |= index + ParserAction.Create((m, f, b, x) => {
                x.Childs[0].Action(m, f, b, x);
                x.UserContents = new List <LPUser> {
                    x.Childs[0].UserContents as LPUser
                };
            });
            argument |= index + comma + argument + ParserAction.Create((m, f, b, x) => { });

            index |= variable + ParserAction.Create((m, f, b, x) => { });
            index |= variable + pp_open + variable + pp_close + ParserAction.Create((m, f, b, x) => { });
            index |= index + plus + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + minus + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + multiple + index + ParserAction.Create((m, f, b, x) => { });
            index |= index + divide + index + ParserAction.Create((m, f, b, x) => { });
            index |= minus + index + ParserAction.Create((m, f, b, x) => { });
            index |= op_open + index + op_close + ParserAction.Create((m, f, b, x) => { });

            variable |= name + ParserAction.Create((m, f, b, x) => { });
            variable |= function + ParserAction.Create((m, f, b, x) => { });
            variable |= _const + ParserAction.Create((m, f, b, x) => { x.UserContents = LPConstant.Create(x.Childs[0].Contents); });

            runnable |= loop + op_open + name + equal + index + to + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _foreach + op_open + name + scolon + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _if + op_open + index + op_close + block + ParserAction.Create((m, f, b, x) => { });
            runnable |= _if + op_open + index + op_close + block + _else + block + ParserAction.Create((m, f, b, x) => { });

            gen.PushConflictSolver(true, _else);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(runnable, 2));
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(index, 6));
            gen.PushConflictSolver(false, multiple, divide);
            gen.PushConflictSolver(false, plus, minus);

            //gen.PushConflictSolver(true, new Tuple<ParserProduction, int>(index, 1));
            gen.PushConflictSolver(false, pp_open);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(index, 0));

            try
            {
                gen.PushStarts(script);
                gen.PrintProductionRules();
                gen.GenerateLALR2();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateExtendedShiftReduceParserInstance());
        }
Пример #5
0
        /// <summary>
        /// SRCAL의 파서제너레이터를 생성합니다.
        /// </summary>
        /// <returns></returns>
        private ShiftReduceParser get_pargen()
        {
            if (pargen != null)
            {
                return(pargen);
            }

            var gen = new ParserGenerator();

            // Non-Terminals
            var script   = gen.CreateNewProduction("script", false);
            var line     = gen.CreateNewProduction("line", false);
            var lines    = gen.CreateNewProduction("lines", false);
            var expr     = gen.CreateNewProduction("expr", false);
            var block    = gen.CreateNewProduction("block", false);
            var iblock   = gen.CreateNewProduction("iblock", false);
            var index    = gen.CreateNewProduction("index", false);
            var variable = gen.CreateNewProduction("variable", false);
            var argument = gen.CreateNewProduction("argument", false);
            var function = gen.CreateNewProduction("function", false);
            var runnable = gen.CreateNewProduction("runnable", false);

            // Terminals
            var name     = gen.CreateNewProduction("name");
            var _const   = gen.CreateNewProduction("const"); // number | string
            var loop     = gen.CreateNewProduction("loop");
            var op_open  = gen.CreateNewProduction("op_open");
            var op_close = gen.CreateNewProduction("op_close");
            var pp_open  = gen.CreateNewProduction("pp_open");  // [
            var pp_close = gen.CreateNewProduction("pp_close"); // ]
            var equal    = gen.CreateNewProduction("equal");
            var to       = gen.CreateNewProduction("to");
            var scolon   = gen.CreateNewProduction("scolon");
            var comma    = gen.CreateNewProduction("comma");
            var _foreach = gen.CreateNewProduction("foreach");
            var _if      = gen.CreateNewProduction("if");
            var _else    = gen.CreateNewProduction("else");

            script |= lines + ParserAction.Create(x => { });
            script |= ParserGenerator.EmptyString + ParserAction.Create(x => { });

            block |= pp_open + iblock + pp_close + ParserAction.Create(x => { });
            block |= line + ParserAction.Create(x => { });

            iblock |= block + ParserAction.Create(x => { });
            iblock |= lines + ParserAction.Create(x => { });
            iblock |= ParserGenerator.EmptyString + ParserAction.Create(x => { });

            line |= expr + ParserAction.Create(x => { });

            lines |= expr + ParserAction.Create(x => { });
            lines |= expr + lines + ParserAction.Create(x => { });

            expr |= function + ParserAction.Create(x => { });
            expr |= name + equal + index + ParserAction.Create(x => { });
            expr |= runnable + ParserAction.Create(x => { });

            function |= name + op_open + op_close + ParserAction.Create(x => { });
            function |= name + op_open + argument + op_close + ParserAction.Create(x => { });

            argument |= index + ParserAction.Create(x => { });
            argument |= index + comma + argument + ParserAction.Create(x => { });

            index |= variable + ParserAction.Create(x => { });
            index |= variable + pp_open + variable + pp_close + ParserAction.Create(x => { });

            variable |= name + ParserAction.Create(x => { });
            variable |= function + ParserAction.Create(x => { });
            variable |= _const + ParserAction.Create(x => { });

            runnable |= loop + op_open + name + equal + index + to + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _foreach + op_open + name + scolon + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _if + op_open + index + op_close + block + ParserAction.Create(x => { });
            runnable |= _if + op_open + index + op_close + block + _else + block + ParserAction.Create(x => { });

            gen.PushConflictSolver(true, _else);
            gen.PushConflictSolver(true, new Tuple <ParserProduction, int>(runnable, 2));

            try
            {
                gen.PushStarts(script);
                gen.PrintProductionRules();
                gen.GenerateLALR();
                gen.PrintStates();
                gen.PrintTable();
            }
            catch (Exception e)
            {
                Console.Console.Instance.WriteLine(e.Message);
            }

            Console.Console.Instance.WriteLine(gen.GlobalPrinter.ToString());

            return(pargen = gen.CreateShiftReduceParserInstance());
        }