@@ -1548,3 +1548,120 @@ insert("$", "$");
15481548 exp => exp plus term
15491549 exp => 2+6*(6+4*7-2)+sin(a,b,c,d) + cos()*pi
15501550```
1551+
1552+ ## L-Attributed
1553+
1554+ ```
1555+ // --------------------------------------
1556+ //
1557+ // Scanner Generator
1558+ //
1559+ // --------------------------------------
1560+
1561+ var scanner_gen = new ScannerGenerator();
1562+
1563+ scanner_gen.PushRule("", @"[\r\n ]"); // Skip characters
1564+ scanner_gen.PushRule("end", ";");
1565+ scanner_gen.PushRule("plus", @"\+");
1566+ scanner_gen.PushRule("minus", @"\-");
1567+ scanner_gen.PushRule("multiple", @"\*");
1568+ scanner_gen.PushRule("divide", @"\/");
1569+ scanner_gen.PushRule("op_open", @"\(");
1570+ scanner_gen.PushRule("op_close", @"\)");
1571+ scanner_gen.PushRule("num", @"[0-9]+(\.[0-9]+)?([Ee][\+\-]?[0-9]+)?");
1572+
1573+ // Scanner Instance
1574+ scanner_gen.Generate();
1575+ var scanner = scanner_gen.CreateScannerInstance();
1576+
1577+ // --------------------------------------
1578+ //
1579+ // Parser Generator
1580+ //
1581+ // --------------------------------------
1582+
1583+ var parser_gen = new ParserGenerator.ParserGenerator();
1584+
1585+ // Non-Terminals
1586+ var S = parser_gen.CreateNewProduction("S", false);
1587+ var E = parser_gen.CreateNewProduction("E", false);
1588+
1589+ // Terminals
1590+ var equal = parser_gen.CreateNewProduction("equal");
1591+ var multiple = parser_gen.CreateNewProduction("multiple");
1592+ var divide = parser_gen.CreateNewProduction("divide");
1593+ var plus = parser_gen.CreateNewProduction("plus");
1594+ var minus = parser_gen.CreateNewProduction("minus");
1595+ var num = parser_gen.CreateNewProduction("num");
1596+ var op_open = parser_gen.CreateNewProduction("op_open");
1597+ var op_close = parser_gen.CreateNewProduction("op_close");
1598+ var end = parser_gen.CreateNewProduction("end");
1599+
1600+ // right associativity, -
1601+ parser_gen.PushConflictSolver(false, new Tuple<ParserProduction, int>(E, 4));
1602+ // left associativity, *, /
1603+ parser_gen.PushConflictSolver(true, multiple, divide);
1604+ // left associativity, +, -
1605+ parser_gen.PushConflictSolver(true, plus, minus);
1606+
1607+ S |= E + end + ParserAction.Create(x => x.UserContents = x.Childs[0].UserContents);
1608+ E |= E + plus + E + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents + (double)x.Childs[2].UserContents);
1609+ E |= E + minus + E + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents - (double)x.Childs[2].UserContents);
1610+ E |= E + multiple + E + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents * (double)x.Childs[2].UserContents);
1611+ E |= E + divide + E + ParserAction.Create(x => x.UserContents = (double)x.Childs[0].UserContents / (double)x.Childs[2].UserContents);
1612+ E |= minus + E + ParserAction.Create(x => x.UserContents = -(double)x.Childs[1].UserContents);
1613+ E |= op_open + E + op_close + ParserAction.Create(x => x.UserContents = x.Childs[1].UserContents);
1614+ E |= num + ParserAction.Create(x => x.UserContents = double.Parse(x.Contents));
1615+
1616+ parser_gen.PushStarts(S);
1617+ parser_gen.GenerateLALR();
1618+
1619+ // Parser Instance
1620+ var parser = parser_gen.CreateShiftReduceParserInstance();
1621+
1622+ // --------------------------------------
1623+ //
1624+ // Test
1625+ //
1626+ // --------------------------------------
1627+
1628+ var test_lines = File.ReadAllLines(InputFileName);
1629+ var builder = new StringBuilder();
1630+
1631+ foreach (var line in test_lines)
1632+ {
1633+ parser.Clear();
1634+ scanner.AllocateTarget(line);
1635+
1636+ Action<string, string> insert = (string x, string y) =>
1637+ {
1638+ parser.Insert(x, y);
1639+ if (parser.Error()) throw new Exception();
1640+ while (parser.Reduce())
1641+ {
1642+ parser.Insert(x, y);
1643+ if (parser.Error()) throw new Exception();
1644+ }
1645+ };
1646+
1647+ try
1648+ {
1649+ while(scanner.Valid())
1650+ {
1651+ var ss = scanner.Next();
1652+ if (scanner.Error()) throw new Exception();
1653+ insert(ss.Item1, ss.Item2);
1654+ }
1655+ if (scanner.Error()) throw new Exception();
1656+ insert("$", "$");
1657+
1658+ Console.WriteLine((double)(parser.Tree.root.UserContents));
1659+ builder.Append($"{(double)(parser.Tree.root.UserContents)}\r\n");
1660+ }
1661+ catch (Exception ex)
1662+ {
1663+ Console.WriteLine("Error! Check test case!");
1664+ builder.Append("Error\r\n");
1665+ }
1666+ }
1667+ ```
0 commit comments