diff --git a/Module6/ProgramTree.cs b/Module6/ProgramTree.cs index ac0fb2b4e49e076399ba142f0fbf73529571bf5d..f3ebeba354eb299a94226312c043a01ffcffae0a 100644 --- a/Module6/ProgramTree.cs +++ b/Module6/ProgramTree.cs @@ -3,6 +3,7 @@ namespace ProgramTree { public enum AssignType { Assign, AssignPlus, AssignMinus, AssignMult, AssignDivide }; + public enum BinOpType { Plus, Minus, Multiply, Divide }; public class Node // базовый класс для всех узлов { @@ -89,10 +90,10 @@ namespace ProgramTree } } - public class VarNode : StatementNode + public class VarDefNode : StatementNode { public IdListNode IdList; - public VarNode(IdListNode idlist) + public VarDefNode(IdListNode idlist) { IdList = idlist; } @@ -100,23 +101,23 @@ namespace ProgramTree public class RepeatNode : StatementNode { - public BlockNode Block { get; set; } + public BlockNode StList { get; set; } public ExprNode Expr { get; set; } public RepeatNode(BlockNode block, ExprNode expr) { - Block = block; + StList = block; Expr = expr; } } public class ForNode : StatementNode { - public ExprNode FromExpr { get; set; } + public AssignNode Assign { get; set; } public ExprNode ToExpr { get; set; } public StatementNode Stat { get; set; } - public ForNode(ExprNode from_expr, ExprNode to_expr, StatementNode stat) + public ForNode(AssignNode ass_node, ExprNode to_expr, StatementNode stat) { - FromExpr = from_expr; + Assign = ass_node; ToExpr = to_expr; Stat = stat; } @@ -144,4 +145,17 @@ namespace ProgramTree } } + public class BinaryNode : ExprNode + { + public ExprNode LeftExpr { get; set; } + public ExprNode RightExpr { get; set; } + public BinOpType Op { get; set; } + public BinaryNode(ExprNode left_expr, ExprNode right_expr, BinOpType op) + { + LeftExpr = left_expr; + RightExpr = right_expr; + Op = op; + } + } + } \ No newline at end of file diff --git a/Module6/SimpleLex.cs b/Module6/SimpleLex.cs index 9d7e70cf647eccae36215b8131633ba999590e08..a39bc768da286b9e2f597e912f81401b3a540524 100644 --- a/Module6/SimpleLex.cs +++ b/Module6/SimpleLex.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: DESKTOP-H0VRSS3 -// DateTime: 23.10.2022 18:19:09 +// DateTime: 24.10.2022 4:14:32 // UserName: nikit // GPLEX input file <SimpleLex.lex> // GPLEX frame file <embedded resource> @@ -123,8 +123,8 @@ namespace SimpleScanner enum Result {accept, noMatch, contextFound}; - const int maxAccept = 10; - const int initial = 11; + const int maxAccept = 14; + const int initial = 15; const int eofNum = 0; const int goStart = -1; const int INITIAL = 0; @@ -161,24 +161,24 @@ namespace SimpleScanner } }; - static int[] startState = new int[] {11, 0}; + static int[] startState = new int[] {15, 0}; #region CompressedCharacterMap // - // There are 11 equivalence classes + // There are 15 equivalence classes // There are 2 character sequence regions // There are 1 tables, 123 entries // There are 1 runs, 0 singletons // Decision tree depth is 1 // static sbyte[] mapC0 = new sbyte[123] { -/* '\0' */ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 0, 10, 10, -/* '\x10' */ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -/* '\x20' */ 0, 10, 10, 10, 10, 10, 10, 10, 7, 8, 10, 10, 9, 10, 2, 10, -/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 10, 5, 10, 10, -/* '@' */ 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 3, -/* '`' */ 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14, +/* '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +/* '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 7, 8, 12, 10, 9, 11, 2, 13, +/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14, +/* '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, +/* '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; static sbyte MapC(int code) @@ -186,25 +186,29 @@ namespace SimpleScanner if (code < 123) // '\0' <= code <= 'z' return mapC0[code - 0]; else // '{' <= code <= '\U0010FFFF' - return (sbyte)10; + return (sbyte)14; } #endregion - static Table[] NxS = new Table[13] { + static Table[] NxS = new Table[17] { /* NxS[ 0] */ new Table(0, 0, 0, null), -/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 12}), +/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 16}), /* NxS[ 2] */ new Table(0, 0, -1, null), /* NxS[ 3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}), -/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {9}), +/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {13}), /* NxS[ 5] */ new Table(0, 0, -1, null), /* NxS[ 6] */ new Table(0, 0, -1, null), /* NxS[ 7] */ new Table(0, 0, -1, null), /* NxS[ 8] */ new Table(0, 0, -1, null), /* NxS[ 9] */ new Table(0, 0, -1, null), -/* NxS[ 10] */ new Table(1, 1, -1, new sbyte[] {10}), -/* NxS[ 11] */ new Table(1, 10, -1, new sbyte[] {1, 2, 3, 4, 2, 5, - 6, 7, 8, 2}), -/* NxS[ 12] */ new Table(1, 1, -1, new sbyte[] {10}), +/* NxS[ 10] */ new Table(0, 0, -1, null), +/* NxS[ 11] */ new Table(0, 0, -1, null), +/* NxS[ 12] */ new Table(0, 0, -1, null), +/* NxS[ 13] */ new Table(0, 0, -1, null), +/* NxS[ 14] */ new Table(1, 1, -1, new sbyte[] {14}), +/* NxS[ 15] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5, + 6, 7, 8, 9, 10, 11, 12, 2}), +/* NxS[ 16] */ new Table(1, 1, -1, new sbyte[] {14}), }; int NextState() { @@ -214,7 +218,7 @@ int NextState() { unchecked { int rslt; int idx = MapC(code) - NxS[state].min; - if (idx < 0) idx += 11; + if (idx < 0) idx += 15; if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt; else rslt = NxS[state].nxt[idx]; return rslt; @@ -661,9 +665,21 @@ return (int)Tokens.RIGHT_BRACKET; return (int)Tokens.COMMA; break; case 9: -return (int)Tokens.ASSIGN; +return (int)Tokens.PLUS; break; case 10: +return (int)Tokens.MINUS; + break; + case 11: +return (int)Tokens.MULTIPLY; + break; + case 12: +return (int)Tokens.DIVIDE; + break; + case 13: +return (int)Tokens.ASSIGN; + break; + case 14: yylval.dVal = double.Parse(yytext); return (int)Tokens.RNUM; break; diff --git a/Module6/SimpleLex.lex b/Module6/SimpleLex.lex index fd10cd17412d72257159fa93a9493bc5f8413cb9..b8b08bece491f7ba059f39e36005d0e39c2bab64 100644 --- a/Module6/SimpleLex.lex +++ b/Module6/SimpleLex.lex @@ -35,6 +35,10 @@ ID {Alpha}{AlphaDigit}* "(" { return (int)Tokens.LEFT_BRACKET; } ")" { return (int)Tokens.RIGHT_BRACKET; } "," { return (int)Tokens.COMMA; } +"+" { return (int)Tokens.PLUS; } +"-" { return (int)Tokens.MINUS; } +"*" { return (int)Tokens.MULTIPLY; } +"/" { return (int)Tokens.DIVIDE; } [^ \r\n] { LexError(); diff --git a/Module6/SimpleYacc.cs b/Module6/SimpleYacc.cs index ab4b5fe4ccd51b9790e113884d1dd84d8358714e..727ea6461cd68e2ff6b2e93d74b209cc936df984 100644 --- a/Module6/SimpleYacc.cs +++ b/Module6/SimpleYacc.cs @@ -4,7 +4,7 @@ // GPPG version 1.3.6 // Machine: DESKTOP-H0VRSS3 -// DateTime: 23.10.2022 18:19:09 +// DateTime: 24.10.2022 4:14:32 // UserName: nikit // Input file <SimpleYacc.y> @@ -23,7 +23,8 @@ public enum Tokens { error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,ASSIGN=6, SEMICOLON=7,WHILE=8,DO=9,REPEAT=10,UNTIL=11,FOR=12, TO=13,WRITE=14,LEFT_BRACKET=15,RIGHT_BRACKET=16,IF=17,THEN=18, - ELSE=19,COMMA=20,VAR=21,INUM=22,RNUM=23,ID=24}; + ELSE=19,COMMA=20,VAR=21,PLUS=22,MINUS=23,MULTIPLY=24, + DIVIDE=25,INUM=26,RNUM=27,ID=28}; public struct ValueType { @@ -54,102 +55,120 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation> #pragma warning disable 649 private static Dictionary<int, string> aliasses; #pragma warning restore 649 - private static Rule[] rules = new Rule[29]; - private static State[] states = new State[59]; + private static Rule[] rules = new Rule[36]; + private static State[] states = new State[70]; private static string[] nonTerms = new string[] { - "expr", "ident", "assign", "statement", "cycle", "while", "repeat", "for", - "write", "if", "var", "stlist", "block", "idlist", "progr", "$accept", + "expr", "ident", "T", "F", "assign", "statement", "cycle", "while", "repeat", + "for", "write", "if", "var", "stlist", "block", "idlist", "progr", "$accept", }; static Parser() { - states[0] = new State(new int[]{3,4},new int[]{-15,1,-13,3}); + states[0] = new State(new int[]{3,4},new int[]{-17,1,-15,3}); states[1] = new State(new int[]{2,2}); states[2] = new State(-1); states[3] = new State(-2); - states[4] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-12,5,-4,31,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); + states[4] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-14,5,-6,44,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); states[5] = new State(new int[]{4,6,7,7}); - states[6] = new State(-18); - states[7] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,8,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); + states[6] = new State(-25); + states[7] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,8,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); states[8] = new State(-4); states[9] = new State(-5); states[10] = new State(new int[]{6,11}); - states[11] = new State(new int[]{24,14,22,15},new int[]{-1,12,-2,13}); - states[12] = new State(-15); - states[13] = new State(-16); - states[14] = new State(-14); - states[15] = new State(-17); - states[16] = new State(-6); - states[17] = new State(-7); - states[18] = new State(new int[]{24,14,22,15},new int[]{-1,19,-2,13}); - states[19] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,20,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[20] = new State(-19); - states[21] = new State(-8); - states[22] = new State(new int[]{24,14,22,15},new int[]{-1,23,-2,13}); - states[23] = new State(new int[]{9,24}); - states[24] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,25,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[25] = new State(-20); - states[26] = new State(-9); - states[27] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-12,28,-4,31,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[28] = new State(new int[]{11,29,7,7}); - states[29] = new State(new int[]{24,14,22,15},new int[]{-1,30,-2,13}); - states[30] = new State(-21); - states[31] = new State(-3); - states[32] = new State(-10); - states[33] = new State(new int[]{24,14},new int[]{-2,34}); - states[34] = new State(new int[]{6,35}); - states[35] = new State(new int[]{24,14,22,15},new int[]{-1,36,-2,13}); - states[36] = new State(new int[]{13,37}); - states[37] = new State(new int[]{24,14,22,15},new int[]{-1,38,-2,13}); - states[38] = new State(new int[]{9,39}); - states[39] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,40,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[40] = new State(-22); - states[41] = new State(-11); - states[42] = new State(new int[]{15,43}); - states[43] = new State(new int[]{24,14,22,15},new int[]{-1,44,-2,13}); - states[44] = new State(new int[]{16,45}); - states[45] = new State(-23); - states[46] = new State(-12); - states[47] = new State(new int[]{24,14,22,15},new int[]{-1,48,-2,13}); - states[48] = new State(new int[]{18,49}); - states[49] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,50,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[50] = new State(new int[]{19,51,4,-24,7,-24,11,-24}); - states[51] = new State(new int[]{24,14,3,4,5,18,8,22,10,27,12,33,14,42,17,47,21,54},new int[]{-4,52,-3,9,-2,10,-13,16,-5,17,-6,21,-7,26,-8,32,-9,41,-10,46,-11,53}); - states[52] = new State(-25); - states[53] = new State(-13); - states[54] = new State(new int[]{24,14},new int[]{-14,55,-2,58}); - states[55] = new State(new int[]{20,56,4,-26,7,-26,11,-26,19,-26}); - states[56] = new State(new int[]{24,14},new int[]{-2,57}); - states[57] = new State(-28); - states[58] = new State(-27); + states[11] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,12,-3,28,-4,27,-2,17}); + states[12] = new State(new int[]{22,13,23,23,4,-15,7,-15,11,-15,19,-15,13,-15}); + states[13] = new State(new int[]{28,18,26,19,15,20},new int[]{-3,14,-4,27,-2,17}); + states[14] = new State(new int[]{24,15,25,25,22,-17,23,-17,4,-17,7,-17,11,-17,19,-17,13,-17,16,-17,28,-17,3,-17,5,-17,8,-17,10,-17,12,-17,14,-17,17,-17,21,-17,9,-17,18,-17}); + states[15] = new State(new int[]{28,18,26,19,15,20},new int[]{-4,16,-2,17}); + states[16] = new State(-20); + states[17] = new State(-22); + states[18] = new State(-14); + states[19] = new State(-23); + states[20] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,21,-3,28,-4,27,-2,17}); + states[21] = new State(new int[]{16,22,22,13,23,23}); + states[22] = new State(-24); + states[23] = new State(new int[]{28,18,26,19,15,20},new int[]{-3,24,-4,27,-2,17}); + states[24] = new State(new int[]{24,15,25,25,22,-18,23,-18,4,-18,7,-18,11,-18,19,-18,13,-18,16,-18,28,-18,3,-18,5,-18,8,-18,10,-18,12,-18,14,-18,17,-18,21,-18,9,-18,18,-18}); + states[25] = new State(new int[]{28,18,26,19,15,20},new int[]{-4,26,-2,17}); + states[26] = new State(-21); + states[27] = new State(-19); + states[28] = new State(new int[]{24,15,25,25,22,-16,23,-16,4,-16,7,-16,11,-16,19,-16,13,-16,16,-16,28,-16,3,-16,5,-16,8,-16,10,-16,12,-16,14,-16,17,-16,21,-16,9,-16,18,-16}); + states[29] = new State(-6); + states[30] = new State(-7); + states[31] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,32,-3,28,-4,27,-2,17}); + states[32] = new State(new int[]{22,13,23,23,28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,33,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[33] = new State(-26); + states[34] = new State(-8); + states[35] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,36,-3,28,-4,27,-2,17}); + states[36] = new State(new int[]{9,37,22,13,23,23}); + states[37] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,38,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[38] = new State(-27); + states[39] = new State(-9); + states[40] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-14,41,-6,44,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[41] = new State(new int[]{11,42,7,7}); + states[42] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,43,-3,28,-4,27,-2,17}); + states[43] = new State(new int[]{22,13,23,23,4,-28,7,-28,11,-28,19,-28}); + states[44] = new State(-3); + states[45] = new State(-10); + states[46] = new State(new int[]{28,18},new int[]{-5,47,-2,10}); + states[47] = new State(new int[]{13,48}); + states[48] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,49,-3,28,-4,27,-2,17}); + states[49] = new State(new int[]{9,50,22,13,23,23}); + states[50] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,51,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[51] = new State(-29); + states[52] = new State(-11); + states[53] = new State(new int[]{15,54}); + states[54] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,55,-3,28,-4,27,-2,17}); + states[55] = new State(new int[]{16,56,22,13,23,23}); + states[56] = new State(-30); + states[57] = new State(-12); + states[58] = new State(new int[]{28,18,26,19,15,20},new int[]{-1,59,-3,28,-4,27,-2,17}); + states[59] = new State(new int[]{18,60,22,13,23,23}); + states[60] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,61,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[61] = new State(new int[]{19,62,4,-31,7,-31,11,-31}); + states[62] = new State(new int[]{28,18,3,4,5,31,8,35,10,40,12,46,14,53,17,58,21,65},new int[]{-6,63,-5,9,-2,10,-15,29,-7,30,-8,34,-9,39,-10,45,-11,52,-12,57,-13,64}); + states[63] = new State(-32); + states[64] = new State(-13); + states[65] = new State(new int[]{28,18},new int[]{-16,66,-2,69}); + states[66] = new State(new int[]{20,67,4,-33,7,-33,11,-33,19,-33}); + states[67] = new State(new int[]{28,18},new int[]{-2,68}); + states[68] = new State(-35); + states[69] = new State(-34); - rules[1] = new Rule(-16, new int[]{-15,2}); - rules[2] = new Rule(-15, new int[]{-13}); - rules[3] = new Rule(-12, new int[]{-4}); - rules[4] = new Rule(-12, new int[]{-12,7,-4}); - rules[5] = new Rule(-4, new int[]{-3}); - rules[6] = new Rule(-4, new int[]{-13}); - rules[7] = new Rule(-4, new int[]{-5}); - rules[8] = new Rule(-4, new int[]{-6}); - rules[9] = new Rule(-4, new int[]{-7}); - rules[10] = new Rule(-4, new int[]{-8}); - rules[11] = new Rule(-4, new int[]{-9}); - rules[12] = new Rule(-4, new int[]{-10}); - rules[13] = new Rule(-4, new int[]{-11}); - rules[14] = new Rule(-2, new int[]{24}); - rules[15] = new Rule(-3, new int[]{-2,6,-1}); - rules[16] = new Rule(-1, new int[]{-2}); - rules[17] = new Rule(-1, new int[]{22}); - rules[18] = new Rule(-13, new int[]{3,-12,4}); - rules[19] = new Rule(-5, new int[]{5,-1,-4}); - rules[20] = new Rule(-6, new int[]{8,-1,9,-4}); - rules[21] = new Rule(-7, new int[]{10,-12,11,-1}); - rules[22] = new Rule(-8, new int[]{12,-2,6,-1,13,-1,9,-4}); - rules[23] = new Rule(-9, new int[]{14,15,-1,16}); - rules[24] = new Rule(-10, new int[]{17,-1,18,-4}); - rules[25] = new Rule(-10, new int[]{17,-1,18,-4,19,-4}); - rules[26] = new Rule(-11, new int[]{21,-14}); - rules[27] = new Rule(-14, new int[]{-2}); - rules[28] = new Rule(-14, new int[]{-14,20,-2}); + rules[1] = new Rule(-18, new int[]{-17,2}); + rules[2] = new Rule(-17, new int[]{-15}); + rules[3] = new Rule(-14, new int[]{-6}); + rules[4] = new Rule(-14, new int[]{-14,7,-6}); + rules[5] = new Rule(-6, new int[]{-5}); + rules[6] = new Rule(-6, new int[]{-15}); + rules[7] = new Rule(-6, new int[]{-7}); + rules[8] = new Rule(-6, new int[]{-8}); + rules[9] = new Rule(-6, new int[]{-9}); + rules[10] = new Rule(-6, new int[]{-10}); + rules[11] = new Rule(-6, new int[]{-11}); + rules[12] = new Rule(-6, new int[]{-12}); + rules[13] = new Rule(-6, new int[]{-13}); + rules[14] = new Rule(-2, new int[]{28}); + rules[15] = new Rule(-5, new int[]{-2,6,-1}); + rules[16] = new Rule(-1, new int[]{-3}); + rules[17] = new Rule(-1, new int[]{-1,22,-3}); + rules[18] = new Rule(-1, new int[]{-1,23,-3}); + rules[19] = new Rule(-3, new int[]{-4}); + rules[20] = new Rule(-3, new int[]{-3,24,-4}); + rules[21] = new Rule(-3, new int[]{-3,25,-4}); + rules[22] = new Rule(-4, new int[]{-2}); + rules[23] = new Rule(-4, new int[]{26}); + rules[24] = new Rule(-4, new int[]{15,-1,16}); + rules[25] = new Rule(-15, new int[]{3,-14,4}); + rules[26] = new Rule(-7, new int[]{5,-1,-6}); + rules[27] = new Rule(-8, new int[]{8,-1,9,-6}); + rules[28] = new Rule(-9, new int[]{10,-14,11,-1}); + rules[29] = new Rule(-10, new int[]{12,-5,13,-1,9,-6}); + rules[30] = new Rule(-11, new int[]{14,15,-1,16}); + rules[31] = new Rule(-12, new int[]{17,-1,18,-6}); + rules[32] = new Rule(-12, new int[]{17,-1,18,-6,19,-6}); + rules[33] = new Rule(-13, new int[]{21,-16}); + rules[34] = new Rule(-16, new int[]{-2}); + rules[35] = new Rule(-16, new int[]{-16,20,-2}); } protected override void Initialize() { @@ -210,45 +229,66 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation> case 15: // assign -> ident, ASSIGN, expr { CurrentSemanticValue.stVal = new AssignNode(ValueStack[ValueStack.Depth-3].eVal as IdNode, ValueStack[ValueStack.Depth-1].eVal); } break; - case 16: // expr -> ident + case 16: // expr -> T +{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; } + break; + case 17: // expr -> expr, PLUS, T +{ CurrentSemanticValue.eVal = new BinaryNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].eVal, BinOpType.Plus); } + break; + case 18: // expr -> expr, MINUS, T +{ CurrentSemanticValue.eVal = new BinaryNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].eVal, BinOpType.Minus); } + break; + case 19: // T -> F +{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; } + break; + case 20: // T -> T, MULTIPLY, F +{ CurrentSemanticValue.eVal = new BinaryNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].eVal, BinOpType.Multiply); } + break; + case 21: // T -> T, DIVIDE, F +{ CurrentSemanticValue.eVal = new BinaryNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].eVal, BinOpType.Divide); } + break; + case 22: // F -> ident { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; } break; - case 17: // expr -> INUM + case 23: // F -> INUM { CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); } break; - case 18: // block -> BEGIN, stlist, END + case 24: // F -> LEFT_BRACKET, expr, RIGHT_BRACKET +{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; } + break; + case 25: // block -> BEGIN, stlist, END { CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; } break; - case 19: // cycle -> CYCLE, expr, statement + case 26: // cycle -> CYCLE, expr, statement { CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 20: // while -> WHILE, expr, DO, statement + case 27: // while -> WHILE, expr, DO, statement { CurrentSemanticValue.stVal = new WhileNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 21: // repeat -> REPEAT, stlist, UNTIL, expr + case 28: // repeat -> REPEAT, stlist, UNTIL, expr { CurrentSemanticValue.stVal = new RepeatNode(ValueStack[ValueStack.Depth-3].blVal, ValueStack[ValueStack.Depth-1].eVal); } break; - case 22: // for -> FOR, ident, ASSIGN, expr, TO, expr, DO, statement -{ CurrentSemanticValue.stVal = new ForNode(ValueStack[ValueStack.Depth-5].eVal, ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } + case 29: // for -> FOR, assign, TO, expr, DO, statement +{ CurrentSemanticValue.stVal = new ForNode(ValueStack[ValueStack.Depth-5].stVal as AssignNode, ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 23: // write -> WRITE, LEFT_BRACKET, expr, RIGHT_BRACKET + case 30: // write -> WRITE, LEFT_BRACKET, expr, RIGHT_BRACKET { CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); } break; - case 24: // if -> IF, expr, THEN, statement + case 31: // if -> IF, expr, THEN, statement { CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 25: // if -> IF, expr, THEN, statement, ELSE, statement + case 32: // if -> IF, expr, THEN, statement, ELSE, statement { CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-5].eVal, ValueStack[ValueStack.Depth-3].stVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 26: // var -> VAR, idlist -{ CurrentSemanticValue.stVal = new VarNode(ValueStack[ValueStack.Depth-1].idListVal); } + case 33: // var -> VAR, idlist +{ CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].idListVal); } break; - case 27: // idlist -> ident + case 34: // idlist -> ident { CurrentSemanticValue.idListVal = new IdListNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); } break; - case 28: // idlist -> idlist, COMMA, ident + case 35: // idlist -> idlist, COMMA, ident { ValueStack[ValueStack.Depth-3].idListVal.Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); CurrentSemanticValue.idListVal = ValueStack[ValueStack.Depth-3].idListVal; diff --git a/Module6/SimpleYacc.y b/Module6/SimpleYacc.y index 15083eb9b2afa474b86bfe524799f75a7712972e..5ab30e3f3d39e05d6cd46b8f207399df77c904a4 100644 --- a/Module6/SimpleYacc.y +++ b/Module6/SimpleYacc.y @@ -21,12 +21,12 @@ %namespace SimpleParser -%token BEGIN END CYCLE ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE LEFT_BRACKET RIGHT_BRACKET IF THEN ELSE COMMA VAR +%token BEGIN END CYCLE ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE LEFT_BRACKET RIGHT_BRACKET IF THEN ELSE COMMA VAR PLUS MINUS MULTIPLY DIVIDE %token <iVal> INUM %token <dVal> RNUM %token <sVal> ID -%type <eVal> expr ident +%type <eVal> expr ident T F %type <stVal> assign statement cycle while repeat for write if var %type <blVal> stlist block %type <idListVal> idlist @@ -64,9 +64,20 @@ ident : ID { $$ = new IdNode($1); } assign : ident ASSIGN expr { $$ = new AssignNode($1 as IdNode, $3); } ; -expr : ident { $$ = $1 as IdNode; } - | INUM { $$ = new IntNumNode($1); } - ; +expr : T { $$ = $1; } + | expr PLUS T { $$ = new BinaryNode($1, $3, BinOpType.Plus); } + | expr MINUS T { $$ = new BinaryNode($1, $3, BinOpType.Minus); } + ; + +T : F { $$ = $1; } + | T MULTIPLY F { $$ = new BinaryNode($1, $3, BinOpType.Multiply); } + | T DIVIDE F { $$ = new BinaryNode($1, $3, BinOpType.Divide); } + ; + +F : ident { $$ = $1 as IdNode; } + | INUM { $$ = new IntNumNode($1); } + | LEFT_BRACKET expr RIGHT_BRACKET { $$ = $2; } + ; block : BEGIN stlist END { $$ = $2; } ; @@ -80,7 +91,7 @@ while : WHILE expr DO statement { $$ = new WhileNode($2, $4); } repeat : REPEAT stlist UNTIL expr { $$ = new RepeatNode($2, $4); } ; -for : FOR ident ASSIGN expr TO expr DO statement { $$ = new ForNode($4, $6, $8); } +for : FOR assign TO expr DO statement { $$ = new ForNode($2 as AssignNode, $4, $6); } ; write : WRITE LEFT_BRACKET expr RIGHT_BRACKET { $$ = new WriteNode($3); } @@ -90,7 +101,7 @@ if : IF expr THEN statement { $$ = new IfNode($2, $4); } | IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); } ; -var : VAR idlist { $$ = new VarNode($2); } +var : VAR idlist { $$ = new VarDefNode($2); } ; idlist : ident diff --git a/TestASTParser/Tests.cs b/TestASTParser/Tests.cs index 4fe61829d512390484c29df4378b9ff5139a83d0..01331900a80eaffcee999cd0f3382e4a3d6e1284 100644 --- a/TestASTParser/Tests.cs +++ b/TestASTParser/Tests.cs @@ -58,7 +58,21 @@ namespace TestASTParser { var tree = ASTParserTests.Parse("begin repeat a:=2 until 2 end"); Assert.AreEqual("ProgramTree.RepeatNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]); - // TODO: проверить узлы содержимого repeat + + Assert.AreEqual("ProgramTree.BlockNode, SimpleLang", (string)tree["StList"]["$values"][0]["StList"]["$type"]); + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["Id"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["Expr"]["Num"]).Trim()); + + Assert.AreEqual("0", ((string)tree["StList"]["$values"][0]["StList"]["StList"]["$values"][0]["AssOp"]).Trim()); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Expr"]["Num"]).Trim()); + } } @@ -71,7 +85,25 @@ namespace TestASTParser { var tree = ASTParserTests.Parse("begin for i:=2 to 10 do a:=2 end"); Assert.AreEqual("ProgramTree.ForNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]); - // TODO: проверить узлы содержимого for + + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][0]["Assign"]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["Assign"]["Id"]["$type"]); + Assert.AreEqual("i", (string)tree["StList"]["$values"][0]["Assign"]["Id"]["Name"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Assign"]["Expr"]["$type"]); + Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Assign"]["Expr"]["Num"]).Trim()); + Assert.AreEqual("0", ((string)tree["StList"]["$values"][0]["Assign"]["AssOp"]).Trim()); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["ToExpr"]["$type"]); + Assert.AreEqual("10", ((string)tree["StList"]["$values"][0]["ToExpr"]["Num"]).Trim()); + + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][0]["Stat"]["$type"]); + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["Stat"]["Id"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][0]["Stat"]["Id"]["Name"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Stat"]["Expr"]["$type"]); + Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Stat"]["Expr"]["Num"]).Trim()); + Assert.AreEqual("0", ((string)tree["StList"]["$values"][0]["Stat"]["AssOp"]).Trim()); + } } @@ -85,7 +117,12 @@ namespace TestASTParser { var tree = ASTParserTests.Parse("begin write(2) end"); Assert.AreEqual("ProgramTree.WriteNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]); - // TODO: проверить содержимое write + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("2", ((string)tree["StList"]["$values"][0]["Expr"]["Num"]).Trim()); + + Console.WriteLine(tree["StList"]["$values"][0].ToString()); + } } @@ -97,23 +134,157 @@ namespace TestASTParser //Ignore("This test is disabled")] public void TestIf() { - //Assert.Fail(); - // TODO: дописать тест + var tree1 = ASTParserTests.Parse("begin if 1 then write(1) else write(0) end"); + + Assert.AreEqual("ProgramTree.IfNode, SimpleLang", (string)tree1["StList"]["$values"][0]["$type"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree1["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("1", ((string)tree1["StList"]["$values"][0]["Expr"]["Num"]).Trim()); + + Assert.AreEqual("ProgramTree.WriteNode, SimpleLang", (string)tree1["StList"]["$values"][0]["ThenStat"]["$type"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree1["StList"]["$values"][0]["ThenStat"]["Expr"]["$type"]); + Assert.AreEqual("1", ((string)tree1["StList"]["$values"][0]["ThenStat"]["Expr"]["Num"]).Trim()); + + Assert.AreEqual("ProgramTree.WriteNode, SimpleLang", (string)tree1["StList"]["$values"][0]["ElseStat"]["$type"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree1["StList"]["$values"][0]["ElseStat"]["Expr"]["$type"]); + Assert.AreEqual("0", ((string)tree1["StList"]["$values"][0]["ElseStat"]["Expr"]["Num"]).Trim()); + + + var tree2 = ASTParserTests.Parse("begin if 1 then write(1) end"); + Assert.AreEqual("ProgramTree.IfNode, SimpleLang", (string)tree2["StList"]["$values"][0]["$type"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree2["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("1", ((string)tree2["StList"]["$values"][0]["Expr"]["Num"]).Trim()); + + Assert.AreEqual("ProgramTree.WriteNode, SimpleLang", (string)tree2["StList"]["$values"][0]["ThenStat"]["$type"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree2["StList"]["$values"][0]["ThenStat"]["Expr"]["$type"]); + Assert.AreEqual("1", ((string)tree2["StList"]["$values"][0]["ThenStat"]["Expr"]["Num"]).Trim()); + + Assert.AreEqual("", tree2["StList"]["$values"][0]["ElseStat"].ToString()); + } - + + [Test] //[Ignore("This test is disabled")] public void TestVarDef() { - //Assert.Fail(); - // TODO: дописать тест + var tree = ASTParserTests.Parse(@"begin var a,b,c end"); + + Assert.AreEqual("ProgramTree.VarDefNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][0]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][0]["Name"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][1]["$type"]); + Assert.AreEqual("b", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][1]["Name"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][2]["$type"]); + Assert.AreEqual("c", (string)tree["StList"]["$values"][0]["IdList"]["IdList"]["$values"][2]["Name"]); + + } - + [Test] public void TestBinary() { - //Assert.Fail(); - // TODO: дописать тест + var tree = ASTParserTests.Parse(@"begin + a:=1+1; + b:=1-1; + c:=a*b; + d:=a/b; + e:=1 * ((a+b) / 2 - 666) + end"); + /* ===> a:=1+1;*/ + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][0]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][0]["Id"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][0]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["$type"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["LeftExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][0]["Expr"]["LeftExpr"]["Num"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][0]["Expr"]["RightExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][0]["Expr"]["RightExpr"]["Num"]); + Assert.AreEqual("0", (string)tree["StList"]["$values"][0]["Expr"]["Op"]); + + /* ===> b:=1-1;*/ + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][1]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][1]["Id"]["$type"]); + Assert.AreEqual("b", (string)tree["StList"]["$values"][1]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][1]["Expr"]["$type"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][1]["Expr"]["LeftExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][1]["Expr"]["LeftExpr"]["Num"]); + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][1]["Expr"]["RightExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][1]["Expr"]["RightExpr"]["Num"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][1]["Expr"]["Op"]); + + /* ===> c:=a*b;*/ + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][2]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][2]["Id"]["$type"]); + Assert.AreEqual("c", (string)tree["StList"]["$values"][2]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][2]["Expr"]["$type"]); + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][2]["Expr"]["LeftExpr"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][2]["Expr"]["LeftExpr"]["Name"]); + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][2]["Expr"]["RightExpr"]["$type"]); + Assert.AreEqual("b", (string)tree["StList"]["$values"][2]["Expr"]["RightExpr"]["Name"]); + Assert.AreEqual("2", (string)tree["StList"]["$values"][2]["Expr"]["Op"]); + + + + /* ===> d:=a/b;*/ + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][3]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][3]["Id"]["$type"]); + Assert.AreEqual("d", (string)tree["StList"]["$values"][3]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][3]["Expr"]["$type"]); + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][3]["Expr"]["LeftExpr"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][3]["Expr"]["LeftExpr"]["Name"]); + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][3]["Expr"]["RightExpr"]["$type"]); + Assert.AreEqual("b", (string)tree["StList"]["$values"][3]["Expr"]["RightExpr"]["Name"]); + Assert.AreEqual("3", (string)tree["StList"]["$values"][3]["Expr"]["Op"]); + + + + /* ===> e:=1 * ((a+b) / 2 - 666)*/ + Assert.AreEqual("ProgramTree.AssignNode, SimpleLang", (string)tree["StList"]["$values"][4]["$type"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][4]["Id"]["$type"]); + Assert.AreEqual("e", (string)tree["StList"]["$values"][4]["Id"]["Name"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["$type"]); + Assert.AreEqual("2", (string)tree["StList"]["$values"][4]["Expr"]["Op"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["LeftExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][4]["Expr"]["LeftExpr"]["Num"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["$type"]); + Assert.AreEqual("1", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["Op"]); + + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["$type"]); + Assert.AreEqual("3", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["Op"]); + + // + Assert.AreEqual("ProgramTree.BinaryNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["$type"]); + Assert.AreEqual("0", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["Op"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["LeftExpr"]["$type"]); + Assert.AreEqual("a", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["LeftExpr"]["Name"]); + + Assert.AreEqual("ProgramTree.IdNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["RightExpr"]["$type"]); + Assert.AreEqual("b", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["LeftExpr"]["RightExpr"]["Name"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["RightExpr"]["$type"]); + Assert.AreEqual("2", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["LeftExpr"]["RightExpr"]["Num"]); + + Assert.AreEqual("ProgramTree.IntNumNode, SimpleLang", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["RightExpr"]["$type"]); + Assert.AreEqual("666", (string)tree["StList"]["$values"][4]["Expr"]["RightExpr"]["RightExpr"]["Num"]); + } } } \ No newline at end of file