Advertisement
vasy1

Untitled

Jun 7th, 2023
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.90 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