static void Main(string[] args) { ParserGenerator.ParserGenerator pg = new ParserGenerator.ParserGenerator(); //pg.parseGrammar(); //while(true); }
public static void Main(string[] args) { var gen = new ParserGenerator(); // Non-Terminals var exp = gen.CreateNewProduction("exp", false); var term = gen.CreateNewProduction("term", false); var factor = gen.CreateNewProduction("factor", false); var func = gen.CreateNewProduction("func", false); var arguments = gen.CreateNewProduction("args", false); var args_left = gen.CreateNewProduction("args_left", false); // Terminals var plus = gen.CreateNewProduction("plus"); // + var minus = gen.CreateNewProduction("minus"); // - var multiple = gen.CreateNewProduction("multiple"); // * var divide = gen.CreateNewProduction("divide"); // / var id = gen.CreateNewProduction("id"); // [_$a-zA-Z][_$a-zA-Z0-9]* var op_open = gen.CreateNewProduction("op_open"); // ( var op_close = gen.CreateNewProduction("op_close"); // ) 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 |= args_left + id; arguments |= ParserGenerator.EmptyString; args_left |= args_left + id + split; args_left |= ParserGenerator.EmptyString; gen.PushStarts(exp); gen.Generate(); gen.PrintStates(); var slr = gen.CreateShiftReduceParserInstance(); // 2*4+5$ Action <string, string> insert = (string x, string y) => { slr.Insert(x, y); while (slr.Reduce()) { var l = slr.LatestReduce(); Console.Write(l.Produnction.PadLeft(8) + " => "); Console.WriteLine(string.Join(" ", l.Childs.Select(z => z.Produnction))); Console.Write(l.Produnction.PadLeft(8) + " => "); Console.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents))); slr.Insert(x, y); } }; var sg2 = new ScannerGenerator(); sg2.PushRule("", "[\\r\\n ]"); sg2.PushRule("plus", "\\+"); sg2.PushRule("minus", "-"); sg2.PushRule("multiple", "\\*"); sg2.PushRule("divide", "\\/"); sg2.PushRule("op_open", "\\("); sg2.PushRule("op_close", "\\)"); sg2.PushRule("split", ","); sg2.PushRule("id", "[a-z][a-z0-9]*"); sg2.PushRule("num", "[0-9]+"); sg2.Generate(); sg2.CreateScannerInstance(); var scanner2 = sg2.CreateScannerInstance(); scanner2.AllocateTarget("2+6*(6+4*7-2)+sin(a,b)+cos()*pi"); while (scanner2.Valid()) { var ss = scanner2.Next(); insert(ss.Item1, ss.Item2); } insert("$", "$"); }
private void bPGG_Click(object sender, EventArgs e) { try { var gen = new ParserGenerator.ParserGenerator(); var non_terminals = new Dictionary <string, ParserProduction>(); var terminals = new Dictionary <string, ParserProduction>(); terminals.Add("''", ParserGenerator.ParserGenerator.EmptyString); foreach (var nt in rtbPGNT.Text.Split(',')) { non_terminals.Add(nt.Trim(), gen.CreateNewProduction(nt.Trim(), false)); } foreach (var t in rtbPGT.Lines) { if (t.Trim() == "") { continue; } var name = t.Split(',')[0]; var pp = t.Substring(name.Length + 1).Trim(); terminals.Add(pp, gen.CreateNewProduction(name.Trim())); } var prec = new Dictionary <string, List <Tuple <ParserProduction, int> > >(); foreach (var pp in rtbPGPR.Lines) { if (pp.Trim() == "") { continue; } var split = pp.Split(new[] { "->" }, StringSplitOptions.None); var left = split[0].Trim(); var right = split[1].Split(' '); var prlist = new List <ParserProduction>(); bool stay_prec = false; foreach (var ntt in right) { if (string.IsNullOrEmpty(ntt)) { continue; } if (ntt == "%prec") { stay_prec = true; continue; } if (stay_prec) { if (!prec.ContainsKey(ntt)) { prec.Add(ntt, new List <Tuple <ParserProduction, int> >()); } prec[ntt].Add(new Tuple <ParserProduction, int>(non_terminals[left], non_terminals[left].sub_productions.Count)); continue; } if (non_terminals.ContainsKey(ntt)) { prlist.Add(non_terminals[ntt]); } else if (terminals.ContainsKey(ntt)) { prlist.Add(terminals[ntt]); } else { rtbPGS.Text = $"Production rule build error!\r\n{ntt} is neither non-terminal nor terminal!\r\nDeclare the token-name!"; return; } } non_terminals[left].sub_productions.Add(prlist); } for (int i = rtbPGC.Lines.Length - 1; i >= 0; i--) { var line = rtbPGC.Lines[i].Trim(); if (line == "") { continue; } var tt = line.Split(' ')[0]; var rr = line.Substring(tt.Length).Trim().Split(','); var left = true; var items1 = new List <Tuple <ParserProduction, int> >(); var items2 = new List <ParserProduction>(); if (tt == "%right") { left = false; } foreach (var ii in rr.Select(x => x.Trim())) { if (string.IsNullOrEmpty(ii)) { continue; } if (terminals.ContainsKey(ii)) { items2.Add(terminals[ii]); } else if (prec.ContainsKey(ii)) { items1.AddRange(prec[ii]); } else { rtbPGS.Text = $"Conflict rule applying error!\r\n{ii} is neither terminal nor %prec!\r\nDeclare the token-name!"; return; } } if (items1.Count > 0) { gen.PushConflictSolver(left, items1.ToArray()); } else { gen.PushConflictSolver(left, items2.ToArray()); } } rtbPGS.Clear(); gen.GlobalPrinter.Clear(); gen.PushStarts(non_terminals[rtbPGNT.Text.Split(',')[0].Trim()]); if (rbSLR.Checked == true) { gen.Generate(); } else if (rbLALR.Checked == true) { gen.GenerateLALR(); } else { gen.GenerateLR1(); } gen.PrintStates(); gen.PrintTable(); rtbPGS.AppendText(gen.GlobalPrinter.ToString()); srparser = gen.CreateShiftReduceParserInstance(); } catch (Exception ex) { rtbPGS.AppendText("Generate Error!\r\n" + ex.Message + "\r\n" + ex.StackTrace); } }
public LL1Parser(string contents) { this.scanner = new TokenScanner(contents); parsetable = new ParserGenerator.ParserGenerator(); }