From 959f22183f6951a530febad00a19f1917062923e Mon Sep 17 00:00:00 2001 From: Elijah Gichev <elijah.gichev@gmail.com> Date: Tue, 20 Dec 2022 10:50:25 +0300 Subject: [PATCH] added types --- Module7/Visitors/CountCyclesOpVisitor.cs | 13 +- Module8/ParserHelper.cs | 22 +- Module8/ProgramTree.cs | 56 ++- Module8/SimpleLex.cs | 132 ++++-- Module8/SimpleLex.lex | 23 +- Module8/SimpleYacc.cs | 438 ++++++++++++------ Module8/SimpleYacc.lst | 68 ++- Module8/SimpleYacc.y | 112 ++++- .../GenCodeVisitors/GenCodeCreator.cs | 19 +- .../GenCodeVisitors/GenCodeVisitor.cs | 79 +++- Module8/Visitors/Visitor.cs | 10 +- Module8/generateParserScanner.bat | 1 + TestCodeGenerator/Tests.cs | 48 +- TestVisitors/Tests.cs | 18 +- 14 files changed, 799 insertions(+), 240 deletions(-) diff --git a/Module7/Visitors/CountCyclesOpVisitor.cs b/Module7/Visitors/CountCyclesOpVisitor.cs index dcbaec8..496cc6b 100644 --- a/Module7/Visitors/CountCyclesOpVisitor.cs +++ b/Module7/Visitors/CountCyclesOpVisitor.cs @@ -10,35 +10,36 @@ namespace SimpleLang.Visitors { public int amountOps = 0; public int amountCycles = 0; - public bool isInCycle = false; + //public bool isInCycle = false; + public int cycles = 0; public int MidCount() { return amountOps == 0 ? 0 : amountOps / amountCycles; } public override void VisitAssignNode(AssignNode a) { - if (!isInCycle) return; + if (cycles == 0) return; amountOps++; } public override void VisitVarDefNode(VarDefNode w) { - if (!isInCycle) return; + if (cycles == 0) return; amountOps++; } public override void VisitWriteNode(WriteNode w) { - if (!isInCycle) return; + if (cycles == 0) return; amountOps++; } public override void VisitCycleNode(CycleNode c) { amountCycles++; - isInCycle = true; + ++cycles; c.Stat.Visit(this); - isInCycle = false; + --cycles; } } } diff --git a/Module8/ParserHelper.cs b/Module8/ParserHelper.cs index a085ecd..f758cfb 100644 --- a/Module8/ParserHelper.cs +++ b/Module8/ParserHelper.cs @@ -4,7 +4,7 @@ using System; namespace SimpleParser { - public enum type { tint, tdouble }; + public enum type { tint, tdouble, tbool, tchar }; public static class SymbolTable // Таблица символов { @@ -29,5 +29,25 @@ namespace SimpleParser public static class ParserHelper { + static public Type castSymbolTypeToInner(type t) + { + Type innerType = typeof(int); + switch (t) + { + case type.tint: + innerType = typeof(int); + break; + case type.tdouble: + innerType = typeof(double); + break; + case type.tbool: + innerType = typeof(bool); + break; + case type.tchar: + innerType = typeof(char); + break; + } + return innerType; + } } } \ No newline at end of file diff --git a/Module8/ProgramTree.cs b/Module8/ProgramTree.cs index 8ffb89b..6561658 100644 --- a/Module8/ProgramTree.cs +++ b/Module8/ProgramTree.cs @@ -24,15 +24,7 @@ namespace ProgramTree } } - public class IntNumNode : ExprNode - { - public int Num { get; set; } - public IntNumNode(int num) { Num = num; } - public override void Visit(Visitor v) - { - v.VisitIntNumNode(this); - } - } + public class BinOpNode : ExprNode { @@ -128,9 +120,12 @@ namespace ProgramTree public class VarDefNode : StatementNode { public List<IdNode> vars = new List<IdNode>(); - public VarDefNode(IdNode id) + + public SimpleParser.type type = SimpleParser.type.tint; + public VarDefNode(IdNode id, SimpleParser.type type) { Add(id); + this.type = type; } public void Add(IdNode id) @@ -191,4 +186,45 @@ namespace ProgramTree } } + // num nodes + public class IntNumNode : ExprNode + { + public int Num { get; set; } + public IntNumNode(int num) { Num = num; } + public override void Visit(Visitor v) + { + v.VisitIntNumNode(this); + } + } + + public class FloatNumNode : ExprNode + { + public double Num { get; set; } + public FloatNumNode(double num) { Num = num; } + public override void Visit(Visitor v) + { + v.VisitFloatNumNode(this); + } + } + + public class BoolNumNode : ExprNode + { + public bool Num { get; set; } + public BoolNumNode(bool num) { Num = num; } + public override void Visit(Visitor v) + { + v.VisitBoolNumNode(this); + } + } + + public class CharNumNode : ExprNode + { + public char Num { get; set; } + public CharNumNode(char num) { Num = num; } + public override void Visit(Visitor v) + { + v.VisitCharNumNode(this); + } + } + } \ No newline at end of file diff --git a/Module8/SimpleLex.cs b/Module8/SimpleLex.cs index 09a5c3c..3cab70b 100644 --- a/Module8/SimpleLex.cs +++ b/Module8/SimpleLex.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: WIN-51KGPO1PTR9 -// DateTime: 04.12.2022 17:28:51 +// DateTime: 11.12.2022 22:15:53 // UserName: ????????????? // GPLEX input file <SimpleLex.lex> // GPLEX frame file <embedded resource> @@ -123,8 +123,8 @@ namespace SimpleScanner enum Result {accept, noMatch, contextFound}; - const int maxAccept = 18; - const int initial = 19; + const int maxAccept = 27; + const int initial = 28; const int eofNum = 0; const int goStart = -1; const int INITIAL = 0; @@ -161,58 +161,77 @@ namespace SimpleScanner } }; - static int[] startState = new int[] {19, 0}; + static int[] startState = new int[] {28, 0}; #region CompressedCharacterMap // - // There are 16 equivalence classes + // There are 26 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' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, -/* '\x10' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -/* '\x20' */ 0, 15, 15, 15, 15, 14, 15, 15, 11, 12, 9, 8, 13, 7, 2, 10, -/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 15, 5, 15, 15, -/* '@' */ 15, 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, 15, 15, 15, 15, 3, -/* '`' */ 15, 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 }; +/* '\0' */ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 12, 25, 25, +/* '\x10' */ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +/* '\x20' */ 12, 25, 25, 25, 25, 24, 25, 11, 21, 22, 19, 18, 23, 17, 2, 20, +/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 16, 25, 15, 25, 25, +/* '@' */ 25, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +/* 'P' */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 25, 25, 25, 25, 13, +/* '`' */ 25, 8, 13, 13, 13, 6, 7, 13, 13, 13, 13, 13, 9, 13, 13, 13, +/* 'p' */ 13, 13, 4, 10, 3, 5, 13, 13, 13, 13, 13 }; static sbyte MapC(int code) { // '\0' <= code <= '\U0010FFFF' if (code < 123) // '\0' <= code <= 'z' return mapC0[code - 0]; else // '{' <= code <= '\U0010FFFF' - return (sbyte)15; + return (sbyte)25; } #endregion - static Table[] NxS = new Table[21] { + static Table[] NxS = new Table[31] { /* NxS[ 0] */ new Table(0, 0, 0, null), -/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 20}), +/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 30}), /* 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[] {17}), -/* NxS[ 5] */ new Table(0, 0, -1, null), -/* NxS[ 6] */ new Table(5, 1, -1, new sbyte[] {16}), -/* NxS[ 7] */ new Table(5, 1, -1, new sbyte[] {15}), -/* NxS[ 8] */ new Table(5, 1, -1, new sbyte[] {14}), -/* NxS[ 9] */ new Table(0, 0, -1, null), -/* NxS[ 10] */ new Table(0, 0, -1, null), -/* NxS[ 11] */ new Table(0, 0, -1, null), +/* NxS[ 3] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 26, 4, 4, + 4, 4, 4, 4, -1, -1, 4}), +/* NxS[ 4] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 4, + 4, 4, 4, 4, -1, -1, 4}), +/* NxS[ 5] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 4, + 4, 22, 4, 4, -1, -1, 4}), +/* NxS[ 6] */ new Table(0, 1, 29, new sbyte[] {-1}), +/* NxS[ 7] */ new Table(15, 1, -1, new sbyte[] {20}), +/* NxS[ 8] */ new Table(0, 0, -1, null), +/* NxS[ 9] */ new Table(15, 1, -1, new sbyte[] {19}), +/* NxS[ 10] */ new Table(15, 1, -1, new sbyte[] {18}), +/* NxS[ 11] */ new Table(15, 1, -1, new sbyte[] {17}), /* NxS[ 12] */ new Table(0, 0, -1, null), /* NxS[ 13] */ new Table(0, 0, -1, null), /* NxS[ 14] */ new Table(0, 0, -1, null), /* NxS[ 15] */ new Table(0, 0, -1, null), /* NxS[ 16] */ new Table(0, 0, -1, null), /* NxS[ 17] */ new Table(0, 0, -1, null), -/* NxS[ 18] */ new Table(1, 1, -1, new sbyte[] {18}), -/* NxS[ 19] */ new Table(1, 15, -1, new sbyte[] {1, 2, 3, 4, 2, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 2}), -/* NxS[ 20] */ new Table(1, 1, -1, new sbyte[] {18}), +/* NxS[ 18] */ new Table(0, 0, -1, null), +/* NxS[ 19] */ new Table(0, 0, -1, null), +/* NxS[ 20] */ new Table(0, 0, -1, null), +/* NxS[ 21] */ new Table(0, 0, -1, null), +/* NxS[ 22] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 4, + 4, 4, 23, 4, -1, -1, 4}), +/* NxS[ 23] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 4, + 4, 4, 4, 24, -1, -1, 4}), +/* NxS[ 24] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 25, + 4, 4, 4, 4, -1, -1, 4}), +/* NxS[ 25] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 4, 4, + 4, 4, 4, 4, -1, -1, 4}), +/* NxS[ 26] */ new Table(1, 13, -1, new sbyte[] {4, -1, 4, 4, 24, 4, + 4, 4, 4, 4, -1, -1, 4}), +/* NxS[ 27] */ new Table(1, 1, -1, new sbyte[] {27}), +/* NxS[ 28] */ new Table(7, 23, 4, new sbyte[] {5, 4, 4, 4, 6, -1, + 4, 7, 2, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, -1, 1, 2, + 3}), +/* NxS[ 29] */ new Table(11, 1, -1, new sbyte[] {21}), +/* NxS[ 30] */ new Table(1, 1, -1, new sbyte[] {27}), }; int NextState() { @@ -222,7 +241,7 @@ int NextState() { unchecked { int rslt; int idx = MapC(code) - NxS[state].min; - if (idx < 0) idx += 16; + if (idx < 0) idx += 26; if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt; else rslt = NxS[state].nxt[idx]; return rslt; @@ -647,56 +666,71 @@ yylval.iVal = int.Parse(yytext); return (int)Tokens.INUM; break; case 2: - case 4: + case 6: + case 7: LexError(); break; case 3: + case 4: + case 5: + case 22: + case 23: + case 24: + case 26: int res = ScannerHelper.GetIDToken(yytext); if (res == (int)Tokens.ID) yylval.sVal = yytext; return res; break; - case 5: + case 8: return (int)Tokens.SEMICOLON; break; - case 6: + case 9: return (int)Tokens.MINUS; break; - case 7: + case 10: return (int)Tokens.PLUS; break; - case 8: + case 11: return (int)Tokens.MULT; break; - case 9: + case 12: return (int)Tokens.DIV; break; - case 10: + case 13: return (int)Tokens.LPAREN; break; - case 11: + case 14: return (int)Tokens.RPAREN; break; - case 12: + case 15: return (int)Tokens.COLUMN; break; - case 13: + case 16: return (int)Tokens.MOD; break; - case 14: + case 17: return (int)Tokens.ASSIGNMULT; break; - case 15: + case 18: return (int)Tokens.ASSIGNPLUS; break; - case 16: + case 19: return (int)Tokens.ASSIGNMINUS; break; - case 17: + case 20: return (int)Tokens.ASSIGN; break; - case 18: -yylval.dVal = double.Parse(yytext); + case 21: +yylval.cVal = yytext[1]; + return (int)Tokens.CNUM; + break; + case 25: +yylval.bVal = bool.Parse(yytext); + return (int)Tokens.BNUM; + break; + case 27: +yylval.dVal = double.Parse(yytext, CultureInfo.InvariantCulture); return (int)Tokens.RNUM; break; default: @@ -820,8 +854,10 @@ class ScannerHelper keywords.Add("do", (int)Tokens.DO); keywords.Add("repeat", (int)Tokens.REPEAT); keywords.Add("until", (int)Tokens.UNTIL); - - + keywords.Add("int", (int)Tokens.INT); + keywords.Add("float", (int)Tokens.FLOAT); + keywords.Add("bool", (int)Tokens.BOOL); + keywords.Add("char", (int)Tokens.CHAR); } public static int GetIDToken(string s) { diff --git a/Module8/SimpleLex.lex b/Module8/SimpleLex.lex index 4a1d430..ba4093b 100644 --- a/Module8/SimpleLex.lex +++ b/Module8/SimpleLex.lex @@ -11,6 +11,11 @@ INTNUM {Digit}+ REALNUM {INTNUM}\.{INTNUM} ID {Alpha}{AlphaDigit}* +BOOLNUM (true|false) + +CHARNUM (\'.\') + + %% {INTNUM} { @@ -19,10 +24,20 @@ ID {Alpha}{AlphaDigit}* } {REALNUM} { - yylval.dVal = double.Parse(yytext); + yylval.dVal = double.Parse(yytext, CultureInfo.InvariantCulture); return (int)Tokens.RNUM; } +{BOOLNUM} { + yylval.bVal = bool.Parse(yytext); + return (int)Tokens.BNUM; +} + +{CHARNUM} { + yylval.cVal = yytext[1]; + return (int)Tokens.CNUM; +} + {ID} { int res = ScannerHelper.GetIDToken(yytext); if (res == (int)Tokens.ID) @@ -86,8 +101,10 @@ class ScannerHelper keywords.Add("do", (int)Tokens.DO); keywords.Add("repeat", (int)Tokens.REPEAT); keywords.Add("until", (int)Tokens.UNTIL); - - + keywords.Add("int", (int)Tokens.INT); + keywords.Add("float", (int)Tokens.FLOAT); + keywords.Add("bool", (int)Tokens.BOOL); + keywords.Add("char", (int)Tokens.CHAR); } public static int GetIDToken(string s) { diff --git a/Module8/SimpleYacc.cs b/Module8/SimpleYacc.cs index b88992e..d3af8ce 100644 --- a/Module8/SimpleYacc.cs +++ b/Module8/SimpleYacc.cs @@ -4,7 +4,7 @@ // GPPG version 1.3.6 // Machine: WIN-51KGPO1PTR9 -// DateTime: 04.12.2022 17:28:51 +// DateTime: 11.12.2022 22:15:54 // UserName: ????????????? // Input file <SimpleYacc.y> @@ -25,12 +25,15 @@ public enum Tokens { ASSIGNPLUS=7,ASSIGNMINUS=8,ASSIGNMULT=9,SEMICOLON=10,WRITE=11,VAR=12, PLUS=13,MINUS=14,MULT=15,DIV=16,LPAREN=17,RPAREN=18, COLUMN=19,MOD=20,IF=21,THEN=22,ELSE=23,WHILE=24, - DO=25,REPEAT=26,UNTIL=27,INUM=28,RNUM=29,ID=30}; + DO=25,REPEAT=26,UNTIL=27,INT=28,FLOAT=29,BOOL=30, + CHAR=31,INUM=32,RNUM=33,BNUM=34,CNUM=35,ID=36}; public struct ValueType { public double dVal; public int iVal; + public bool bVal; + public char cVal; public string sVal; public Node nVal; public ExprNode eVal; @@ -56,119 +59,177 @@ 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[38]; - private static State[] states = new State[67]; + private static Rule[] rules = new Rule[62]; + private static State[] states = new State[99]; private static string[] nonTerms = new string[] { - "progr", "expr", "ident", "T", "F", "statement", "assign", "block", "cycle", - "write", "empty", "var", "varlist", "if", "while", "repeat", "stlist", - "$accept", "Anon@1", }; + "progr", "expr", "ident", "T", "F", "NUM", "statement", "assign", "block", + "cycle", "write", "empty", "var", "varlist", "if", "while", "repeat", "int", + "float", "bool", "char", "intlist", "floatlist", "boollist", "charlist", + "stlist", "$accept", "Anon@1", "Anon@2", "Anon@3", "Anon@4", "Anon@5", + }; static Parser() { - states[0] = new State(new int[]{3,4},new int[]{-1,1,-8,3}); + states[0] = new State(new int[]{3,4},new int[]{-1,1,-9,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[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14},new int[]{-17,5,-6,66,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); + states[4] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18},new int[]{-26,5,-7,70,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); states[5] = new State(new int[]{4,6,10,7}); - states[6] = new State(-27); - states[7] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14},new int[]{-6,8,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); + states[6] = new State(-35); + states[7] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18,27,-18},new int[]{-7,8,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); states[8] = new State(-4); states[9] = new State(-5); states[10] = new State(new int[]{6,11}); - states[11] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,12,-4,30,-5,29,-3,17}); - states[12] = new State(new int[]{13,13,14,23,4,-16,10,-16,27,-16,23,-16}); - states[13] = new State(new int[]{30,18,28,19,17,20},new int[]{-4,14,-5,29,-3,17}); - states[14] = new State(new int[]{15,15,16,25,20,27,13,-17,14,-17,4,-17,10,-17,27,-17,23,-17,18,-17,30,-17,3,-17,5,-17,11,-17,12,-17,21,-17,24,-17,26,-17,22,-17,25,-17}); - states[15] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,16,-3,17}); - states[16] = new State(-20); - states[17] = new State(-24); - states[18] = new State(-15); - states[19] = new State(-25); - states[20] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,21,-4,30,-5,29,-3,17}); - states[21] = new State(new int[]{18,22,13,13,14,23}); - states[22] = new State(-26); - states[23] = new State(new int[]{30,18,28,19,17,20},new int[]{-4,24,-5,29,-3,17}); - states[24] = new State(new int[]{15,15,16,25,20,27,13,-18,14,-18,4,-18,10,-18,27,-18,23,-18,18,-18,30,-18,3,-18,5,-18,11,-18,12,-18,21,-18,24,-18,26,-18,22,-18,25,-18}); - states[25] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,26,-3,17}); - states[26] = new State(-21); - states[27] = new State(new int[]{30,18,28,19,17,20},new int[]{-5,28,-3,17}); - states[28] = new State(-22); - states[29] = new State(-23); - states[30] = new State(new int[]{15,15,16,25,20,27,13,-19,14,-19,4,-19,10,-19,27,-19,23,-19,18,-19,30,-19,3,-19,5,-19,11,-19,12,-19,21,-19,24,-19,26,-19,22,-19,25,-19}); - states[31] = new State(-6); - states[32] = new State(-7); - states[33] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,34,-4,30,-5,29,-3,17}); - states[34] = new State(new int[]{13,13,14,23,30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,35,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); - states[35] = new State(-28); - states[36] = new State(-8); - states[37] = new State(new int[]{17,38}); - states[38] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,39,-4,30,-5,29,-3,17}); - states[39] = new State(new int[]{18,40,13,13,14,23}); - states[40] = new State(-29); - states[41] = new State(-9); - states[42] = new State(-30,new int[]{-19,43}); - states[43] = new State(new int[]{30,18},new int[]{-13,44,-3,47}); - states[44] = new State(new int[]{19,45,4,-31,10,-31,27,-31,23,-31}); - states[45] = new State(new int[]{30,18},new int[]{-3,46}); - states[46] = new State(-33); - states[47] = new State(-32); - states[48] = new State(-10); - states[49] = new State(-11); - states[50] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,51,-4,30,-5,29,-3,17}); - states[51] = new State(new int[]{22,52,13,13,14,23}); - states[52] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,53,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); - states[53] = new State(new int[]{23,54,4,-34,10,-34,27,-34}); - states[54] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,55,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); - states[55] = new State(-35); - states[56] = new State(-12); - states[57] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,58,-4,30,-5,29,-3,17}); - states[58] = new State(new int[]{25,59,13,13,14,23}); - states[59] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,4,-14,10,-14,27,-14,23,-14},new int[]{-6,60,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); - states[60] = new State(-36); - states[61] = new State(-13); - states[62] = new State(new int[]{30,18,3,4,5,33,11,37,12,42,21,50,24,57,26,62,27,-14,10,-14},new int[]{-17,63,-6,66,-7,9,-3,10,-8,31,-9,32,-10,36,-12,41,-11,48,-14,49,-15,56,-16,61}); - states[63] = new State(new int[]{27,64,10,7}); - states[64] = new State(new int[]{30,18,28,19,17,20},new int[]{-2,65,-4,30,-5,29,-3,17}); - states[65] = new State(new int[]{13,13,14,23,4,-37,10,-37,27,-37,23,-37}); - states[66] = new State(-3); + states[11] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,12,-4,34,-5,33,-3,17,-6,26}); + states[12] = new State(new int[]{13,13,14,22,4,-20,10,-20,27,-20,23,-20}); + states[13] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-4,14,-5,33,-3,17,-6,26}); + states[14] = new State(new int[]{15,15,16,24,20,31,13,-21,14,-21,4,-21,10,-21,27,-21,23,-21,18,-21,36,-21,3,-21,5,-21,11,-21,12,-21,21,-21,24,-21,26,-21,28,-21,29,-21,30,-21,31,-21,22,-21,25,-21}); + states[15] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-5,16,-3,17,-6,26}); + states[16] = new State(-24); + states[17] = new State(-28); + states[18] = new State(-19); + states[19] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,20,-4,34,-5,33,-3,17,-6,26}); + states[20] = new State(new int[]{18,21,13,13,14,22}); + states[21] = new State(-29); + states[22] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-4,23,-5,33,-3,17,-6,26}); + states[23] = new State(new int[]{15,15,16,24,20,31,13,-22,14,-22,4,-22,10,-22,27,-22,23,-22,18,-22,36,-22,3,-22,5,-22,11,-22,12,-22,21,-22,24,-22,26,-22,28,-22,29,-22,30,-22,31,-22,22,-22,25,-22}); + states[24] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-5,25,-3,17,-6,26}); + states[25] = new State(-25); + states[26] = new State(-30); + states[27] = new State(-31); + states[28] = new State(-32); + states[29] = new State(-33); + states[30] = new State(-34); + states[31] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-5,32,-3,17,-6,26}); + states[32] = new State(-26); + states[33] = new State(-27); + states[34] = new State(new int[]{15,15,16,24,20,31,13,-23,14,-23,4,-23,10,-23,27,-23,23,-23,18,-23,36,-23,3,-23,5,-23,11,-23,12,-23,21,-23,24,-23,26,-23,28,-23,29,-23,30,-23,31,-23,22,-23,25,-23}); + states[35] = new State(-6); + states[36] = new State(-7); + states[37] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,38,-4,34,-5,33,-3,17,-6,26}); + states[38] = new State(new int[]{13,13,14,22,36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18,27,-18,23,-18},new int[]{-7,39,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); + states[39] = new State(-36); + states[40] = new State(-8); + states[41] = new State(new int[]{17,42}); + states[42] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,43,-4,34,-5,33,-3,17,-6,26}); + states[43] = new State(new int[]{18,44,13,13,14,22}); + states[44] = new State(-37); + states[45] = new State(-9); + states[46] = new State(-38,new int[]{-28,47}); + states[47] = new State(new int[]{36,18},new int[]{-14,48,-3,51}); + states[48] = new State(new int[]{19,49,4,-39,10,-39,27,-39,23,-39}); + states[49] = new State(new int[]{36,18},new int[]{-3,50}); + states[50] = new State(-41); + states[51] = new State(-40); + states[52] = new State(-10); + states[53] = new State(-11); + states[54] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,55,-4,34,-5,33,-3,17,-6,26}); + states[55] = new State(new int[]{22,56,13,13,14,22}); + states[56] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18,27,-18,23,-18},new int[]{-7,57,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); + states[57] = new State(new int[]{23,58,4,-42,10,-42,27,-42}); + states[58] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18,27,-18,23,-18},new int[]{-7,59,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); + states[59] = new State(-43); + states[60] = new State(-12); + states[61] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,62,-4,34,-5,33,-3,17,-6,26}); + states[62] = new State(new int[]{25,63,13,13,14,22}); + states[63] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,4,-18,10,-18,27,-18,23,-18},new int[]{-7,64,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); + states[64] = new State(-44); + states[65] = new State(-13); + states[66] = new State(new int[]{36,18,3,4,5,37,11,41,12,46,21,54,24,61,26,66,28,72,29,79,30,86,31,93,27,-18,10,-18},new int[]{-26,67,-7,70,-8,9,-3,10,-9,35,-10,36,-11,40,-13,45,-12,52,-15,53,-16,60,-17,65,-18,71,-19,78,-20,85,-21,92}); + states[67] = new State(new int[]{27,68,10,7}); + states[68] = new State(new int[]{36,18,17,19,32,27,33,28,34,29,35,30},new int[]{-2,69,-4,34,-5,33,-3,17,-6,26}); + states[69] = new State(new int[]{13,13,14,22,4,-45,10,-45,27,-45,23,-45}); + states[70] = new State(-3); + states[71] = new State(-14); + states[72] = new State(-46,new int[]{-29,73}); + states[73] = new State(new int[]{36,18},new int[]{-22,74,-3,77}); + states[74] = new State(new int[]{19,75,4,-47,10,-47,27,-47,23,-47}); + states[75] = new State(new int[]{36,18},new int[]{-3,76}); + states[76] = new State(-49); + states[77] = new State(-48); + states[78] = new State(-15); + states[79] = new State(-50,new int[]{-30,80}); + states[80] = new State(new int[]{36,18},new int[]{-23,81,-3,84}); + states[81] = new State(new int[]{19,82,4,-51,10,-51,27,-51,23,-51}); + states[82] = new State(new int[]{36,18},new int[]{-3,83}); + states[83] = new State(-53); + states[84] = new State(-52); + states[85] = new State(-16); + states[86] = new State(-54,new int[]{-31,87}); + states[87] = new State(new int[]{36,18},new int[]{-24,88,-3,91}); + states[88] = new State(new int[]{19,89,4,-55,10,-55,27,-55,23,-55}); + states[89] = new State(new int[]{36,18},new int[]{-3,90}); + states[90] = new State(-57); + states[91] = new State(-56); + states[92] = new State(-17); + states[93] = new State(-58,new int[]{-32,94}); + states[94] = new State(new int[]{36,18},new int[]{-25,95,-3,98}); + states[95] = new State(new int[]{19,96,4,-59,10,-59,27,-59,23,-59}); + states[96] = new State(new int[]{36,18},new int[]{-3,97}); + states[97] = new State(-61); + states[98] = new State(-60); - rules[1] = new Rule(-18, new int[]{-1,2}); - rules[2] = new Rule(-1, new int[]{-8}); - rules[3] = new Rule(-17, new int[]{-6}); - rules[4] = new Rule(-17, new int[]{-17,10,-6}); - rules[5] = new Rule(-6, new int[]{-7}); - rules[6] = new Rule(-6, new int[]{-8}); - rules[7] = new Rule(-6, new int[]{-9}); - rules[8] = new Rule(-6, new int[]{-10}); - rules[9] = new Rule(-6, new int[]{-12}); - rules[10] = new Rule(-6, new int[]{-11}); - rules[11] = new Rule(-6, new int[]{-14}); - rules[12] = new Rule(-6, new int[]{-15}); - rules[13] = new Rule(-6, new int[]{-16}); - rules[14] = new Rule(-11, new int[]{}); - rules[15] = new Rule(-3, new int[]{30}); - rules[16] = new Rule(-7, new int[]{-3,6,-2}); - rules[17] = new Rule(-2, new int[]{-2,13,-4}); - rules[18] = new Rule(-2, new int[]{-2,14,-4}); - rules[19] = new Rule(-2, new int[]{-4}); - rules[20] = new Rule(-4, new int[]{-4,15,-5}); - rules[21] = new Rule(-4, new int[]{-4,16,-5}); - rules[22] = new Rule(-4, new int[]{-4,20,-5}); - rules[23] = new Rule(-4, new int[]{-5}); - rules[24] = new Rule(-5, new int[]{-3}); - rules[25] = new Rule(-5, new int[]{28}); - rules[26] = new Rule(-5, new int[]{17,-2,18}); - rules[27] = new Rule(-8, new int[]{3,-17,4}); - rules[28] = new Rule(-9, new int[]{5,-2,-6}); - rules[29] = new Rule(-10, new int[]{11,17,-2,18}); - rules[30] = new Rule(-19, new int[]{}); - rules[31] = new Rule(-12, new int[]{12,-19,-13}); - rules[32] = new Rule(-13, new int[]{-3}); - rules[33] = new Rule(-13, new int[]{-13,19,-3}); - rules[34] = new Rule(-14, new int[]{21,-2,22,-6}); - rules[35] = new Rule(-14, new int[]{21,-2,22,-6,23,-6}); - rules[36] = new Rule(-15, new int[]{24,-2,25,-6}); - rules[37] = new Rule(-16, new int[]{26,-17,27,-2}); + rules[1] = new Rule(-27, new int[]{-1,2}); + rules[2] = new Rule(-1, new int[]{-9}); + rules[3] = new Rule(-26, new int[]{-7}); + rules[4] = new Rule(-26, new int[]{-26,10,-7}); + rules[5] = new Rule(-7, new int[]{-8}); + rules[6] = new Rule(-7, new int[]{-9}); + rules[7] = new Rule(-7, new int[]{-10}); + rules[8] = new Rule(-7, new int[]{-11}); + rules[9] = new Rule(-7, new int[]{-13}); + rules[10] = new Rule(-7, new int[]{-12}); + rules[11] = new Rule(-7, new int[]{-15}); + rules[12] = new Rule(-7, new int[]{-16}); + rules[13] = new Rule(-7, new int[]{-17}); + rules[14] = new Rule(-7, new int[]{-18}); + rules[15] = new Rule(-7, new int[]{-19}); + rules[16] = new Rule(-7, new int[]{-20}); + rules[17] = new Rule(-7, new int[]{-21}); + rules[18] = new Rule(-12, new int[]{}); + rules[19] = new Rule(-3, new int[]{36}); + rules[20] = new Rule(-8, new int[]{-3,6,-2}); + rules[21] = new Rule(-2, new int[]{-2,13,-4}); + rules[22] = new Rule(-2, new int[]{-2,14,-4}); + rules[23] = new Rule(-2, new int[]{-4}); + rules[24] = new Rule(-4, new int[]{-4,15,-5}); + rules[25] = new Rule(-4, new int[]{-4,16,-5}); + rules[26] = new Rule(-4, new int[]{-4,20,-5}); + rules[27] = new Rule(-4, new int[]{-5}); + rules[28] = new Rule(-5, new int[]{-3}); + rules[29] = new Rule(-5, new int[]{17,-2,18}); + rules[30] = new Rule(-5, new int[]{-6}); + rules[31] = new Rule(-6, new int[]{32}); + rules[32] = new Rule(-6, new int[]{33}); + rules[33] = new Rule(-6, new int[]{34}); + rules[34] = new Rule(-6, new int[]{35}); + rules[35] = new Rule(-9, new int[]{3,-26,4}); + rules[36] = new Rule(-10, new int[]{5,-2,-7}); + rules[37] = new Rule(-11, new int[]{11,17,-2,18}); + rules[38] = new Rule(-28, new int[]{}); + rules[39] = new Rule(-13, new int[]{12,-28,-14}); + rules[40] = new Rule(-14, new int[]{-3}); + rules[41] = new Rule(-14, new int[]{-14,19,-3}); + rules[42] = new Rule(-15, new int[]{21,-2,22,-7}); + rules[43] = new Rule(-15, new int[]{21,-2,22,-7,23,-7}); + rules[44] = new Rule(-16, new int[]{24,-2,25,-7}); + rules[45] = new Rule(-17, new int[]{26,-26,27,-2}); + rules[46] = new Rule(-29, new int[]{}); + rules[47] = new Rule(-18, new int[]{28,-29,-22}); + rules[48] = new Rule(-22, new int[]{-3}); + rules[49] = new Rule(-22, new int[]{-22,19,-3}); + rules[50] = new Rule(-30, new int[]{}); + rules[51] = new Rule(-19, new int[]{29,-30,-23}); + rules[52] = new Rule(-23, new int[]{-3}); + rules[53] = new Rule(-23, new int[]{-23,19,-3}); + rules[54] = new Rule(-31, new int[]{}); + rules[55] = new Rule(-20, new int[]{30,-31,-24}); + rules[56] = new Rule(-24, new int[]{-3}); + rules[57] = new Rule(-24, new int[]{-24,19,-3}); + rules[58] = new Rule(-32, new int[]{}); + rules[59] = new Rule(-21, new int[]{31,-32,-25}); + rules[60] = new Rule(-25, new int[]{-3}); + rules[61] = new Rule(-25, new int[]{-25,19,-3}); } protected override void Initialize() { @@ -223,10 +284,22 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation> case 13: // statement -> repeat { CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; } break; - case 14: // empty -> /* empty */ + case 14: // statement -> int +{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; } + break; + case 15: // statement -> float +{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; } + break; + case 16: // statement -> bool +{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; } + break; + case 17: // statement -> char +{ CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-1].stVal; } + break; + case 18: // empty -> /* empty */ { CurrentSemanticValue.stVal = new EmptyNode(); } break; - case 15: // ident -> ID + case 19: // ident -> ID { if (!InDefSect) if (!SymbolTable.vars.ContainsKey(ValueStack[ValueStack.Depth-1].sVal)) @@ -234,81 +307,182 @@ public class Parser: ShiftReduceParser<ValueType, LexLocation> CurrentSemanticValue.eVal = new IdNode(ValueStack[ValueStack.Depth-1].sVal); } break; - case 16: // assign -> ident, ASSIGN, expr + case 20: // assign -> ident, ASSIGN, expr { CurrentSemanticValue.stVal = new AssignNode(ValueStack[ValueStack.Depth-3].eVal as IdNode, ValueStack[ValueStack.Depth-1].eVal); } break; - case 17: // expr -> expr, PLUS, T + case 21: // expr -> expr, PLUS, T { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'+'); } break; - case 18: // expr -> expr, MINUS, T + case 22: // expr -> expr, MINUS, T { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'-'); } break; - case 19: // expr -> T + case 23: // expr -> T { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; } break; - case 20: // T -> T, MULT, F + case 24: // T -> T, MULT, F { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'*'); } break; - case 21: // T -> T, DIV, F + case 25: // T -> T, DIV, F { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'/'); } break; - case 22: // T -> T, MOD, F + case 26: // T -> T, MOD, F { CurrentSemanticValue.eVal = new BinOpNode(ValueStack[ValueStack.Depth-3].eVal,ValueStack[ValueStack.Depth-1].eVal,'%'); } break; - case 23: // T -> F + case 27: // T -> F { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; } break; - case 24: // F -> ident + case 28: // F -> ident { CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal as IdNode; } break; - case 25: // F -> INUM + case 29: // F -> LPAREN, expr, RPAREN +{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; } + break; + case 30: // F -> NUM +{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-1].eVal; } + break; + case 31: // NUM -> INUM { CurrentSemanticValue.eVal = new IntNumNode(ValueStack[ValueStack.Depth-1].iVal); } break; - case 26: // F -> LPAREN, expr, RPAREN -{ CurrentSemanticValue.eVal = ValueStack[ValueStack.Depth-2].eVal; } + case 32: // NUM -> RNUM +{ CurrentSemanticValue.eVal = new FloatNumNode(ValueStack[ValueStack.Depth-1].dVal); } + break; + case 33: // NUM -> BNUM +{ CurrentSemanticValue.eVal = new BoolNumNode(ValueStack[ValueStack.Depth-1].bVal); } break; - case 27: // block -> BEGIN, stlist, END + case 34: // NUM -> CNUM +{ CurrentSemanticValue.eVal = new CharNumNode(ValueStack[ValueStack.Depth-1].cVal); } + break; + case 35: // block -> BEGIN, stlist, END { CurrentSemanticValue.blVal = ValueStack[ValueStack.Depth-2].blVal; } break; - case 28: // cycle -> CYCLE, expr, statement + case 36: // cycle -> CYCLE, expr, statement { CurrentSemanticValue.stVal = new CycleNode(ValueStack[ValueStack.Depth-2].eVal,ValueStack[ValueStack.Depth-1].stVal); } break; - case 29: // write -> WRITE, LPAREN, expr, RPAREN + case 37: // write -> WRITE, LPAREN, expr, RPAREN { CurrentSemanticValue.stVal = new WriteNode(ValueStack[ValueStack.Depth-2].eVal); } break; - case 30: // Anon@1 -> /* empty */ + case 38: // Anon@1 -> /* empty */ { InDefSect = true; } break; - case 31: // var -> VAR, Anon@1, varlist + case 39: // var -> VAR, Anon@1, varlist { - foreach (var v in (ValueStack[ValueStack.Depth-1].stVal as VarDefNode).vars) - SymbolTable.NewVarDef(v.Name, type.tint); + var node = (ValueStack[ValueStack.Depth-1].stVal as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); InDefSect = false; } break; - case 32: // varlist -> ident + case 40: // varlist -> ident { - CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode); + CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode, type.tint); } break; - case 33: // varlist -> varlist, COLUMN, ident + case 41: // varlist -> varlist, COLUMN, ident { (ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; } break; - case 34: // if -> IF, expr, THEN, statement + case 42: // if -> IF, expr, THEN, statement { CurrentSemanticValue.stVal = new IfNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 35: // if -> IF, expr, THEN, statement, ELSE, statement + case 43: // 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 36: // while -> WHILE, expr, DO, statement + case 44: // while -> WHILE, expr, DO, statement { CurrentSemanticValue.stVal = new WhileNode(ValueStack[ValueStack.Depth-3].eVal, ValueStack[ValueStack.Depth-1].stVal); } break; - case 37: // repeat -> REPEAT, stlist, UNTIL, expr + case 45: // repeat -> REPEAT, stlist, UNTIL, expr { CurrentSemanticValue.stVal = new RepeatNode(ValueStack[ValueStack.Depth-1].eVal, ValueStack[ValueStack.Depth-3].blVal); } break; + case 46: // Anon@2 -> /* empty */ +{ InDefSect = true; } + break; + case 47: // int -> INT, Anon@2, intlist +{ + var node = (ValueStack[ValueStack.Depth-1].stVal as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + break; + case 48: // intlist -> ident +{ + CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode, type.tint); + } + break; + case 49: // intlist -> intlist, COLUMN, ident +{ + (ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); + CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; + } + break; + case 50: // Anon@3 -> /* empty */ +{ InDefSect = true; } + break; + case 51: // float -> FLOAT, Anon@3, floatlist +{ + var node = (ValueStack[ValueStack.Depth-1].stVal as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + break; + case 52: // floatlist -> ident +{ + CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode, type.tdouble); + } + break; + case 53: // floatlist -> floatlist, COLUMN, ident +{ + (ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); + CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; + } + break; + case 54: // Anon@4 -> /* empty */ +{ InDefSect = true; } + break; + case 55: // bool -> BOOL, Anon@4, boollist +{ + var node = (ValueStack[ValueStack.Depth-1].stVal as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + break; + case 56: // boollist -> ident +{ + CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode, type.tbool); + } + break; + case 57: // boollist -> boollist, COLUMN, ident +{ + (ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); + CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; + } + break; + case 58: // Anon@5 -> /* empty */ +{ InDefSect = true; } + break; + case 59: // char -> CHAR, Anon@5, charlist +{ + var node = (ValueStack[ValueStack.Depth-1].stVal as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + break; + case 60: // charlist -> ident +{ + CurrentSemanticValue.stVal = new VarDefNode(ValueStack[ValueStack.Depth-1].eVal as IdNode, type.tchar); + } + break; + case 61: // charlist -> charlist, COLUMN, ident +{ + (ValueStack[ValueStack.Depth-3].stVal as VarDefNode).Add(ValueStack[ValueStack.Depth-1].eVal as IdNode); + CurrentSemanticValue.stVal = ValueStack[ValueStack.Depth-3].stVal; + } + break; } } diff --git a/Module8/SimpleYacc.lst b/Module8/SimpleYacc.lst index 2de6038..d357bd9 100644 --- a/Module8/SimpleYacc.lst +++ b/Module8/SimpleYacc.lst @@ -3,9 +3,9 @@ // GPPG error listing for yacc source file <SimpleYacc.y> // ========================================================================== // Version: 1.3.6 -// Machine: SSM -// DateTime: 19.08.2014 13:28:35 -// UserName: Станислав +// Machine: WIN-51KGPO1PTR9 +// DateTime: 11.12.2022 17:56:28 +// UserName: Администратор // ========================================================================== @@ -21,6 +21,8 @@ %union { public double dVal; public int iVal; + public bool bVal; + public char cVal; public string sVal; public Node nVal; public ExprNode eVal; @@ -35,23 +37,33 @@ %start progr -%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN +%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN MOD IF THEN ELSE WHILE DO REPEAT UNTIL INT, FLOAT, BOOL, CHAR %token <iVal> INUM %token <dVal> RNUM +%token <bVal> BNUM +%token <cVal> CNUM %token <sVal> ID -%type <nVal> varlist %type <eVal> expr ident T F -%type <stVal> statement assign block cycle write empty var +%type <stVal> statement assign block cycle write empty var varlist if while repeat %type <blVal> stlist block %% -// Error: NonTerminal symbol "st" has no productions -// Warning: Terminating st fixes the following size-2 NonTerminal set - // {cycle, st} -// Error: There are 2 non-terminating NonTerminal Symbols - // {cycle, st} -// ------------------------------------------------------------------ +// Error: NonTerminal symbol "float" has no productions +// Error: NonTerminal symbol "int" has no productions +// Error: NonTerminal symbol "char" has no productions +// Error: NonTerminal symbol "bool" has no productions +// Warning: Terminating char fixes the following size-1 NonTerminal set + // {char} +// Warning: Terminating int fixes the following size-1 NonTerminal set + // {int} +// Error: There are 4 non-terminating NonTerminal Symbols + // {int, float, bool, char} +// Warning: Terminating bool fixes the following size-1 NonTerminal set + // {bool} +// Warning: Terminating float fixes the following size-1 NonTerminal set + // {float} +// --------------------------------------------------------------------- progr : block { root = $1; } ; @@ -67,12 +79,21 @@ stlist : statement } ; + statement: assign { $$ = $1; } | block { $$ = $1; } | cycle { $$ = $1; } | write { $$ = $1; } | var { $$ = $1; } | empty { $$ = $1; } + | if { $$ = $1; } + | while { $$ = $1; } + | repeat { $$ = $1; } + | int { $$ = $1; } + | float { $$ = $1; } + | bool { $$ = $1; } + | char { $$ = $1; } + ; empty : { $$ = new EmptyNode(); } @@ -97,18 +118,25 @@ expr : expr PLUS T { $$ = new BinOpNode($1,$3,'+'); } T : T MULT F { $$ = new BinOpNode($1,$3,'*'); } | T DIV F { $$ = new BinOpNode($1,$3,'/'); } + | T MOD F { $$ = new BinOpNode($1,$3,'%'); } | F { $$ = $1; } ; F : ident { $$ = $1 as IdNode; } - | INUM { $$ = new IntNumNode($1); } | LPAREN expr RPAREN { $$ = $2; } + | NUM { $$ = $1; } + ; + +NUM : INUM { $$ = new IntNumNode($1); } + | RNUM { $$ = new FloatNumNode($1); } + | BNUM { $$ = new BoolNumNode($1); } + | CNUM { $$ = new CharNumNode($1); } ; block : BEGIN stlist END { $$ = $2; } ; -cycle : CYCLE expr st { $$ = new CycleNode($2,$3); } +cycle : CYCLE expr statement { $$ = new CycleNode($2,$3); } ; write : WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); } @@ -132,6 +160,18 @@ varlist : ident $$ = $1; } ; + +if : IF expr THEN statement { $$ = new IfNode($2, $4); } + | IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); } + ; + +while : WHILE expr DO statement { $$ = new WhileNode($2, $4); } + ; + +repeat : REPEAT stlist UNTIL expr { $$ = new RepeatNode($4, $2); } + ; + + %% diff --git a/Module8/SimpleYacc.y b/Module8/SimpleYacc.y index 1e4d1d0..e4fb8ae 100644 --- a/Module8/SimpleYacc.y +++ b/Module8/SimpleYacc.y @@ -10,6 +10,8 @@ %union { public double dVal; public int iVal; + public bool bVal; + public char cVal; public string sVal; public Node nVal; public ExprNode eVal; @@ -24,15 +26,16 @@ %start progr -%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN MOD IF THEN ELSE WHILE DO REPEAT UNTIL +%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN MOD IF THEN ELSE WHILE DO REPEAT UNTIL INT FLOAT BOOL CHAR %token <iVal> INUM %token <dVal> RNUM +%token <bVal> BNUM +%token <cVal> CNUM %token <sVal> ID -%type <eVal> expr ident T F -%type <stVal> statement assign block cycle write empty var varlist if while repeat +%type <eVal> expr ident T F NUM +%type <stVal> statement assign block cycle write empty var varlist if while repeat int float bool char intlist floatlist boollist charlist %type <blVal> stlist block - %% progr : block { root = $1; } @@ -49,6 +52,7 @@ stlist : statement } ; + statement: assign { $$ = $1; } | block { $$ = $1; } | cycle { $$ = $1; } @@ -58,6 +62,10 @@ statement: assign { $$ = $1; } | if { $$ = $1; } | while { $$ = $1; } | repeat { $$ = $1; } + | int { $$ = $1; } + | float { $$ = $1; } + | bool { $$ = $1; } + | char { $$ = $1; } ; @@ -88,8 +96,14 @@ T : T MULT F { $$ = new BinOpNode($1,$3,'*'); } ; F : ident { $$ = $1 as IdNode; } - | INUM { $$ = new IntNumNode($1); } | LPAREN expr RPAREN { $$ = $2; } + | NUM { $$ = $1; } + ; + +NUM : INUM { $$ = new IntNumNode($1); } + | RNUM { $$ = new FloatNumNode($1); } + | BNUM { $$ = new BoolNumNode($1); } + | CNUM { $$ = new CharNumNode($1); } ; block : BEGIN stlist END { $$ = $2; } @@ -103,15 +117,16 @@ write : WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); } var : VAR { InDefSect = true; } varlist { - foreach (var v in ($3 as VarDefNode).vars) - SymbolTable.NewVarDef(v.Name, type.tint); + var node = ($3 as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); InDefSect = false; } ; varlist : ident { - $$ = new VarDefNode($1 as IdNode); + $$ = new VarDefNode($1 as IdNode, type.tint); } | varlist COLUMN ident { @@ -131,6 +146,87 @@ repeat : REPEAT stlist UNTIL expr { $$ = new RepeatNode($4, $2); } ; +int : INT { InDefSect = true; } intlist + { + var node = ($3 as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + ; + +intlist : ident + { + $$ = new VarDefNode($1 as IdNode, type.tint); + } + | intlist COLUMN ident + { + ($1 as VarDefNode).Add($3 as IdNode); + $$ = $1; + } + ; + +float : FLOAT { InDefSect = true; } floatlist + { + var node = ($3 as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + ; + +floatlist : ident + { + $$ = new VarDefNode($1 as IdNode, type.tdouble); + } + | floatlist COLUMN ident + { + ($1 as VarDefNode).Add($3 as IdNode); + $$ = $1; + } + ; + +bool : BOOL { InDefSect = true; } boollist + { + var node = ($3 as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + ; + +boollist : ident + { + $$ = new VarDefNode($1 as IdNode, type.tbool); + } + | boollist COLUMN ident + { + ($1 as VarDefNode).Add($3 as IdNode); + $$ = $1; + } + ; + +char : CHAR { InDefSect = true; } charlist + { + var node = ($3 as VarDefNode); + foreach (var v in node.vars) + SymbolTable.NewVarDef(v.Name, node.type); + InDefSect = false; + } + ; + +charlist : ident + { + $$ = new VarDefNode($1 as IdNode, type.tchar); + } + | charlist COLUMN ident + { + ($1 as VarDefNode).Add($3 as IdNode); + $$ = $1; + } + ; + + %% diff --git a/Module8/Visitors/GenCodeVisitors/GenCodeCreator.cs b/Module8/Visitors/GenCodeVisitors/GenCodeCreator.cs index 7353771..27546eb 100644 --- a/Module8/Visitors/GenCodeVisitors/GenCodeCreator.cs +++ b/Module8/Visitors/GenCodeVisitors/GenCodeCreator.cs @@ -12,7 +12,11 @@ namespace SimpleLang.Visitors private DynamicMethod dyn; private ILGenerator gen; private bool write_commands = true; - private static MethodInfo writeLineInt = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }); + + private static MethodInfo writeLineWithType(Type t) + { + return typeof(Console).GetMethod("WriteLine", new Type[] { t }); + } public List<string> commands = new List<string>(); @@ -36,6 +40,13 @@ namespace SimpleLang.Visitors commands.Add(op.ToString() + " " + num); } + public void Emit(OpCode op, double num) + { + gen.Emit(op, num); + if (write_commands) + commands.Add(op.ToString() + " " + num); + } + public void Emit(OpCode op, LocalBuilder lb) { gen.Emit(op, lb); @@ -74,9 +85,9 @@ namespace SimpleLang.Visitors commands.Add("MarkLabel" + " Label" + l.GetHashCode()); } - public void EmitWriteLine() - { - gen.Emit(OpCodes.Call, writeLineInt); + public void EmitWriteLine(Type t) + { + gen.Emit(OpCodes.Call, writeLineWithType(t)); if (write_commands) commands.Add("WriteLine"); } diff --git a/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs b/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs index 4ebe637..bd3a2d8 100644 --- a/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs +++ b/Module8/Visitors/GenCodeVisitors/GenCodeVisitor.cs @@ -5,6 +5,8 @@ using System.Text; using ProgramTree; using System.Reflection.Emit; +using SimpleParser; + namespace SimpleLang.Visitors { public class GenCodeVisitor: Visitor @@ -12,6 +14,8 @@ namespace SimpleLang.Visitors private Dictionary<string, LocalBuilder> vars = new Dictionary<string, LocalBuilder>(); private GenCodeCreator genc; + private List<Type> binOperationsTypes = new List<Type> { }; + public GenCodeVisitor() { genc = new GenCodeCreator(); @@ -26,8 +30,37 @@ namespace SimpleLang.Visitors { genc.Emit(OpCodes.Ldc_I4, num.Num); } + + public override void VisitFloatNumNode(FloatNumNode num) + { + genc.Emit(OpCodes.Ldc_R8, num.Num); + } + + public override void VisitBoolNumNode(BoolNumNode num) + { + genc.Emit(num.Num ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); + } + + public override void VisitCharNumNode(CharNumNode num) + { + genc.Emit(OpCodes.Ldc_I4, num.Num); + } public override void VisitBinOpNode(BinOpNode binop) { + if(!(binop.Left is BinOpNode)) + { + Type t = exprNodeToInnerType(binop.Left); + binOperationsTypes.Add(t); + } + + if (!(binop.Right is BinOpNode)) + { + Type t = exprNodeToInnerType(binop.Right); + binOperationsTypes.Add(t); + } + + + binop.Left.Visit(this); binop.Right.Visit(this); switch (binop.Op) @@ -49,6 +82,10 @@ namespace SimpleLang.Visitors break; } + + /*char a1 = 'a'; char a2 = 'a'; + + var c = a1 a2;*/ } public override void VisitAssignNode(AssignNode a) { @@ -89,27 +126,38 @@ namespace SimpleLang.Visitors public override void VisitWriteNode(WriteNode w) { w.Expr.Visit(this); - genc.EmitWriteLine(); + + Type t = exprNodeToInnerType(w.Expr); + genc.EmitWriteLine(t); } public override void VisitVarDefNode(VarDefNode w) { + Type t = ParserHelper.castSymbolTypeToInner(w.type); + foreach (var v in w.vars) - vars[v.Name] = genc.DeclareLocal(typeof(int)); + { + vars[v.Name] = genc.DeclareLocal(t); + } + } public override void VisitIfNode(IfNode cond) { var elseLabel = genc.DefineLabel(); + var endLabel = genc.DefineLabel(); cond.expr.Visit(this); genc.Emit(OpCodes.Ldc_I4_0); // положил 0 на стек genc.Emit(OpCodes.Beq, elseLabel); // если if expr == 0 тогда переод к elseLabel cond.ifTrue.Visit(this); + genc.Emit(OpCodes.Br, endLabel); genc.MarkLabel(elseLabel); if (cond.ifFalse != null) cond.ifFalse.Visit(this); + + genc.MarkLabel(endLabel); } public override void VisitWhileNode(WhileNode whileNode) @@ -162,5 +210,32 @@ namespace SimpleLang.Visitors foreach (var s in genc.commands) Console.WriteLine(s); } + + + private Type exprNodeToInnerType(ExprNode node) + { + Type t = typeof(int); + if (node is IntNumNode) + { + t = typeof(int); + } + else if (node is FloatNumNode) + { + t = typeof(double); + } + else if (node is BoolNumNode) + { + t = typeof(bool); + } + else if (node is CharNumNode) + { + t = typeof(char); + } + else if (node is IdNode id) + { + t = ParserHelper.castSymbolTypeToInner(SymbolTable.vars[id.Name]); + } + return t; + } } } diff --git a/Module8/Visitors/Visitor.cs b/Module8/Visitors/Visitor.cs index a7b6b44..4a3d427 100644 --- a/Module8/Visitors/Visitor.cs +++ b/Module8/Visitors/Visitor.cs @@ -9,7 +9,7 @@ namespace SimpleLang.Visitors public abstract class Visitor { public virtual void VisitIdNode(IdNode id) { } - public virtual void VisitIntNumNode(IntNumNode num) { } + public virtual void VisitBinOpNode(BinOpNode binop) { } public virtual void VisitAssignNode(AssignNode a) { } public virtual void VisitCycleNode(CycleNode c) { } @@ -21,5 +21,13 @@ namespace SimpleLang.Visitors public virtual void VisitWhileNode(WhileNode whileNode) { } public virtual void VisitRepeatNode(RepeatNode repeatNodee) { } + + public virtual void VisitIntNumNode(IntNumNode num) { } + + public virtual void VisitFloatNumNode(FloatNumNode num) { } + + public virtual void VisitBoolNumNode(BoolNumNode num) { } + + public virtual void VisitCharNumNode(CharNumNode num) { } } } diff --git a/Module8/generateParserScanner.bat b/Module8/generateParserScanner.bat index 7ca5476..06c5897 100644 --- a/Module8/generateParserScanner.bat +++ b/Module8/generateParserScanner.bat @@ -1,3 +1,4 @@ cls gplex.exe /unicode SimpleLex.lex gppg.exe /no-lines /gplex SimpleYacc.y +pause diff --git a/TestCodeGenerator/Tests.cs b/TestCodeGenerator/Tests.cs index cb30d77..e7994e2 100644 --- a/TestCodeGenerator/Tests.cs +++ b/TestCodeGenerator/Tests.cs @@ -12,6 +12,8 @@ namespace TestCodeGenerator { public static Parser Parse(string text) { + System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); + Scanner scanner = new Scanner(); scanner.SetSource(text, 0); Parser parser = new Parser(scanner); @@ -62,7 +64,13 @@ namespace TestCodeGenerator //code.PrintCommands(); code.RunProgram(); } - + + [Test] + public void SmokeTest2() + { + Assert.AreEqual("2.2", TestHelper.GenerateNRun(@"begin float a; a := 1.2; if a then a:=a+1 else a:=a+2; write(a) end")); + } + [Test] public void TestOutput() { @@ -72,7 +80,7 @@ namespace TestCodeGenerator [Test] public void TestIntDivMod() { - Assert.AreEqual("48", TestHelper.GenerateNRun(@"begin var a; a := (232 / 5) + (232 % 5); write(a) end")); + Assert.AreEqual("48", TestHelper.GenerateNRun(@"begin var b; b := (232 / 5) + (232 % 5); write(b) end")); } [Test] @@ -94,5 +102,41 @@ namespace TestCodeGenerator { Assert.AreEqual("1024", TestHelper.GenerateNRun(@"begin var a3,b3; b3:=1; a3:=10; repeat a3:=a3-1; b3:=b3*2 until a3; write(b3) end")); } + + + [Test] + public void TestTypeFloat() + { + Assert.AreEqual("1.2", TestHelper.GenerateNRun(@"begin float a4; a4:=1.2; write(a4) end")); + } + + [Test] + public void TestTypeInt() + { + Assert.AreEqual("2", TestHelper.GenerateNRun(@"begin int a5; a5:=2; write(a5) end")); + } + + [Test] + public void TestTypeBool() + { + Assert.AreEqual("False", TestHelper.GenerateNRun(@"begin bool a6; a6:=false; write(a6) end")); + + Assert.AreEqual("True", TestHelper.GenerateNRun(@"begin bool a7; a7:=true; write(a7) end")); + } + + [Test] + public void TestTypeChar() + { + Assert.AreEqual("a", TestHelper.GenerateNRun(@"begin char c1; c1:='a'; write(c1) end")); + + } + + [Test] + public void TestTypes() + { + Assert.AreEqual("2.4", TestHelper.GenerateNRun(@"begin var b; b := (232 / 5) + (232 % 5); write(b) end")); + + //Assert.AreEqual("2.4", TestHelper.GenerateNRun(@"begin int b; b := 1.2; write(b) end")); + } } } \ No newline at end of file diff --git a/TestVisitors/Tests.cs b/TestVisitors/Tests.cs index 67c5747..a3aa446 100644 --- a/TestVisitors/Tests.cs +++ b/TestVisitors/Tests.cs @@ -47,16 +47,16 @@ namespace TestVisitors cycle 3 begin a := 1; - a := 1; - a := 1; - a := 1; - a := 1; - a := 1; - a := 1; - a := 1; - a := 1; - a := 1; end; + a := 1; + a := 1; + a := 1; + a := 1; + a := 1; + a := 1; + a := 1; + a := 1; + a := 1; write(a) end; cycle 3 -- GitLab