public AstNode(int type, string text, AstNode child1, AstNode child2) { Type = type; Text = text; if(child1 != null) AddChild(child1); if(child2 != null) AddChild(child2); }
public void AddChild(AstNode child) { if (child.Parent != null) { child.Parent.childs.Remove(child); } childs.Remove(child); childs.Add(child); child.parent = this; }
private static string getStringSubTree(AstNode node, string indent, bool root) { if (node == null) return ""; string result = indent; if (!root) if(node.Index < node.Parent.ChildCount - 1) { result += MiddleNodeChar + " "; indent += ConnectChar + " "; } else { result += LastNodeChar + " "; indent += " "; } result += node + "\n"; for(int i = 0; i < node.ChildCount; i++) result += getStringSubTree(node.GetChild(i), indent, false); return result; }
public static void Print(AstNode node) { string tree = astNodeToAdvancedDosStringTree(node); Console.WriteLine(tree); }
public static string astNodeToAdvancedDosStringTree(AstNode node) { return getStringSubTree(node, "", true); }
public void RemoveChild(AstNode child) { childs.Remove(child); if (child.parent == this) child.parent = null; }
public AstNode(int type, AstNode child1) : this(type, child1, null) { }
public AstNode(int type, AstNode child1, AstNode child2) : this(type, null, child1, child2) { }
private double ExecuteNode(AstNode node) { switch (node.Type) { case AstNodeType.UNKNOWN: throw new IntepreterException("Неопределенный тип узла AST-дерева"); case AstNodeType.NUMBER: return double.Parse(node.Text, NFI); case AstNodeType.IDENT: if (varTable.ContainsKey(node.Text)) return varTable[node.Text]; else throw new ParserBaseException(string.Format("Значение {0} не определено", node.Text)); case AstNodeType.ADD: return ExecuteNode(node.GetChild(0)) + ExecuteNode(node.GetChild(1)); case AstNodeType.SUB: return ExecuteNode(node.GetChild(0)) - ExecuteNode(node.GetChild(1)); case AstNodeType.MUL: return ExecuteNode(node.GetChild(0)) * ExecuteNode(node.GetChild(1)); case AstNodeType.DIV: return ExecuteNode(node.GetChild(0)) / ExecuteNode(node.GetChild(1)); case AstNodeType.ASSIGN: varTable[node.GetChild(0).Text] = ExecuteNode(node.GetChild(1)); break; case AstNodeType.INPUT: Console.Write("input {0}: ", node.GetChild(0).Text); varTable[node.GetChild(0).Text] = double.Parse(Console.ReadLine(), NFI); break; case AstNodeType.PRINT: Console.WriteLine(ExecuteNode(node.GetChild(0)).ToString(NFI)); break; case AstNodeType.IF: if (double.Parse(ExecuteNode(node.GetChild(0)).ToString(NFI)) > 0 || double.Parse(ExecuteNode(node.GetChild(0)).ToString(NFI)) < 0) { Console.WriteLine(ExecuteNode(node.GetChild(1)).ToString(NFI)); } else if (double.Parse(ExecuteNode(node.GetChild(0)).ToString(NFI)) == 0) { Console.WriteLine(ExecuteNode(node.GetChild(2)).ToString(NFI)); } break; case AstNodeType.WHILE: if (double.Parse(ExecuteNode(node.GetChild(0)).ToString(NFI)) > 0 || double.Parse(ExecuteNode(node.GetChild(0)).ToString(NFI)) < 0) { Console.WriteLine(ExecuteNode(node.GetChild(1)).ToString(NFI)); } break; case AstNodeType.BLOCK: case AstNodeType.PROGRAM: for (int i = 0; i < node.ChildCount; i++) ExecuteNode(node.GetChild(i)); break; /* default: throw new IntepreterException("Неизвестный тип узла AST-дерева"); */ } return 0; }
public MathLangIntepreter(AstNode programNode) { if (programNode.Type != AstNodeType.PROGRAM) throw new IntepreterException("AST-дерево не является программой"); this.programNode = programNode; }
public static void Execute(AstNode programNode) { MathLangIntepreter mli = new MathLangIntepreter(programNode); mli.Execute(); }