Advertisement
vasy1

Untitled

Jun 7th, 2023
639
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.87 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. public class LRParser
  5. {
  6.     private Grammar grammar;
  7.     private LRTable table;
  8.  
  9.     public LRParser(Grammar grammar, LRTable table)
  10.     {
  11.         this.grammar = grammar;
  12.         this.table = table;
  13.     }
  14.  
  15.  
  16. // Метод для разбора входной строки
  17. public void Parse(string input)
  18. {
  19.     // Создаем стек состояний и стек символов
  20.     Stack<int> stateStack = new Stack<int>();
  21.     Stack<Symbol> symbolStack = new Stack<Symbol>();
  22.  
  23.     stateStack.Push(0); // Инициализация начального состояния
  24.  
  25.     int index = 0;
  26.     while (index < input.Length)
  27.     {
  28.         int currentState = stateStack.Peek(); // Получаем текущее состояние
  29.         char currentInput = input[index]; // Получаем текущий входной символ
  30.         ActionTableEntry entry = table.GetAction(currentState, currentInput); // Получаем запись из таблицы действий
  31.  
  32.         if (entry == null)
  33.         {
  34.             Console.WriteLine("Error: Invalid input at index " + index);
  35.             return;
  36.         }
  37.  
  38.         if (entry.Action == ActionType.Shift) // Если действие - сдвиг
  39.         {
  40.             stateStack.Push(entry.Value); // Переходим к новому состоянию
  41.             symbolStack.Push(new Symbol(currentInput)); // Добавляем текущий входной символ в стек символов
  42.             index++; // Переходим к следующему символу входной строки
  43.         }
  44.         else if (entry.Action == ActionType.Reduce) // Если действие - свертка
  45.         {
  46.             Rule rule = grammar.GetRule(entry.Value); // Получаем правило свертки по индексу из таблицы действий
  47.             List<Symbol> poppedSymbols = new List<Symbol>();
  48.  
  49.             for (int i = 0; i < rule.Right.Length; i++) // Извлекаем символы из стека символов в соответствии с правилом свертки
  50.             {
  51.                 poppedSymbols.Add(symbolStack.Pop());
  52.                 stateStack.Pop();
  53.             }
  54.  
  55.             poppedSymbols.Reverse(); // Разворачиваем извлеченные символы в правильном порядке
  56.             Symbol nonTerminal = rule.Left; // Получаем нетерминальный символ слева от правила свертки
  57.             int nextState = table.GetGoto(stateStack.Peek(), nonTerminal); // Получаем следующее состояние из таблицы переходов
  58.  
  59.             stateStack.Push(nextState); // Переходим к следующему состоянию
  60.             symbolStack.Push(nonTerminal); // Добавляем нетерминальный символ в стек символов
  61.  
  62.             Console.WriteLine("Reduced by rule: " + rule);
  63.             // Выполнение семантических действий, связанных с правилом
  64.         }
  65.         else if (entry.Action == ActionType.Accept) // Если действие - принятие
  66.         {
  67.             Console.WriteLine("Input successfully parsed!");
  68.             return;
  69.         }
  70.     }
  71.  
  72.     Console.WriteLine("Error: Unexpected end of input");
  73. }
  74.  
  75. }
  76.  
  77. public class Symbol
  78. {
  79.     public char Value { get; set; }
  80.     public bool IsTerminal { get; set; }
  81.  
  82.     public Symbol(char value, bool isTerminal = true)
  83.     {
  84.         Value = value;
  85.         IsTerminal = isTerminal;
  86.     }
  87.  
  88.     public override string ToString()
  89.     {
  90.         return Value.ToString();
  91.     }
  92. }
  93.  
  94. public class Rule
  95. {
  96.     public Symbol Left { get; set; }
  97.     public Symbol[] Right { get; set; }
  98.  
  99.     public Rule(Symbol left, params Symbol[] right)
  100.     {
  101.         Left = left;
  102.         Right = right;
  103.     }
  104.  
  105.     public override string ToString()
  106.     {
  107.         string rightStr = string.Join(" ", Right);
  108.         return Left + " -> " + rightStr;
  109.     }
  110. }
  111.  
  112. public class Grammar
  113. {
  114.     public List<Symbol> Terminals { get; set; }
  115.     public List<Symbol> NonTerminals { get; set; }
  116.     public List<Rule> Rules { get; set; }
  117.     public Symbol StartSymbol { get; set; }
  118.  
  119.     public Grammar(List<Symbol> terminals, List<Symbol> nonTerminals, List<Rule> rules, Symbol startSymbol)
  120.     {
  121.         Terminals = terminals;
  122.         NonTerminals = nonTerminals;
  123.         Rules = rules;
  124.         StartSymbol = startSymbol;
  125.     }
  126.  
  127.     // Метод для получения правила по индексу
  128.     public Rule GetRule(int index)
  129.     {
  130.         if (index >= 0 && index < Rules.Count)
  131.         {
  132.             return Rules[index];
  133.         }
  134.  
  135.         return null;
  136.     }
  137. }
  138.  
  139. public enum ActionType
  140. {
  141.     Shift,
  142.     Reduce,
  143.     Accept
  144. }
  145.  
  146. public class ActionTableEntry
  147. {
  148.     public ActionType Action { get; set; }
  149.     public int Value { get; set; }
  150.  
  151.     public ActionTableEntry(ActionType action, int value)
  152.     {
  153.         Action = action;
  154.         Value = value;
  155.     }
  156. }
  157.  
  158. public class GotoTableEntry
  159. {
  160.     public int Value { get; set; }
  161.  
  162.     public GotoTableEntry(int value)
  163.     {
  164.         Value = value;
  165.     }
  166. }
  167.  
  168. public class LRTable
  169. {
  170.     private Dictionary<Tuple<int, char>, ActionTableEntry> actionTable;
  171.     private Dictionary<Tuple<int, Symbol>, GotoTableEntry> gotoTable;
  172.  
  173.     public LRTable()
  174.     {
  175.         actionTable = new Dictionary<Tuple<int, char>, ActionTableEntry>();
  176.         gotoTable = new Dictionary<Tuple<int, Symbol>, GotoTableEntry>();
  177.     }
  178.  
  179.     // Метод для добавления записи в таблицу действий
  180.     public void AddAction(int state, char input, ActionType action, int value)
  181.     {
  182.         actionTable.Add(new Tuple<int, char>(state, input), new ActionTableEntry(action, value));
  183.     }
  184.  
  185.     // Метод для добавления записи в таблицу переходов
  186.     public void AddGoto(int state, Symbol symbol, int value)
  187.     {
  188.         gotoTable.Add(new Tuple<int, Symbol>(state, symbol), new GotoTableEntry(value));
  189.     }
  190.  
  191.     // Метод для получения записи из таблицы действий
  192.     public ActionTableEntry GetAction(int state, char input)
  193.     {
  194.         ActionTableEntry entry;
  195.         actionTable.TryGetValue(new Tuple<int, char>(state, input), out entry);
  196.         return entry;
  197.     }
  198.  
  199.     // Метод для получения значения перехода из таблицы переходов
  200.     public int GetGoto(int state, Symbol symbol)
  201.     {
  202.         GotoTableEntry entry;
  203.         gotoTable.TryGetValue(new Tuple<int, Symbol>(state, symbol), out entry);
  204.         return entry != null ? entry.Value : -1;
  205.     }
  206. }
  207.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement