/// <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()); }
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()); }
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); //} }
/// <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()); }
/// <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()); }