Ejemplo n.º 1
0
        /// <summary>
        /// Constructs AST node from operator (root) and one or two operands.
        /// In order for the node to be successfully created stacks must contain
        /// an operator and, depending on the operator, one or two operands.
        /// </summary>
        /// <example>
        /// The newly created subtree (operator and root and operands are children)
        /// is then pushed into the operands stack. Example: in a*b+c before '+'
        /// can be processed, a*b is turned into an subtree and pushed as an operand
        /// to the operands stack. Then new subtree can be created with + at the root
        /// and 'c' and 'a*b' as its child nodes.
        /// </example>
        /// <param name="context">Parsing context</param>
        /// <returns>Parsing error of any</returns>
        private ParseErrorType MakeNode(ParseContext context)
        {
            IOperator operatorNode = _operators.Pop();

            IRValueNode rightOperand = this.SafeGetOperand();

            if (rightOperand == null)
            {
                // Oddly, no operands
                return(ParseErrorType.RightOperandExpected);
            }

            if (operatorNode.IsUnary)
            {
                operatorNode.AppendChild(rightOperand);
                operatorNode.RightOperand = rightOperand;
            }
            else
            {
                IRValueNode leftOperand = this.SafeGetOperand();
                if (leftOperand == null)
                {
                    // Operand is missing in expression like x <- [].
                    // Operator on top of the stack is <- since [] was not
                    // successfully parsed. So we need to mark right operand
                    // as error token.
                    context.AddError(new ParseError(ParseErrorType.LeftOperandExpected, ErrorLocation.Token, GetIndexerOrFunctionErrorRange(context, operatorNode)));
                    return(ParseErrorType.LeftOperandExpected);
                }

                if (leftOperand.End <= operatorNode.Start && rightOperand.Start >= operatorNode.End)
                {
                    operatorNode.LeftOperand  = leftOperand;
                    operatorNode.RightOperand = rightOperand;

                    operatorNode.AppendChild(leftOperand);
                    operatorNode.AppendChild(rightOperand);
                }
                else
                {
                    return(ParseErrorType.UnexpectedToken);
                }
            }

            _operands.Push(operatorNode);
            return(ParseErrorType.None);
        }
Ejemplo n.º 2
0
        private ParseErrorType HandleFunctionOrIndexer(IOperator operatorNode)
        {
            // Indexing or function call is performed on the topmost operand which
            // generally should be a variable or a node that evaluates to it.
            // However, we leave syntax check to separate code.

            IRValueNode operand = this.SafeGetOperand();

            if (operand == null)
            {
                // Oddly, no operand
                return(ParseErrorType.IndentifierExpected);
            }

            operatorNode.LeftOperand = operand;
            operatorNode.AppendChild(operand);
            _operands.Push(operatorNode);

            return(ParseErrorType.None);
        }
Ejemplo n.º 3
0
        private ParseErrorType HandleFunctionOrIndexer(IOperator operatorNode) {
            // Indexing or function call is performed on the topmost operand which 
            // generally should be a variable or a node that evaluates to it.
            // However, we leave syntax check to separate code.

            IRValueNode operand = this.SafeGetOperand();
            if (operand == null) {
                // Oddly, no operand
                return ParseErrorType.IndentifierExpected;
            }

            operatorNode.LeftOperand = operand;
            operatorNode.AppendChild(operand);
            _operands.Push(operatorNode);

            return ParseErrorType.None;
        }