public void testAddListToExistChildren() { // Add child ^(nil 101 102 103) to root ^(5 6) // should add 101 102 103 to end of 5's child list CommonTree root = new CommonTree(new CommonToken(5)); root.AddChild(new CommonTree(new CommonToken(6))); // child tree CommonTree r0 = new CommonTree((IToken)null); CommonTree c0, c1, c2; r0.AddChild(c0 = new CommonTree(new CommonToken(101))); r0.AddChild(c1 = new CommonTree(new CommonToken(102))); r0.AddChild(c2 = new CommonTree(new CommonToken(103))); root.AddChild(r0); Assert.IsNull(root.parent); Assert.AreEqual(-1, root.childIndex); // check children of root all point at root Assert.AreEqual(root, c0.parent); Assert.AreEqual(1, c0.childIndex); Assert.AreEqual(root, c0.parent); Assert.AreEqual(2, c1.childIndex); Assert.AreEqual(root, c0.parent); Assert.AreEqual(3, c2.childIndex); }
public void test4Nodes() { // ^(101 ^(102 103) 104) CommonTree r0 = new CommonTree(new CommonToken(101)); r0.AddChild(new CommonTree(new CommonToken(102))); r0.GetChild(0).AddChild(new CommonTree(new CommonToken(103))); r0.AddChild(new CommonTree(new CommonToken(104))); Assert.IsNull(r0.parent); Assert.AreEqual(-1, r0.childIndex); }
/// <summary> /// Test a tree with four nodes - ^(101 ^(102 103) 104) /// </summary> public void test4Nodes() { ITree t = new CommonTree(new CommonToken(101)); t.AddChild(new CommonTree(new CommonToken(102))); t.GetChild(0).AddChild(new CommonTree(new CommonToken(103))); t.AddChild(new CommonTree(new CommonToken(104))); ITreeNodeStream stream = CreateCommonTreeNodeStream(t); string expected = " 101 102 103 104"; string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expected, actual); expected = " 101 2 102 2 103 3 104 3"; actual = stream.ToString(); Assert.AreEqual(expected, actual); }
public void testList() { // ^(nil 101 102 103) CommonTree r0 = new CommonTree((IToken)null); CommonTree c0, c1, c2; r0.AddChild(c0 = new CommonTree(new CommonToken(101))); r0.AddChild(c1 = new CommonTree(new CommonToken(102))); r0.AddChild(c2 = new CommonTree(new CommonToken(103))); Assert.IsNull(r0.Parent); Assert.AreEqual(-1, r0.ChildIndex); Assert.AreEqual(r0, c0.Parent); Assert.AreEqual(0, c0.ChildIndex); Assert.AreEqual(r0, c1.Parent); Assert.AreEqual(1, c1.ChildIndex); Assert.AreEqual(r0, c2.Parent); Assert.AreEqual(2, c2.ChildIndex); }
public void testDupTree() { // ^(101 ^(102 103 ^(106 107) ) 104 105) CommonTree r0 = new CommonTree(new CommonToken(101)); CommonTree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); CommonTree dup = (CommonTree)(new CommonTreeAdaptor()).DupTree(r0); Assert.IsNull(dup.parent); Assert.AreEqual(-1, dup.childIndex); dup.SanityCheckParentAndChildIndexes(); }
public void testMarkRewindEntire() { // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); int m = stream.Mark(); // MARK for (int k = 1; k <= 13; k++) { // consume til end stream.LT(1); stream.Consume(); } Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); Assert.AreEqual(Token.UP, ((ITree)stream.LT(-1)).Type); stream.Rewind(m); // REWIND // consume til end again :) for (int k = 1; k <= 13; k++) { // consume til end stream.LT(1); stream.Consume(); } Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); Assert.AreEqual(Token.UP, ((ITree)stream.LT(-1)).Type); }
public void testLT() { // ^(101 ^(102 103) 104) ITree t = new CommonTree(new CommonToken(101)); t.AddChild(new CommonTree(new CommonToken(102))); t.GetChild(0).AddChild(new CommonTree(new CommonToken(103))); t.AddChild(new CommonTree(new CommonToken(104))); ITreeNodeStream stream = CreateCommonTreeNodeStream(t); Assert.AreEqual(101, ((ITree)stream.LT(1)).Type); Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(2)).Type); Assert.AreEqual(102, ((ITree)stream.LT(3)).Type); Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(4)).Type); Assert.AreEqual(103, ((ITree)stream.LT(5)).Type); Assert.AreEqual(Token.UP, ((ITree)stream.LT(6)).Type); Assert.AreEqual(104, ((ITree)stream.LT(7)).Type); Assert.AreEqual(Token.UP, ((ITree)stream.LT(8)).Type); Assert.AreEqual(Token.EOF, ((ITree)stream.LT(9)).Type); // check way ahead Assert.AreEqual(Token.EOF, ((ITree)stream.LT(100)).Type); }
public void testPushPop() { // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r1.AddChild(new CommonTree(new CommonToken(103))); r0.AddChild(r1); ITree r2 = new CommonTree(new CommonToken(104)); r2.AddChild(new CommonTree(new CommonToken(105))); r0.AddChild(r2); ITree r3 = new CommonTree(new CommonToken(106)); r3.AddChild(new CommonTree(new CommonToken(107))); r0.AddChild(r3); r0.AddChild(new CommonTree(new CommonToken(108))); r0.AddChild(new CommonTree(new CommonToken(109))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); String expecting = " 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3"; String found = stream.ToString(); Assert.AreEqual(expecting, found); // Assume we want to hit node 107 and then "call 102" then return int indexOf102 = 2; int indexOf107 = 12; for (int k = 1; k <= indexOf107; k++) { // consume til 107 node stream.Consume(); } // CALL 102 Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); stream.Push(indexOf102); Assert.AreEqual(102, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 102 Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume DN Assert.AreEqual(103, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 103 Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); // RETURN stream.Pop(); Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); }
public void testMarkRewindInMiddle() { // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); for (int k = 1; k <= 7; k++) { // consume til middle //System.out.println(((ITree)stream.LT(1)).Type); stream.Consume(); } Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); int m = stream.Mark(); // MARK stream.Consume(); // consume 107 stream.Consume(); // consume UP stream.Consume(); // consume UP stream.Consume(); // consume 104 stream.Rewind(m); // REWIND Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(104, ((ITree)stream.LT(1)).Type); stream.Consume(); // now we're past rewind position Assert.AreEqual(105, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); Assert.AreEqual(Token.UP, ((ITree)stream.LT(-1)).Type); }
public void testAoverB() { ITree t = new CommonTree(new CommonToken(101)); t.AddChild(new CommonTree(new CommonToken(102))); ITreeNodeStream stream = CreateCommonTreeNodeStream(t); string expected = " 101 102"; string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expected, actual); expected = " 101 2 102 3"; actual = stream.ToString(); Assert.AreEqual(expected, actual); }
public void testListWithOneNode() { ITree root = new CommonTree((IToken)null); root.AddChild(new CommonTree(new CommonToken(101))); CommonTreeNodeStream stream = new CommonTreeNodeStream(root); string expected = " 101"; string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expected, actual); expected = " 101"; actual = stream.ToString(); Assert.AreEqual(expected, actual); }
public void testReplaceWithOneChildren() { // assume token type 99 and use text CommonTree t = new CommonTree(new CommonToken(99, "a")); CommonTree c0 = new CommonTree(new CommonToken(99, "b")); t.AddChild(c0); CommonTree newChild = new CommonTree(new CommonToken(99, "c")); t.ReplaceChildren(0, 0, newChild); String expected = "(a c)"; Assert.AreEqual(expected, t.ToStringTree()); t.SanityCheckParentAndChildIndexes(); }
public void testBecomeRoot5() { // ^(nil 5) becomes new root of ^(101 102 103) CommonTree newRoot = new CommonTree((IToken)null); newRoot.AddChild(new CommonTree(new CommonToken(5))); CommonTree oldRoot = new CommonTree(new CommonToken(101)); oldRoot.AddChild(new CommonTree(new CommonToken(102))); oldRoot.AddChild(new CommonTree(new CommonToken(103))); ITreeAdaptor adaptor = new CommonTreeAdaptor(); adaptor.BecomeRoot(newRoot, oldRoot); newRoot.SanityCheckParentAndChildIndexes(); }
public void testMarkRewindNested() { // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); int m = stream.Mark(); // MARK at start stream.Consume(); // consume 101 stream.Consume(); // consume DN int m2 = stream.Mark(); // MARK on 102 stream.Consume(); // consume 102 stream.Consume(); // consume DN stream.Consume(); // consume 103 stream.Consume(); // consume 106 stream.Rewind(m2); // REWIND to 102 Assert.AreEqual(102, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // stop at 103 and rewind to start stream.Rewind(m); // REWIND to 101 Assert.AreEqual(101, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(102, ((ITree)stream.LT(1)).Type); stream.Consume(); Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); }
public void testReplaceAllWithTwo() { ITreeAdaptor adaptor = new CommonTreeAdaptor(); CommonTree t = new CommonTree(new CommonToken(99, "a")); t.AddChild(new CommonTree(new CommonToken(99, "b"))); t.AddChild(new CommonTree(new CommonToken(99, "c"))); t.AddChild(new CommonTree(new CommonToken(99, "d"))); CommonTree newChildren = (CommonTree)adaptor.Nil(); newChildren.AddChild(new CommonTree(new CommonToken(99, "x"))); newChildren.AddChild(new CommonTree(new CommonToken(99, "y"))); t.ReplaceChildren(0, 2, newChildren); String expected = "(a x y)"; Assert.AreEqual(expected, t.ToStringTree()); t.SanityCheckParentAndChildIndexes(); }
public static OrigDataType Check(AstNode node, Context context) { switch (node.Type) { case MathExprLexer.PROGRAM: { if (context == null) context = new Context(context); CheckBlock(node, context); return new OrigDataType(DataType.Void); } case MathExprLexer.BLOCK: { context = new Context(context); contexts.Add(context); CheckBlock(node, context); return new OrigDataType(DataType.Void); } case MathExprLexer.LET: case MathExprLexer.VAR: { List<AstNode> nodes = new List<AstNode>(); //String str = node.GetChild(1).GetChild(0).Text; OrigDataType dataType; //OrigDataType dataType = strToDataType(node.GetChild(1).GetChild(0).Text); for (int i = 0; i < node.ChildCount; i++) { dataType = new OrigDataType(DataType.Void); AstNode tempi = (AstNode)node.GetChild(i); Ident ident = context.InThisContext(node.GetChild(i).Text); if (ident != null) throw new ApplicationException(string.Format("Identifier {0} already exists", tempi.Text)); String typeText = node.Type == MathExprLexer.VAR ? "VARS" : "LETS"; AstNode var = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.VARS, typeText)); var.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, tempi.Text))); nodes.Add(var); for (int j = 0; j < node.GetChild(i).ChildCount; j++) { AstNode tempj = (AstNode)node.GetChild(i).GetChild(j); if (tempj.Token.Type == MathExprLexer.TYPE && tempj.ChildCount > 0) { dataType.ReturnFromType(tempj); AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; var.AddChild(tempType); } if (tempj.Token.Type == MathExprLexer.ASSIGN) { AstNode tempAssign = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.ASSIGN, "=")); tempAssign.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, tempi.Text))); tempAssign.AddChild(tempj.GetChild(0)); nodes.Add(tempAssign); if (dataType.SimpleDataType == DataType.Void) { dataType = Check((AstNode)tempAssign.GetChild(1), context); AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; AstNode tempCheckArrayPart = (AstNode)tempj.GetChild(0); //часть массива if (tempCheckArrayPart.Token.Type == MathExprLexer.ARRAY) { dataType.Check((AstNode)tempAssign.GetChild(1)); AstNode tempTypeArr = (AstNode)tempj.GetChild(0); tempType.ODataType.ArrayCount = tempTypeArr.ODataType.ArrayCount; } //вызов функции if (tempCheckArrayPart.Token.Type == MathExprLexer.FUNC_CALL) { Check((AstNode)tempAssign.GetChild(1), context); tempType.ODataType = (tempAssign.GetChild(1) as AstNode).ODataType; } var.AddChild(tempType); crutch++; } } } string name = nodes[i + i].GetChild(0).Text; context[name] = new Ident(name, context.ParentContext == null ? IdentType.GlobalVar : IdentType.LocalVar, dataType, nodes[i + i], identIndex++); } Antlr.Runtime.Tree.CommonTree tree = new Antlr.Runtime.Tree.CommonTree(); foreach (AstNode n in nodes) tree.AddChild(n); node.Parent.ReplaceChildren(node.ChildIndex, node.ChildIndex, tree); return new OrigDataType(DataType.Void); } case MathExprLexer.VARS: case MathExprLexer.PARAMS: return new OrigDataType(DataType.Void); case MathExprLexer.FUNC: { OrigDataType dataType = new OrigDataType(strToDataType(node.GetChild(2).GetChild(0).Text)); string name = node.GetChild(0).Text; Ident ident = context[name]; if (ident != null) throw new ApplicationException(string.Format("Identifier {0} already exists", name)); Ident func = new Ident(name, IdentType.Function, dataType, node, identIndex++); context[name] = func; context = new Context(context); contexts.Add(context); AstNode _params = (AstNode)node.GetChild(1); for (int i = 0; i < _params.ChildCount; i++) { OrigDataType paramDataType = new OrigDataType(strToDataType(_params.GetChild(i).GetChild(0).Text)); string paramName = _params.GetChild(i).Text; if (paramDataType.SimpleDataType == DataType.Void) throw new ApplicationException(string.Format("In function {0} void param {1}", name, paramName)); context[paramName] = new Ident(paramName, IdentType.Param, paramDataType, (AstNode)_params.GetChild(i), identIndex++); } context.Function = func; if (dataType.SimpleDataType == DataType.Array) { dataType.ReturnFromType((AstNode)node.GetChild(2).GetChild(0)); dataType.ArrayCount++; AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; node.GetChild(2).ReplaceChildren(0, 0, tempType); } Check((AstNode)node.GetChild(3), context); return new OrigDataType(DataType.Void); } case MathExprLexer.CONVERT: { OrigDataType dataType = new OrigDataType(strToDataType(node.GetChild(1).Text)); return dataType; } case MathExprLexer.FUNC_CALL: { Ident ident = context[node.GetChild(0).Text]; node.ODataType = ident.DataType; if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); if (ident.IdentType != IdentType.Function) throw new ApplicationException(string.Format("Identifier {0} is not function", node.GetChild(0).Text)); if (node.ChildCount == 2 && node.GetChild(1).ChildCount != ident.Node.GetChild(1).ChildCount) throw new ApplicationException(string.Format("Not equals params count in function {0}", node.GetChild(0).Text)); for (int i = 0; i < ident.Node.GetChild(1).ChildCount; i++) { OrigDataType formalDataType = new OrigDataType(strToDataType(ident.Node.GetChild(1).GetChild(i).GetChild(0).Text)); OrigDataType factDataType = Check((AstNode)node.GetChild(1).GetChild(i), context); if (formalDataType.SimpleDataType != factDataType.SimpleDataType) { if (formalDataType.SimpleDataType == DataType.Double && factDataType.SimpleDataType == DataType.Int) convert((AstNode)node.GetChild(1).GetChild(i), new OrigDataType(DataType.Double)); else throw new ApplicationException(string.Format("In function {0} param {1} incopotible types {2} {3}", node.GetChild(0).Text, i, dataTypeToStr(formalDataType.SimpleDataType), dataTypeToStr(factDataType.SimpleDataType))); } } return new OrigDataType(strToDataType(ident.Node.GetChild(2).GetChild(0).Text)); } case MathExprLexer.IDENT: { Ident ident = context[node.Text]; if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.Text)); if (ident.IdentType == IdentType.Function) { if (ident.DataType.SimpleDataType == DataType.Void) throw new ApplicationException(string.Format("Function {0} returns void", ident.Name)); if (ident.Node.GetChild(1).ChildCount > 0) throw new ApplicationException(string.Format("No params for function {0} call", ident.Name)); AstNode call = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.FUNC_CALL)); call.AddChild(node); call.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.PARAMS))); node.Parent.SetChild(node.ChildIndex, call); node.ODataType = ident.DataType; return node.ODataType; } else { node.ODataType = ident.DataType; return node.ODataType; } } case MathExprLexer.NUMBER: { node.ODataType = node.Text.Contains(".") ? new OrigDataType(DataType.Double) : new OrigDataType(DataType.Int); return node.ODataType; } case MathExprLexer.STRINGVAL: { node.ODataType.SimpleDataType = DataType.String; return node.ODataType; } case MathExprLexer.TRUE: case MathExprLexer.FALSE: { node.ODataType.SimpleDataType = DataType.Bool; return node.ODataType; } case MathExprLexer.ARRAY: { OrigDataType dataType = new OrigDataType(DataType.Void); dataType.ReturnFromValue(node); node.ODataType = dataType; int tmpArr = dataType.ArrayCount; //int type = node.GetChild(0).Type; for (int i = 0; i < node.ChildCount; i++) { dataType = Check((AstNode)node.GetChild(i), context); } return dataType; } case MathExprLexer.ARRAYPART: { Ident ident = context[node.GetChild(0).Text]; OrigDataType dataType = new OrigDataType(ident.DataType.SimpleDataType); dataType.ArrayCount = ident.DataType.ArrayCount - node.ChildCount + 1; for (int i = 1; i < node.ChildCount; i++) { Check((AstNode)node.GetChild(i), context); } node.ODataType = dataType; return dataType; } case MathExprLexer.ASSIGN: { Ident ident = context[node.GetChild(0).Text]; if (node.GetChild(0).Type == MathExprLexer.ARRAYPART) { ident = context[node.GetChild(0).GetChild(0).Text]; } if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); if (ident.IdentType == IdentType.Function) throw new ApplicationException(string.Format("Assign to function {0}", node.GetChild(0).Text)); OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (ident.DataType.SimpleDataType == DataType.Void) return rightDataType; //if(ident.OrigDataType == OrigDataType.Void) if (ident.DataType.SimpleDataType != rightDataType.SimpleDataType) { if (ident.DataType.SimpleDataType == DataType.Double && rightDataType.SimpleDataType == DataType.Int) convert((AstNode)node.GetChild(1), new OrigDataType(DataType.Double)); else throw new ApplicationException(string.Format("Assign incopotible types {0} {1}", dataTypeToStr(ident.DataType.SimpleDataType), dataTypeToStr(rightDataType.SimpleDataType))); } return new OrigDataType(DataType.Void); } case MathExprLexer.RETURN: { if (context.Function == null) throw new ApplicationException(string.Format("Return not in function in line {0}", node.Line)); OrigDataType returnDataType = Check((AstNode)node.GetChild(0), context); if (context.Function.DataType.SimpleDataType != returnDataType.SimpleDataType && context.Function.DataType.ArrayCount != returnDataType.ArrayCount) { if (context.Function.DataType.SimpleDataType == DataType.Double && returnDataType.SimpleDataType == DataType.Int) convert((AstNode)node.GetChild(0), new OrigDataType(DataType.Double)); else throw new ApplicationException(string.Format("Return incopotible types {0} {1}", dataTypeToStr(context.Function.DataType.SimpleDataType), dataTypeToStr(returnDataType.SimpleDataType))); } return new OrigDataType(DataType.Void); } case MathExprLexer.SINCR: case MathExprLexer.EINCR: case MathExprLexer.SDECR: case MathExprLexer.EDECR: { OrigDataType idenDataType = Check((AstNode)node.GetChild(0), context); if (idenDataType.SimpleDataType != DataType.Int && idenDataType.SimpleDataType != DataType.Double) throw new ApplicationException(string.Format("In crement condition type is {0}", dataTypeToStr(idenDataType.SimpleDataType))); return new OrigDataType(DataType.Void); } case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: case MathExprLexer.GE: case MathExprLexer.LE: case MathExprLexer.NE: case MathExprLexer.EQ: case MathExprLexer.GT: case MathExprLexer.LT: { bool compareOperation = true; switch (node.Type) { case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: compareOperation = false; break; } OrigDataType leftDataType = Check((AstNode)node.GetChild(0), context); OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (leftDataType.SimpleDataType != DataType.Double && leftDataType.SimpleDataType != DataType.Int && leftDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("Left operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); if (rightDataType.SimpleDataType != DataType.Double && rightDataType.SimpleDataType != DataType.Int && leftDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("Right operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); if (leftDataType.SimpleDataType == DataType.Double) { if (rightDataType.SimpleDataType == DataType.Int) convert((AstNode)node.GetChild(1), new OrigDataType(DataType.Double)); node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Double); return node.ODataType; } if (rightDataType.SimpleDataType == DataType.Double) { if (leftDataType.SimpleDataType == DataType.Int) convert((AstNode)node.GetChild(0), new OrigDataType(DataType.Double)); node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Double); return node.ODataType; } node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Int); return node.ODataType; } case MathExprLexer.NOT: { OrigDataType dataType = Check((AstNode)node.GetChild(0), context); if (dataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("Not operator with type {0}", dataTypeToStr(dataType.SimpleDataType))); node.ODataType.SimpleDataType = DataType.Bool; return node.ODataType; } case MathExprLexer.AND: case MathExprLexer.OR: { OrigDataType leftDataType = Check((AstNode)node.GetChild(0), context); OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (leftDataType.SimpleDataType != DataType.Bool && rightDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("{0} operator with type {1}, {2}", node.Text, dataTypeToStr(leftDataType.SimpleDataType), dataTypeToStr(rightDataType.SimpleDataType))); node.ODataType = new OrigDataType(DataType.Bool); return node.ODataType; } case MathExprLexer.REPEATE: case MathExprLexer.WHILE: { OrigDataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); // context = new Context(context); Check((AstNode)node.GetChild(1), context); return new OrigDataType(DataType.Void); } case MathExprLexer.IF: { OrigDataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("In if condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); //context = new Context(context); Check((AstNode)node.GetChild(1), context); if (node.ChildCount == 3) Check((AstNode)node.GetChild(2), context); return new OrigDataType(DataType.Void); } case MathExprLexer.FOR: { for (int i = 0; i < node.ChildCount - 1; i++) { Check((AstNode)node.GetChild(i), context); } context = new Context(context); CheckBlock((AstNode)node.GetChild(node.ChildCount - 1), context); OrigDataType condDataType = Check((AstNode)node.GetChild(node.ChildCount - 3), context); if (condDataType.SimpleDataType != DataType.Bool) throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); return new OrigDataType(DataType.Void); } case MathExprLexer.SWITCH: { OrigDataType identDataType = Check((AstNode)node.GetChild(0), context); for (int i = 1; i < node.ChildCount; i++) { AstNode tempi = (AstNode)node.GetChild(i); for (int j = 0; j < tempi.GetChild(0).ChildCount; j++) { if (identDataType.SimpleDataType != Check((AstNode)tempi.GetChild(0).GetChild(j), context).SimpleDataType) throw new ApplicationException(string.Format("In switch identDataType type is {0}", dataTypeToStr(identDataType.SimpleDataType))); } context = new Context(context); CheckBlock((AstNode)tempi.GetChild(1), context); //Check((AstNode)node.GetChild(i), context); } //context = new Context(context); return new OrigDataType(DataType.Void); } case MathExprLexer.PRINT: { if (node.ChildCount > 0) { Check((AstNode)node.GetChild(0), context); if ((node.GetChild(0) as AstNode).ODataType.SimpleDataType != DataType.String) { convert((AstNode)node.GetChild(0), new OrigDataType(DataType.String)); } } return new OrigDataType(DataType.String); } default: { throw new ApplicationException("Unknown token type"); } } }
public void testNestedPushPop() { // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r1.AddChild(new CommonTree(new CommonToken(103))); r0.AddChild(r1); ITree r2 = new CommonTree(new CommonToken(104)); r2.AddChild(new CommonTree(new CommonToken(105))); r0.AddChild(r2); ITree r3 = new CommonTree(new CommonToken(106)); r3.AddChild(new CommonTree(new CommonToken(107))); r0.AddChild(r3); r0.AddChild(new CommonTree(new CommonToken(108))); r0.AddChild(new CommonTree(new CommonToken(109))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); // Assume we want to hit node 107 and then "call 102", which // calls 104, then return int indexOf102 = 2; int indexOf107 = 12; for (int k = 1; k <= indexOf107; k++) { // consume til 107 node stream.Consume(); } Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); // CALL 102 stream.Push(indexOf102); Assert.AreEqual(102, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 102 Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume DN Assert.AreEqual(103, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 103 // CALL 104 int indexOf104 = 6; stream.Push(indexOf104); Assert.AreEqual(104, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 102 Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume DN Assert.AreEqual(105, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 103 Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); // RETURN (to UP node in 102 subtree) stream.Pop(); Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); // RETURN (to empty stack) stream.Pop(); Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); }
public void testSeek() { // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 Up Up 104 105 Up EndOfFile ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); BufferedTreeNodeStream stream = new BufferedTreeNodeStream(r0); stream.Consume(); // consume 101 stream.Consume(); // consume DN stream.Consume(); // consume 102 stream.Seek(7); // seek to 107 Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 107 stream.Consume(); // consume Up stream.Consume(); // consume Up Assert.AreEqual(104, ((ITree)stream.LT(1)).Type); }
public void testList() { ITree root = new CommonTree((IToken)null); ITree t = new CommonTree(new CommonToken(101)); t.AddChild(new CommonTree(new CommonToken(102))); t.GetChild(0).AddChild(new CommonTree(new CommonToken(103))); t.AddChild(new CommonTree(new CommonToken(104))); ITree u = new CommonTree(new CommonToken(105)); root.AddChild(t); root.AddChild(u); CommonTreeNodeStream stream = new CommonTreeNodeStream(root); string expected = " 101 102 103 104 105"; string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expected, actual); expected = " 101 2 102 2 103 3 104 3 105"; actual = stream.ToString(); Assert.AreEqual(expected, actual); }
public void testBufferWrap() { int N = 10; // make tree with types: 1 2 ... INITIAL_LOOKAHEAD_BUFFER_SIZE+N ITree t = new CommonTree((IToken)null); for (int i = 0; i < UnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + N; i++) { t.AddChild(new CommonTree(new CommonToken(i + 1))); } // move head to index N ITreeNodeStream stream = CreateUnBufferedTreeNodeStream(t); for (int i = 1; i <= N; i++) { // consume N ITree node = (ITree)stream.LT(1); Assert.AreEqual(i, node.Type); stream.Consume(); } // now use LT to lookahead past end of buffer int remaining = UnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE - N; int wrapBy = 4; // wrap around by 4 nodes Assert.IsTrue(wrapBy < N, "bad test code; wrapBy must be less than N"); for (int i = 1; i <= remaining + wrapBy; i++) { // wrap past end of buffer ITree node = (ITree)stream.LT(i); // look ahead to ith token Assert.AreEqual(N + i, node.Type); } }
public void testPushPopFromEOF() { // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r1.AddChild(new CommonTree(new CommonToken(103))); r0.AddChild(r1); ITree r2 = new CommonTree(new CommonToken(104)); r2.AddChild(new CommonTree(new CommonToken(105))); r0.AddChild(r2); ITree r3 = new CommonTree(new CommonToken(106)); r3.AddChild(new CommonTree(new CommonToken(107))); r0.AddChild(r3); r0.AddChild(new CommonTree(new CommonToken(108))); r0.AddChild(new CommonTree(new CommonToken(109))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); while (stream.LA(1) != Token.EOF) { stream.Consume(); } int indexOf102 = 2; int indexOf104 = 6; Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); // CALL 102 stream.Push(indexOf102); Assert.AreEqual(102, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 102 Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume DN Assert.AreEqual(103, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 103 Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); // RETURN (to empty stack) stream.Pop(); Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); // CALL 104 stream.Push(indexOf104); Assert.AreEqual(104, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 102 Assert.AreEqual(Token.DOWN, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume DN Assert.AreEqual(105, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 103 Assert.AreEqual(Token.UP, ((ITree)stream.LT(1)).Type); // RETURN (to empty stack) stream.Pop(); Assert.AreEqual(Token.EOF, ((ITree)stream.LT(1)).Type); }
public static OrigDataType Check(AstNode node, Context context) { switch (node.Type) { case MathExprLexer.PROGRAM: { if (context == null) { context = new Context(context); } CheckBlock(node, context); return(new OrigDataType(DataType.Void)); } case MathExprLexer.BLOCK: { context = new Context(context); contexts.Add(context); CheckBlock(node, context); return(new OrigDataType(DataType.Void)); } case MathExprLexer.LET: case MathExprLexer.VAR: { List <AstNode> nodes = new List <AstNode>(); //String str = node.GetChild(1).GetChild(0).Text; OrigDataType dataType; //OrigDataType dataType = strToDataType(node.GetChild(1).GetChild(0).Text); for (int i = 0; i < node.ChildCount; i++) { dataType = new OrigDataType(DataType.Void); AstNode tempi = (AstNode)node.GetChild(i); Ident ident = context.InThisContext(node.GetChild(i).Text); if (ident != null) { throw new ApplicationException(string.Format("Identifier {0} already exists", tempi.Text)); } String typeText = node.Type == MathExprLexer.VAR ? "VARS" : "LETS"; AstNode var = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.VARS, typeText)); var.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, tempi.Text))); nodes.Add(var); for (int j = 0; j < node.GetChild(i).ChildCount; j++) { AstNode tempj = (AstNode)node.GetChild(i).GetChild(j); if (tempj.Token.Type == MathExprLexer.TYPE && tempj.ChildCount > 0) { dataType.ReturnFromType(tempj); AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; var.AddChild(tempType); } if (tempj.Token.Type == MathExprLexer.ASSIGN) { AstNode tempAssign = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.ASSIGN, "=")); tempAssign.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, tempi.Text))); tempAssign.AddChild(tempj.GetChild(0)); nodes.Add(tempAssign); if (dataType.SimpleDataType == DataType.Void) { dataType = Check((AstNode)tempAssign.GetChild(1), context); AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; AstNode tempCheckArrayPart = (AstNode)tempj.GetChild(0); //часть массива if (tempCheckArrayPart.Token.Type == MathExprLexer.ARRAY) { dataType.Check((AstNode)tempAssign.GetChild(1)); AstNode tempTypeArr = (AstNode)tempj.GetChild(0); tempType.ODataType.ArrayCount = tempTypeArr.ODataType.ArrayCount; } //вызов функции if (tempCheckArrayPart.Token.Type == MathExprLexer.FUNC_CALL) { Check((AstNode)tempAssign.GetChild(1), context); tempType.ODataType = (tempAssign.GetChild(1) as AstNode).ODataType; } var.AddChild(tempType); crutch++; } } } string name = nodes[i + i].GetChild(0).Text; context[name] = new Ident(name, context.ParentContext == null ? IdentType.GlobalVar : IdentType.LocalVar, dataType, nodes[i + i], identIndex++); } Antlr.Runtime.Tree.CommonTree tree = new Antlr.Runtime.Tree.CommonTree(); foreach (AstNode n in nodes) { tree.AddChild(n); } node.Parent.ReplaceChildren(node.ChildIndex, node.ChildIndex, tree); return(new OrigDataType(DataType.Void)); } case MathExprLexer.VARS: case MathExprLexer.PARAMS: return(new OrigDataType(DataType.Void)); case MathExprLexer.FUNC: { OrigDataType dataType = new OrigDataType(strToDataType(node.GetChild(2).GetChild(0).Text)); string name = node.GetChild(0).Text; Ident ident = context[name]; if (ident != null) { throw new ApplicationException(string.Format("Identifier {0} already exists", name)); } Ident func = new Ident(name, IdentType.Function, dataType, node, identIndex++); context[name] = func; context = new Context(context); contexts.Add(context); AstNode _params = (AstNode)node.GetChild(1); for (int i = 0; i < _params.ChildCount; i++) { OrigDataType paramDataType = new OrigDataType(strToDataType(_params.GetChild(i).GetChild(0).Text)); string paramName = _params.GetChild(i).Text; if (paramDataType.SimpleDataType == DataType.Void) { throw new ApplicationException(string.Format("In function {0} void param {1}", name, paramName)); } context[paramName] = new Ident(paramName, IdentType.Param, paramDataType, (AstNode)_params.GetChild(i), identIndex++); } context.Function = func; if (dataType.SimpleDataType == DataType.Array) { dataType.ReturnFromType((AstNode)node.GetChild(2).GetChild(0)); dataType.ArrayCount++; AstNode tempType = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.TYPE, dataTypeToStr(dataType.SimpleDataType))); tempType.ODataType = dataType; node.GetChild(2).ReplaceChildren(0, 0, tempType); } Check((AstNode)node.GetChild(3), context); return(new OrigDataType(DataType.Void)); } case MathExprLexer.CONVERT: { OrigDataType dataType = new OrigDataType(strToDataType(node.GetChild(1).Text)); return(dataType); } case MathExprLexer.FUNC_CALL: { Ident ident = context[node.GetChild(0).Text]; node.ODataType = ident.DataType; if (ident == null) { throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); } if (ident.IdentType != IdentType.Function) { throw new ApplicationException(string.Format("Identifier {0} is not function", node.GetChild(0).Text)); } if (node.ChildCount == 2 && node.GetChild(1).ChildCount != ident.Node.GetChild(1).ChildCount) { throw new ApplicationException(string.Format("Not equals params count in function {0}", node.GetChild(0).Text)); } for (int i = 0; i < ident.Node.GetChild(1).ChildCount; i++) { OrigDataType formalDataType = new OrigDataType(strToDataType(ident.Node.GetChild(1).GetChild(i).GetChild(0).Text)); OrigDataType factDataType = Check((AstNode)node.GetChild(1).GetChild(i), context); if (formalDataType.SimpleDataType != factDataType.SimpleDataType) { if (formalDataType.SimpleDataType == DataType.Double && factDataType.SimpleDataType == DataType.Int) { convert((AstNode)node.GetChild(1).GetChild(i), new OrigDataType(DataType.Double)); } else { throw new ApplicationException(string.Format("In function {0} param {1} incopotible types {2} {3}", node.GetChild(0).Text, i, dataTypeToStr(formalDataType.SimpleDataType), dataTypeToStr(factDataType.SimpleDataType))); } } } return(new OrigDataType(strToDataType(ident.Node.GetChild(2).GetChild(0).Text))); } case MathExprLexer.IDENT: { Ident ident = context[node.Text]; if (ident == null) { throw new ApplicationException(string.Format("Unknown identifier {0}", node.Text)); } if (ident.IdentType == IdentType.Function) { if (ident.DataType.SimpleDataType == DataType.Void) { throw new ApplicationException(string.Format("Function {0} returns void", ident.Name)); } if (ident.Node.GetChild(1).ChildCount > 0) { throw new ApplicationException(string.Format("No params for function {0} call", ident.Name)); } AstNode call = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.FUNC_CALL)); call.AddChild(node); call.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.PARAMS))); node.Parent.SetChild(node.ChildIndex, call); node.ODataType = ident.DataType; return(node.ODataType); } else { node.ODataType = ident.DataType; return(node.ODataType); } } case MathExprLexer.NUMBER: { node.ODataType = node.Text.Contains(".") ? new OrigDataType(DataType.Double) : new OrigDataType(DataType.Int); return(node.ODataType); } case MathExprLexer.STRINGVAL: { node.ODataType.SimpleDataType = DataType.String; return(node.ODataType); } case MathExprLexer.TRUE: case MathExprLexer.FALSE: { node.ODataType.SimpleDataType = DataType.Bool; return(node.ODataType); } case MathExprLexer.ARRAY: { OrigDataType dataType = new OrigDataType(DataType.Void); dataType.ReturnFromValue(node); node.ODataType = dataType; int tmpArr = dataType.ArrayCount; //int type = node.GetChild(0).Type; for (int i = 0; i < node.ChildCount; i++) { dataType = Check((AstNode)node.GetChild(i), context); } return(dataType); } case MathExprLexer.ARRAYPART: { Ident ident = context[node.GetChild(0).Text]; OrigDataType dataType = new OrigDataType(ident.DataType.SimpleDataType); dataType.ArrayCount = ident.DataType.ArrayCount - node.ChildCount + 1; for (int i = 1; i < node.ChildCount; i++) { Check((AstNode)node.GetChild(i), context); } node.ODataType = dataType; return(dataType); } case MathExprLexer.ASSIGN: { Ident ident = context[node.GetChild(0).Text]; if (node.GetChild(0).Type == MathExprLexer.ARRAYPART) { ident = context[node.GetChild(0).GetChild(0).Text]; } if (ident == null) { throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); } if (ident.IdentType == IdentType.Function) { throw new ApplicationException(string.Format("Assign to function {0}", node.GetChild(0).Text)); } OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (ident.DataType.SimpleDataType == DataType.Void) { return(rightDataType); } //if(ident.OrigDataType == OrigDataType.Void) if (ident.DataType.SimpleDataType != rightDataType.SimpleDataType) { if (ident.DataType.SimpleDataType == DataType.Double && rightDataType.SimpleDataType == DataType.Int) { convert((AstNode)node.GetChild(1), new OrigDataType(DataType.Double)); } else { throw new ApplicationException(string.Format("Assign incopotible types {0} {1}", dataTypeToStr(ident.DataType.SimpleDataType), dataTypeToStr(rightDataType.SimpleDataType))); } } return(new OrigDataType(DataType.Void)); } case MathExprLexer.RETURN: { if (context.Function == null) { throw new ApplicationException(string.Format("Return not in function in line {0}", node.Line)); } OrigDataType returnDataType = Check((AstNode)node.GetChild(0), context); if (context.Function.DataType.SimpleDataType != returnDataType.SimpleDataType && context.Function.DataType.ArrayCount != returnDataType.ArrayCount) { if (context.Function.DataType.SimpleDataType == DataType.Double && returnDataType.SimpleDataType == DataType.Int) { convert((AstNode)node.GetChild(0), new OrigDataType(DataType.Double)); } else { throw new ApplicationException(string.Format("Return incopotible types {0} {1}", dataTypeToStr(context.Function.DataType.SimpleDataType), dataTypeToStr(returnDataType.SimpleDataType))); } } return(new OrigDataType(DataType.Void)); } case MathExprLexer.SINCR: case MathExprLexer.EINCR: case MathExprLexer.SDECR: case MathExprLexer.EDECR: { OrigDataType idenDataType = Check((AstNode)node.GetChild(0), context); if (idenDataType.SimpleDataType != DataType.Int && idenDataType.SimpleDataType != DataType.Double) { throw new ApplicationException(string.Format("In crement condition type is {0}", dataTypeToStr(idenDataType.SimpleDataType))); } return(new OrigDataType(DataType.Void)); } case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: case MathExprLexer.GE: case MathExprLexer.LE: case MathExprLexer.NE: case MathExprLexer.EQ: case MathExprLexer.GT: case MathExprLexer.LT: { bool compareOperation = true; switch (node.Type) { case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: compareOperation = false; break; } OrigDataType leftDataType = Check((AstNode)node.GetChild(0), context); OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (leftDataType.SimpleDataType != DataType.Double && leftDataType.SimpleDataType != DataType.Int && leftDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("Left operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); } if (rightDataType.SimpleDataType != DataType.Double && rightDataType.SimpleDataType != DataType.Int && leftDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("Right operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); } if (leftDataType.SimpleDataType == DataType.Double) { if (rightDataType.SimpleDataType == DataType.Int) { convert((AstNode)node.GetChild(1), new OrigDataType(DataType.Double)); } node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Double); return(node.ODataType); } if (rightDataType.SimpleDataType == DataType.Double) { if (leftDataType.SimpleDataType == DataType.Int) { convert((AstNode)node.GetChild(0), new OrigDataType(DataType.Double)); } node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Double); return(node.ODataType); } node.ODataType = compareOperation ? new OrigDataType(DataType.Bool) : new OrigDataType(DataType.Int); return(node.ODataType); } case MathExprLexer.NOT: { OrigDataType dataType = Check((AstNode)node.GetChild(0), context); if (dataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("Not operator with type {0}", dataTypeToStr(dataType.SimpleDataType))); } node.ODataType.SimpleDataType = DataType.Bool; return(node.ODataType); } case MathExprLexer.AND: case MathExprLexer.OR: { OrigDataType leftDataType = Check((AstNode)node.GetChild(0), context); OrigDataType rightDataType = Check((AstNode)node.GetChild(1), context); if (leftDataType.SimpleDataType != DataType.Bool && rightDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("{0} operator with type {1}, {2}", node.Text, dataTypeToStr(leftDataType.SimpleDataType), dataTypeToStr(rightDataType.SimpleDataType))); } node.ODataType = new OrigDataType(DataType.Bool); return(node.ODataType); } case MathExprLexer.REPEATE: case MathExprLexer.WHILE: { OrigDataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); } // context = new Context(context); Check((AstNode)node.GetChild(1), context); return(new OrigDataType(DataType.Void)); } case MathExprLexer.IF: { OrigDataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("In if condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); } //context = new Context(context); Check((AstNode)node.GetChild(1), context); if (node.ChildCount == 3) { Check((AstNode)node.GetChild(2), context); } return(new OrigDataType(DataType.Void)); } case MathExprLexer.FOR: { for (int i = 0; i < node.ChildCount - 1; i++) { Check((AstNode)node.GetChild(i), context); } context = new Context(context); CheckBlock((AstNode)node.GetChild(node.ChildCount - 1), context); OrigDataType condDataType = Check((AstNode)node.GetChild(node.ChildCount - 3), context); if (condDataType.SimpleDataType != DataType.Bool) { throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType.SimpleDataType))); } return(new OrigDataType(DataType.Void)); } case MathExprLexer.SWITCH: { OrigDataType identDataType = Check((AstNode)node.GetChild(0), context); for (int i = 1; i < node.ChildCount; i++) { AstNode tempi = (AstNode)node.GetChild(i); for (int j = 0; j < tempi.GetChild(0).ChildCount; j++) { if (identDataType.SimpleDataType != Check((AstNode)tempi.GetChild(0).GetChild(j), context).SimpleDataType) { throw new ApplicationException(string.Format("In switch identDataType type is {0}", dataTypeToStr(identDataType.SimpleDataType))); } } context = new Context(context); CheckBlock((AstNode)tempi.GetChild(1), context); //Check((AstNode)node.GetChild(i), context); } //context = new Context(context); return(new OrigDataType(DataType.Void)); } case MathExprLexer.PRINT: { if (node.ChildCount > 0) { Check((AstNode)node.GetChild(0), context); if ((node.GetChild(0) as AstNode).ODataType.SimpleDataType != DataType.String) { convert((AstNode)node.GetChild(0), new OrigDataType(DataType.String)); } } return(new OrigDataType(DataType.String)); } default: { throw new ApplicationException("Unknown token type"); } } }
public void testReplaceOneWithTwoInMiddle() { ITreeAdaptor adaptor = new CommonTreeAdaptor(); CommonTree t = new CommonTree(new CommonToken(99, "a")); t.AddChild(new CommonTree(new CommonToken(99, "b"))); t.AddChild(new CommonTree(new CommonToken(99, "c"))); t.AddChild(new CommonTree(new CommonToken(99, "d"))); CommonTree newChildren = (CommonTree)adaptor.GetNilNode(); newChildren.AddChild(new CommonTree(new CommonToken(99, "x"))); newChildren.AddChild(new CommonTree(new CommonToken(99, "y"))); t.ReplaceChildren(1, 1, newChildren); String expected = "(a b x y d)"; Assert.AreEqual(expected, t.ToStringTree()); t.SanityCheckParentAndChildIndexes(); }
public void testSeekFromStart() { // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF ITree r0 = new CommonTree(new CommonToken(101)); ITree r1 = new CommonTree(new CommonToken(102)); r0.AddChild(r1); r1.AddChild(new CommonTree(new CommonToken(103))); ITree r2 = new CommonTree(new CommonToken(106)); r2.AddChild(new CommonTree(new CommonToken(107))); r1.AddChild(r2); r0.AddChild(new CommonTree(new CommonToken(104))); r0.AddChild(new CommonTree(new CommonToken(105))); CommonTreeNodeStream stream = new CommonTreeNodeStream(r0); stream.Seek(7); // seek to 107 Assert.AreEqual(107, ((ITree)stream.LT(1)).Type); stream.Consume(); // consume 107 stream.Consume(); // consume UP stream.Consume(); // consume UP Assert.AreEqual(104, ((ITree)stream.LT(1)).Type); }
public void testReplaceTwoWithOneAtRight() { CommonTree t = new CommonTree(new CommonToken(99, "a")); t.AddChild(new CommonTree(new CommonToken(99, "b"))); t.AddChild(new CommonTree(new CommonToken(99, "c"))); t.AddChild(new CommonTree(new CommonToken(99, "d"))); CommonTree newChild = new CommonTree(new CommonToken(99, "x")); t.ReplaceChildren(1, 2, newChild); String expected = "(a b x)"; Assert.AreEqual(expected, t.ToStringTree()); t.SanityCheckParentAndChildIndexes(); }
public void testBufferOverflow() { StringBuilder buf = new StringBuilder(); StringBuilder buf2 = new StringBuilder(); // make ^(101 102 ... n) ITree t = new CommonTree(new CommonToken(101)); buf.Append(" 101"); buf2.Append(" 101"); buf2.Append(" "); buf2.Append(Token.DOWN); for (int i = 0; i <= UnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + 10; i++) { t.AddChild(new CommonTree(new CommonToken(102 + i))); buf.Append(" "); buf.Append(102 + i); buf2.Append(" "); buf2.Append(102 + i); } buf2.Append(" "); buf2.Append(Token.UP); ITreeNodeStream stream = CreateUnBufferedTreeNodeStream(t); String expecting = buf.ToString(); String found = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expecting, found); expecting = buf2.ToString(); found = stream.ToString(); Assert.AreEqual(expecting, found); }
public void testList2() { // Add child ^(nil 101 102 103) to root 5 // should pull 101 102 103 directly to become 5's child list CommonTree root = new CommonTree(new CommonToken(5)); // child tree CommonTree r0 = new CommonTree((IToken)null); CommonTree c0, c1, c2; r0.AddChild(c0 = new CommonTree(new CommonToken(101))); r0.AddChild(c1 = new CommonTree(new CommonToken(102))); r0.AddChild(c2 = new CommonTree(new CommonToken(103))); root.AddChild(r0); Assert.IsNull(root.parent); Assert.AreEqual(-1, root.childIndex); // check children of root all point at root Assert.AreEqual(root, c0.parent); Assert.AreEqual(0, c0.childIndex); Assert.AreEqual(root, c0.parent); Assert.AreEqual(1, c1.childIndex); Assert.AreEqual(root, c0.parent); Assert.AreEqual(2, c2.childIndex); }
public void testReplaceInMiddle() { CommonTree t = new CommonTree(new CommonToken(99, "a")); t.AddChild(new CommonTree(new CommonToken(99, "b"))); t.AddChild(new CommonTree(new CommonToken(99, "c"))); // index 1 t.AddChild(new CommonTree(new CommonToken(99, "d"))); CommonTree newChild = new CommonTree(new CommonToken(99, "x")); t.ReplaceChildren(1, 1, newChild); String expected = "(a b x d)"; Assert.AreEqual(expected, t.ToStringTree()); t.SanityCheckParentAndChildIndexes(); }
public static DataType Check(AstNode node, Context context) { switch (node.Type) { case MathExprLexer.PROGRAM: { if (context == null) context = new Context(context); CheckBlock(node, context); return DataType.Void; } case MathExprLexer.BLOCK: { context = new Context(context); CheckBlock(node, context); return DataType.Void; } case MathExprLexer.VAR: { List<AstNode> nodes = new List<AstNode>(); DataType dataType = strToDataType(node.GetChild(0).Text); for (int i = 0; i < node.GetChild(0).ChildCount; i++) { AstNode temp = (AstNode) node.GetChild(0).GetChild(i); if (temp.Token.Type == MathExprLexer.ASSIGN) { Ident ident = context.InThisContext(temp.GetChild(0).Text); if (ident != null) throw new ApplicationException(string.Format("Identifier {0} already exists", temp.GetChild(0).Text)); AstNode var = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.VAR, "VAR")); var.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, dataTypeToStr(dataType)))); var.GetChild(0).AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, temp.GetChild(0).Text))); nodes.Add(var); nodes.Add(temp); } else { Ident ident = context.InThisContext(temp.Text); if (ident != null) throw new ApplicationException(string.Format("Identifier {0} already exists", temp.Text)); AstNode var = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.VAR, "VAR")); var.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.IDENT, dataTypeToStr(dataType)))); var.GetChild(0).AddChild(temp); nodes.Add(var); } string name = nodes[0].GetChild(0).GetChild(0).Text; context[name] = new Ident(name, context.ParentContext == null ? IdentType.GlobalVar : IdentType.LocalVar, dataType, nodes[0]); Antlr.Runtime.Tree.CommonTree tree = new Antlr.Runtime.Tree.CommonTree(); foreach (AstNode n in nodes) tree.AddChild(n); node.Parent.ReplaceChildren(node.ChildIndex, node.ChildIndex, tree); } return DataType.Void; ; } case MathExprLexer.FUNCTION: { DataType dataType = strToDataType(node.GetChild(0).Text); string name = node.GetChild(1).Text; Ident ident = context[name]; if (ident != null) throw new ApplicationException(string.Format("Identifier {0} already exists", name)); Ident func = new Ident(name, IdentType.Function, dataType, node); context[name] = func; context = new Context(context); AstNode _params = (AstNode) node.GetChild(2); for (int i = 0; i < _params.ChildCount; i++) { DataType paramDataType = strToDataType(_params.GetChild(i).Text); string paramName = _params.GetChild(i).GetChild(0).Text; if (paramDataType == DataType.Void) throw new ApplicationException(string.Format("In function {0} void param {1}", name, paramName)); context[paramName] = new Ident(paramName, IdentType.Param, paramDataType, (AstNode) _params.GetChild(i)); } context.Function = func; Check((AstNode) node.GetChild(3), context); return DataType.Void; } case MathExprLexer.CALL: { Ident ident = context[node.GetChild(0).Text]; if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); if (ident.IdentType != IdentType.Function) throw new ApplicationException(string.Format("Identifier {0} is not function", node.GetChild(0).Text)); if (node.GetChild(1).ChildCount != ident.Node.GetChild(2).ChildCount) throw new ApplicationException(string.Format("Not equals params count in function {0}", node.GetChild(0).Text)); for (int i = 0; i < ident.Node.GetChild(2).ChildCount; i++) { DataType formalDataType = strToDataType(ident.Node.GetChild(2).GetChild(i).Text); DataType factDataType = Check((AstNode)node.GetChild(1).GetChild(i), context); if (formalDataType != factDataType) { if (formalDataType == DataType.Double && factDataType == DataType.Int) convert((AstNode)node.GetChild(1).GetChild(i), DataType.Double); else throw new ApplicationException(string.Format("In function {0} param {1} incopotible types {2} {3}", node.GetChild(0).Text, i, dataTypeToStr(formalDataType), dataTypeToStr(factDataType))); } } return strToDataType(ident.Node.GetChild(0).Text); } case MathExprLexer.IDENT: { Ident ident = context[node.Text]; if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.Text)); if (ident.IdentType == IdentType.Function) { if (ident.DataType == DataType.Void) throw new ApplicationException(string.Format("Function {0} returns void", ident.Name)); if (ident.Node.GetChild(1).ChildCount > 0) throw new ApplicationException(string.Format("No params for function {0} call", ident.Name)); AstNode call = new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.CALL)); call.AddChild(node); call.AddChild(new AstNode(new Antlr.Runtime.CommonToken(MathExprLexer.PARAMS))); node.Parent.SetChild(node.ChildIndex, call); node.DataType = ident.DataType; return node.DataType; } else { node.DataType = ident.DataType; return node.DataType; } } case MathExprLexer.NUMBER: { node.DataType = node.Text.Contains(".") ? DataType.Double : DataType.Int; return node.DataType; } case MathExprLexer.TRUE: case MathExprLexer.FALSE: { node.DataType = DataType.Bool; return node.DataType; } case MathExprLexer.ASSIGN: { Ident ident = context[node.GetChild(0).Text]; if (ident == null) throw new ApplicationException(string.Format("Unknown identifier {0}", node.GetChild(0).Text)); if (ident.IdentType == IdentType.Function) throw new ApplicationException(string.Format("Assign to function {0}", node.GetChild(0).Text)); DataType rightDataType = Check((AstNode) node.GetChild(1), context); if (ident.DataType != rightDataType) { if (ident.DataType == DataType.Double && rightDataType == DataType.Int) convert((AstNode) node.GetChild(1), DataType.Double); else throw new ApplicationException(string.Format("Assign incopotible types {0} {1}", dataTypeToStr(ident.DataType), dataTypeToStr(rightDataType))); } return DataType.Void; } case MathExprLexer.RETURN: { if (context.Function == null) throw new ApplicationException(string.Format("Return not in function in line {0}", node.Line)); DataType returnDataType = Check((AstNode) node.GetChild(0), context); if (context.Function.DataType != returnDataType) { if (context.Function.DataType == DataType.Double && returnDataType == DataType.Int) convert((AstNode) node.GetChild(0), DataType.Double); else throw new ApplicationException(string.Format("Return incopotible types {0} {1}", dataTypeToStr(context.Function.DataType), dataTypeToStr(returnDataType))); } return DataType.Void; } case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: case MathExprLexer.GE: case MathExprLexer.LE: case MathExprLexer.NEQUALS: case MathExprLexer.EQUALS: case MathExprLexer.GT: case MathExprLexer.LT: { bool compareOperation = true; switch (node.Type) { case MathExprLexer.ADD: case MathExprLexer.SUB: case MathExprLexer.MUL: case MathExprLexer.DIV: compareOperation = false; break; } DataType leftDataType = Check((AstNode) node.GetChild(0), context); DataType rightDataType = Check((AstNode) node.GetChild(1), context); if (leftDataType != DataType.Double && leftDataType != DataType.Int) throw new ApplicationException(string.Format("Left operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); if (rightDataType != DataType.Double && rightDataType != DataType.Int) throw new ApplicationException(string.Format("Right operand invalid type for operation {0}, line = {1}, pos = {2}", node.Text, node.Line, node.TokenStartIndex)); if (leftDataType == DataType.Double) { if (rightDataType == DataType.Int) convert((AstNode)node.GetChild(1), DataType.Double); node.DataType = compareOperation ? DataType.Bool : DataType.Double; return node.DataType; } if (rightDataType == DataType.Double) { if (leftDataType == DataType.Int) convert((AstNode)node.GetChild(0), DataType.Double); node.DataType = compareOperation ? DataType.Bool : DataType.Double; return node.DataType; } node.DataType = compareOperation ? DataType.Bool : DataType.Int; return node.DataType; } case MathExprLexer.NOT: { DataType dataType = Check((AstNode) node.GetChild(0), context); if (dataType != DataType.Bool) throw new ApplicationException(string.Format("Not operator with type {0}", dataTypeToStr(dataType))); node.DataType = DataType.Bool; return node.DataType; } case MathExprLexer.AND: case MathExprLexer.OR: case MathExprLexer.XOR: { DataType leftDataType = Check((AstNode) node.GetChild(0), context); DataType rightDataType = Check((AstNode) node.GetChild(1), context); if (leftDataType != DataType.Bool && rightDataType != DataType.Bool) throw new ApplicationException(string.Format("{0} operator with type {1}, {2}", node.Text, dataTypeToStr(leftDataType), dataTypeToStr(rightDataType))); node.DataType = DataType.Bool; return node.DataType; } case MathExprLexer.WHILE: { DataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType != DataType.Bool) throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType))); // context = new Context(context); Check((AstNode)node.GetChild(1), context); return DataType.Void; } case MathExprLexer.IF: { DataType condDataType = Check((AstNode)node.GetChild(0), context); if (condDataType != DataType.Bool) throw new ApplicationException(string.Format("In if condition type is {0}", dataTypeToStr(condDataType))); // context = new Context(context); Check((AstNode)node.GetChild(1), context); if (node.ChildCount == 3) Check((AstNode)node.GetChild(2), context); return DataType.Void; } case MathExprLexer.FOR: { context = new Context(context); CheckBlock((AstNode) node.GetChild(0), context); DataType condDataType = Check((AstNode)node.GetChild(1), context); if (condDataType != DataType.Bool) throw new ApplicationException(string.Format("In while condition type is {0}", dataTypeToStr(condDataType))); CheckBlock((AstNode)node.GetChild(2), context); Check((AstNode)node.GetChild(3), context); return DataType.Void; } default: { throw new ApplicationException("Unknown token type"); } break; } }
public void testAoverB() { ITree t = new CommonTree(new CommonToken(101)); t.AddChild(new CommonTree(new CommonToken(102))); ITreeNodeStream stream = CreateBufferedTreeNodeStream(t); string expected = " 101 102"; string actual = GetStringOfEntireStreamContentsWithNodeTypesOnly(stream); Assert.AreEqual(expected, actual); expected = " 101 2 102 3"; actual = stream.ToString(); Assert.AreEqual(expected, actual); }