public ASTNode(Token token, ASTOperand operand) { Token = token; Priority = 0; Operand = operand; Type = operand.Type; Operator = ASTOperator.None; }
public ASTNode(Token token, ASTType type, long value) { Token = token; Type = type; Operator = ASTOperator.None; Operand = null; IValue = value; Computed = true; }
private static void BuildOperatorTree(Stack <ASTNode> parameters, Stack <ASTOperator> operators) { while (operators.Count > 0) { ASTNode left = parameters.Pop(); ASTNode right = null; if (parameters.Count > 0) { right = parameters.Pop(); } ASTOperator op = operators.Pop(); op.Left = left; op.Right = right; parameters.Push(op); } }
ASTExpression ParseExpression() { ASTExpression firstExpr = ParseExpressionImpl(); if (lexer.IsReading) { if (lexer.PeekNext() == TokenType.Operator) // Operators { Token opToken = lexer.NextToken(); ASTExpression rightSide = ParseExpression(); ASTOperator opNode = new ASTOperator(opToken.Source, firstExpr, rightSide); return(opNode); } else if (lexer.PeekNext() == TokenType.SquareBraceOpen) // Array access { ASTIndexer upper = null; while (lexer.PeekNext() == TokenType.SquareBraceOpen) { MatchNext(TokenType.SquareBraceOpen); ASTExpression index = ParseExpression(); upper = new ASTIndexer(firstExpr, index); firstExpr = upper; MatchNext(TokenType.SquareBraceClose); } return(upper); } } return(firstExpr); }
public ASTNode(Token token, ASTOperator op) { Token = token; Operator = op; Priority = Priorities[(int)op]; }
public ASTStatement PushOperator(Token token, ASTOperator opcode) { ASTNode node = new ASTNode(token, opcode); while (inFixStack.Count > 0 && inFixStack.Peek().Priority > node.Priority) { ASTNode nd = inFixStack.Pop(); addPostFixOperator(nd); } inFixStack.Push(node); return this; }
public static ASTStatement ParseStatement() { List <ASTNode> nodes = new List <ASTNode>(); ASTNode currentNode = null; int countClauses = 0; for (; currentToken < currentTokens.Count; currentToken++) { if (currentTokens[currentToken] is SpecialToken) { if (currentTokens[currentToken].Token == "{" || currentTokens[currentToken].Token == "," || (currentTokens[currentToken].Token == ")" && countClauses <= 0)) { break; } if (currentTokens[currentToken].Token == ";" || currentTokens[currentToken].Token == "]") { currentToken++; break; } if (currentTokens[currentToken].Token == "(") { countClauses++; currentNode = new ASTOperator() { Operator = "(", Precedence = -1, Left = null, Right = null }; } else if (currentTokens[currentToken].Token == ")") { --countClauses; } } if (currentTokens[currentToken] is OperatorToken) { // 2 Operators means at least one is an unary one if (currentTokens[currentToken + 1] is OperatorToken) { // Example case "1++ - 2" if (currentTokens[currentToken].Token == "++" || currentTokens[currentToken].Token == "--") { nodes.RemoveAt(nodes.Count - 1); ASTNode left = currentNode; currentNode = new ASTOperator() { Operator = currentTokens[currentToken].Token, Precedence = 0, Left = left, Right = null }; nodes.Add(currentNode); // 2. Operator currentToken++; string op = currentTokens[currentToken].Token; int precedence = ((OperatorToken)currentTokens[currentToken]).Precedence; currentNode = new ASTOperator() { Operator = op, Precedence = precedence, Left = null, Right = null }; } // case "1 - ++2" else { currentNode = new ASTOperator() { Operator = currentTokens[currentToken].Token, Precedence = 0, Left = null, Right = null }; nodes.Add(currentNode); // 2. Operator currentToken++; string op = currentTokens[currentToken].Token; int precedence = ((OperatorToken)currentTokens[currentToken]).Precedence; currentToken++; currentNode = new ASTOperator() { Operator = op, Precedence = precedence, Left = ParseSingleStatement(), Right = null }; //for will increase and ParseSingleStatement will do also --currentToken; } } // Statement starts with an unary operator example ("-1 * 2") || "(-1+2)*5" else if (currentToken == 0 || (currentTokens[currentToken - 1] is SpecialToken && currentTokens[currentToken - 1].Token == "(")) { string op = currentTokens[currentToken].Token; currentToken++; currentNode = new ASTOperator() { Operator = op, Precedence = 0, Left = ParseSingleStatement(), Right = null }; //for will increase and ParseSingleStatement will do also --currentToken; } else { currentNode = new ASTOperator() { Operator = currentTokens[currentToken].Token, Precedence = ((OperatorToken)currentTokens[currentToken]).Precedence, Left = null, Right = null }; } } else { currentNode = ParseSingleStatement(); //for will increase and ParseSingleStatement will do also --currentToken; } nodes.Add(currentNode); } // Prevent being stuck at a ; // if (currentTokens[currentToken].Token == ";") // currentToken++; if (nodes.Count > 1) { // Algorithm to take care of operator precedence Stack <ASTNode> parameters = new Stack <ASTNode>(); Stack <ASTOperator> operators = new Stack <ASTOperator>(); int lastPrecedence = int.MinValue; bool isOperator = false; for (int i = nodes.Count - 1; i >= 0; i--) { if (nodes[i] is ASTOperator && ((ASTOperator)nodes[i]).Operator == "(") { // Build Operator Tree BuildOperatorTree(parameters, operators); // After a ( always has to come an operator or nothing isOperator = true; } else { if (isOperator) { if (nodes[i] is ASTOperator) { ASTOperator op = (ASTOperator)nodes[i]; if (lastPrecedence < op.Precedence) { BuildOperatorTree(parameters, operators); } lastPrecedence = op.Precedence; operators.Push(op); } else { if (parameters.Count == 1) { ASTNode node = parameters.Pop(); if (node is ASTOperator) { ASTOperator op = (ASTOperator)node; op.Left = nodes[i]; parameters.Push(op); continue; } } // This should never ever happen, because else earlier a exception should be raised throw new ParserException("Expected an operator.", -1); } } else { parameters.Push(nodes[i]); } isOperator = !isOperator; } } BuildOperatorTree(parameters, operators); return(new ASTStatement() { Statement = parameters.Pop() }); } else if (nodes.Count == 1) { return(new ASTStatement() { Statement = nodes[0] }); } else { return(null); } }
private static void PrintNode(ASTNode node, int incident) { if (node == null) { return; } for (int i = 0; i < incident; i++) { sw.Write("\t"); } if (node is ASTString) { sw.WriteLine("ASTString: " + ((ASTString)node).String.Replace("\n", "\\n")); } else if (node is ASTNumber) { sw.WriteLine("ASTNumber: " + ((ASTNumber)node).Number); } else if (node is ASTIdentifier) { sw.WriteLine("ASTIdentifier: " + ((ASTIdentifier)node).Identifier); } else if (node is ASTOperator) { ASTOperator op = (ASTOperator)node; sw.WriteLine("ASTOperator: " + op.Operator); PrintNode(op.Left, incident + 1); PrintNode(op.Right, incident + 1); } else if (node is ASTStatement) { ASTStatement stm = (ASTStatement)node; sw.WriteLine("ASTStatement: "); PrintNode(stm.Statement, incident + 1); } else if (node is ASTFunctionCall) { ASTFunctionCall call = (ASTFunctionCall)node; sw.WriteLine("ASTFunctionCall: " + call.Scope + "." + call.FunctionName); foreach (ASTNode param in call.Parameter) { PrintNode(param, incident + 1); } } else if (node is ASTClassParameter) { ASTClassParameter classP = (ASTClassParameter)node; sw.WriteLine("ASTClassParameter: " + classP.Scope); PrintNode(classP.Parameter, incident + 1); } else if (node is ASTIf) { ASTIf ifNode = (ASTIf)node; sw.WriteLine("ASTIf:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(ifNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in ifNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } if (ifNode.ElseCodeBlock != null) { for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tElse:"); foreach (ASTNode codeBlock in ifNode.ElseCodeBlock) { PrintNode(codeBlock, incident + 2); } } } else if (node is ASTFor) { ASTFor forNode = (ASTFor)node; sw.WriteLine("ASTFor:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tInit:"); PrintNode(forNode.Initialise, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(forNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCounter:"); PrintNode(forNode.Count, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in forNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTWhile) { ASTWhile wNode = (ASTWhile)node; sw.WriteLine("ASTWhile:"); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCondition:"); PrintNode(wNode.Condition, incident + 2); for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in wNode.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTFunction) { ASTFunction func = (ASTFunction)node; if (node is ASTConstructor) { sw.WriteLine("ASTConstructor:"); } else { sw.WriteLine("ASTFunction: " + func.ReturnValue.ToString() + " " + func.Name); } for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tParameter:"); foreach (ASTNode n in func.Parameter) { PrintNode(n, incident + 2); } for (int i = 0; i < incident; i++) { sw.Write("\t"); } sw.WriteLine("\tCodeBlock:"); foreach (ASTNode codeBlock in func.CodeBlock) { PrintNode(codeBlock, incident + 2); } } else if (node is ASTFunctionParameter) { ASTFunctionParameter param = (ASTFunctionParameter)node; switch (param.Type) { case VMType.Object: sw.WriteLine("Object: " + param.Name); break; case VMType.String: sw.WriteLine("String: " + param.Name); break; case VMType.Number: sw.WriteLine("Number: " + param.Name); break; } } else if (node is ASTLocalVariable) { ASTLocalVariable param = (ASTLocalVariable)node; switch (param.Type) { case VMType.Object: sw.WriteLine("var Object: " + param.Name); break; case VMType.String: sw.WriteLine("var String: " + param.Name); break; case VMType.Number: sw.WriteLine("var Number: " + param.Name); break; } } else if (node is ASTReturn) { sw.WriteLine("ASTReturn:"); PrintNode(((ASTReturn)node).Return, incident + 1); } else if (node is ASTClass) { ASTClass cNode = (ASTClass)node; sw.WriteLine("ASTClass: " + cNode.Name); sw.WriteLine("\tAttributes:"); foreach (ASTNode n in cNode.Attributes) { PrintNode(n, incident + 2); } sw.WriteLine("\tConstructors:"); foreach (ASTNode n in cNode.Constructors) { PrintNode(n, incident + 2); } sw.WriteLine("\tFunctions:"); foreach (ASTNode n in cNode.Functions) { PrintNode(n, incident + 2); } } }