public void TestNonterminal() { Nonterminal term = new Nonterminal(); string[] arr = { "123", "345" }; term.Add(arr); List <string> list = new List <string>() { "qqq", "ddd" }; term.Add(list); Assert.AreEqual(2, term.Size); term.Add(new List <string>() { "ggg", "www" }); Assert.AreEqual(3, term.Size); }
public StackMachineTest() { EasyLexerLang = new LexerLang(new Terminal[] { new Terminal("ASSIGN_OP", "^=$"), new Terminal("VAR", "^[a-zA-Z]+$", uint.MaxValue), new Terminal("DIGIT", "^0|([1-9][0-9]*)$"), new Terminal("OP", "^\\+|-|\\*|/$"), new Terminal("WHILE_KW", "^while$", 0), new Terminal("PRINT_KW", "^print$", 0), new Terminal("L_QB", "^{$"), new Terminal("R_QB", "^}$"), new Terminal("L_B", "^\\($"), new Terminal("R_B", "^\\)$"), new Terminal("CH_SPACE", "^ $"), new Terminal("CH_LEFTLINE", "^\r$"), new Terminal("CH_NEWLINE", "^\n$"), new Terminal("CH_TAB", "^\t$") }); /* * Правила стековой машины: * Все команды выполняются в постфиксной записи. * * {value logical, value addr, "if", com1} * Где: * logical - если 0, то переход к com1. Ложь - переход к адресу addr. * addr - адрес перехода. * * {value addr, "goto"} * Переход к адресу addr. * */ Nonterminal lang = new Nonterminal("lang", (List <string> commands, ActionInsert insert, int id) => { for (int i = 0; i < id; i++) { insert(i); } }, ZERO_AND_MORE); Nonterminal value = new Nonterminal("value", (List <string> commands, ActionInsert insert, int id) => { insert(); }, OR, "VAR", "DIGIT"); Nonterminal stmt = new Nonterminal("stmt", (List <string> commands, ActionInsert insert, int id) => { insert(1); insert(0); }, AND, value, new Nonterminal("(OP value)*", (List <string> commands, ActionInsert insert, int id) => { for (int i = 0; i < id; i++) { insert(i); } }, ZERO_AND_MORE, new Nonterminal("OP & value", (List <string> commands, ActionInsert insert, int id) => { insert(1); insert(0); }, AND, "OP", value))); Nonterminal assign_expr = new Nonterminal("assign_expr", (List <string> commands, ActionInsert insert, int id) => { insert(0); insert(2); insert(1); }, AND, "VAR", "ASSIGN_OP", stmt); Nonterminal while_expr = new Nonterminal("while_expr", // Нужно преобразовать в стековый код. (List <string> commands, ActionInsert insert, int id) => { insert(2); commands.Add("?"); // Адрес с истиной. int indexAddrTrue = commands.Count - 1; commands.Add("if"); commands.Add("?"); // Адрес с ложью. int indexAddrFalse = commands.Count - 1; commands.Add("goto"); // Сюда надо попасть, если true. commands[indexAddrTrue] = commands.Count.ToString(); insert(5); // Тело while. commands.Add(indexAddrTrue.ToString()); commands.Add("goto"); // Команда перехода в if к while. // Надо выйти из цикла, если false: commands[indexAddrFalse] = commands.Count.ToString(); }, AND, "WHILE_KW", "L_B", stmt, "R_B", "L_QB", lang, "R_QB"); Nonterminal expr = new Nonterminal("expr", // Нужно преобразовать в стековый код. (List <string> commands, ActionInsert insert, int id) => { switch (id) { case 0: { insert(); } break; case 1: { insert(); } break; case 2: { commands.Add("print"); } break; } }, OR, assign_expr, while_expr, "PRINT_KW"); lang.Add(expr); EasyParserLang = new ParserLang(lang); SuperEasyParserLang = new ParserLang(new Nonterminal("easy lang", (List <string> commands, ActionInsert insert, int id) => { insert(0); insert(2); insert(1); }, AND, "VAR", "ASSIGN_OP", "DIGIT")); EasyStackLang = new MyEasyStackLang(); }