Esempio n. 1
0
        /// <summary>
        /// Parses a for-loop block.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="token">Token.</param>
        /// <param name="statementsNode">Statements node.</param>
        private Token ParseForLoop(Token token, StatementsNode statementsNode)
        {
            // first we prepare the ForLoopNode
            VariableIdNode idNode  = nodeBuilder.CreateIdNode();
            ForLoopNode    forLoop = nodeBuilder.CreateForLoopNode(idNode, statementsNode, token);
            Token          next    = null;

            try {
                // then we try to parse the control variables that handle the accumulation and
                // condition checking every time at the beginning of every loop
                next = ParseForLoopControl(forLoop, token);
            } catch (UnexpectedTokenException ex) {
                // fastforward to a safe spot
                if (ex.Token.Type == TokenType.END_OF_BLOCK)
                {
                    return(FastForwardToStatementEnd(ex));
                }
                notifyError(new SyntaxError(ex.Token, ex.ExpectedType, ex.ExpectationSet));
                next = FastForwardTo(ParserConstants.BLOCK_DEF_FASTFORWARD_TO, ex.Token);
            }

            try {
                // now we parse the statements that are executed during each loop
                next = ParseForLoopStatements(forLoop, next);
            } catch (UnexpectedTokenException ex) {
                return(FastForwardToStatementEnd(ex));
            }

            // finally, parse the loop finalization
            return(ParseForLoopEndBlock(forLoop, next));
        }
Esempio n. 2
0
        /// <summary>
        /// Checks the static semantic constraints of a ForLoopNode.
        /// </summary>
        /// <returns>An ISemanticCheckValue.</returns>
        /// <param name="node">Node.</param>
        public ISemanticCheckValue VisitForLoopNode(ForLoopNode node)
        {
            // check that the id property is ok
            IProperty property = getVariableProperty(node);

            if (property == voidProperty)
            {
                return(voidProperty);
            }

            VariableIdNode controlVariable = node.IDNode;

            // check that the control variable is declared
            checkPropertyDeclared(node, property, true);

            // check that the control variable's type is integer
            if (property.GetTokenType() != TokenType.INT_VAL)
            {
                analyzer.notifyError(new IllegalTypeError(controlVariable));
            }

            // set the control variable as static so any attempts to assign new value
            // to it inside the loop reports an error
            analyzer.SymbolicTable [controlVariable.ID].Constant = true;

            IExpressionNode max = node.MaxValue;

            // check that the expression that defines the maximum value of the control variable
            // exists and evaluates to an integer
            if (max == null)
            {
                analyzer.notifyError(new NullPointerError(node));
            }
            else
            {
                IProperty maxProperty = max.Accept(this.typeChecker).asProperty();

                if (!checkPropertyType(maxProperty, TokenType.INT_VAL))
                {
                    analyzer.notifyError(new IllegalTypeError(max));
                }
            }

            // check that the assingment that sets the control variables initial value
            // evaluates to an integer
            IProperty rangeFromProperty = node.RangeFrom.Accept(this.typeChecker).asProperty();

            if (!checkPropertyType(rangeFromProperty, TokenType.INT_VAL))
            {
                analyzer.notifyError(new IllegalTypeError(node.RangeFrom));
            }

            // check the statements of this for loop
            node.Statements.Accept(this);

            // the control variable needs not to ba constant any more
            analyzer.SymbolicTable [controlVariable.ID].Constant = false;

            return(voidProperty);
        }
Esempio n. 3
0
        /// <summary>
        /// Visits for loop node.
        /// </summary>
        /// <returns>An ISemanticCheckValue.</returns>
        /// <param name="node">Node.</param>
        public ISemanticCheckValue VisitForLoopNode(ForLoopNode node)
        {
            IProperty rangeFrom = node.RangeFrom.Accept(this).asProperty();
            IProperty max       = node.MaxValue.Accept(this).asProperty();
            bool      alright   = true;

            // check that the type is accepted as the "range from" expression
            // basically, chack it's integer
            if (!SemanticAnalysisConstants.LEGIT_OPERATIONS.ContainsKey(rangeFrom.GetTokenType()) ||
                !SemanticAnalysisConstants.LEGIT_OPERATIONS [rangeFrom.GetTokenType()].ContainsKey(TokenType.RANGE_FROM))
            {
                analyzer.notifyError(new IllegalTypeError(node.RangeFrom));
                alright = false;
            }

            // check that the type is accepted as the "range upto" expression
            // basically, chack it's integer
            if (!SemanticAnalysisConstants.LEGIT_OPERATIONS.ContainsKey(max.GetTokenType()) ||
                !SemanticAnalysisConstants.LEGIT_OPERATIONS [max.GetTokenType()].ContainsKey(TokenType.RANGE_UPTO))
            {
                analyzer.notifyError(new IllegalTypeError(node.MaxValue));
                alright = false;
            }

            // if both evaluations weren't alright, return an error property
            if (!alright)
            {
                return(new ErrorProperty());
            }

            return(rangeFrom);
        }
Esempio n. 4
0
        /// <summary>
        /// Parses for-loop's statements.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="forLoop">ForLoopNode.</param>
        /// <param name="token">Token.</param>
        private Token ParseForLoopStatements(ForLoopNode forLoop, Token token)
        {
            StatementsNode statements = nodeBuilder.CreateStatementsNode(forLoop.Token);

            forLoop.Statements = statements;
            // parse the statement's to be executed during each loop
            return(ParseStatements(scanner.getNextToken(token), statements));
        }
Esempio n. 5
0
        public ForLoopNode CreateForLoopNode(VariableIdNode idNode, StatementsNode statementsNode, Token t)
        {
            ForLoopNode node = new ForLoopNode(idNode, symbolTable, t);

            statementsNode.Statement = node;

            return(node);
        }
Esempio n. 6
0
        /// <summary>
        /// Parses for-loop control block.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="forLoop">ForLoopNode.</param>
        /// <param name="token">Token.</param>
        private Token ParseForLoopControl(ForLoopNode forLoop, Token token)
        {
            VariableIdNode idNode = forLoop.IDNode;
            // first, parse the id that holds the accumulator value
            Token next = ParseVarId(scanner.getNextToken(token), idNode);

            match(next, TokenType.RANGE_FROM);
            // second, parse the start index as an assignment for the accumulator id
            forLoop.RangeFrom = nodeBuilder.CreateAssignNode(idNode, next);
            next = ParseExpression(scanner.getNextToken(next), forLoop.RangeFrom);

            match(next, TokenType.RANGE_UPTO);
            // third, parse the maximum value of the index
            next = ParseExpression(scanner.getNextToken(next), forLoop);

            match(next, TokenType.START_BLOCK);
            return(next);
        }
Esempio n. 7
0
        /// <summary>
        /// Visits for loop node.
        /// </summary>
        /// <returns>An ISemanticCheckValue.</returns>
        /// <param name="node">Node.</param>
        public ISemanticCheckValue VisitForLoopNode(ForLoopNode node)
        {
            // evaluate the maximum value of the loop's control id
            int max = node.MaxValue.Accept(this).asProperty().asInteger();

            // set the control variable's value to the start index
            node.RangeFrom.Accept(this);
            VariableIdNode idNode = node.IDNode;

            // while the max index value is not reached
            while (idNode.Accept(this).asProperty().asInteger() <= max)
            {
                // execute the statements
                node.Statements.Accept(this);
                // call for the accumulator to accumulate the control variable's value
                node.Accumulator.Accept(this);
            }

            return(voidProperty);
        }
Esempio n. 8
0
        /// <summary>
        /// Parses for loop end block.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="forLoop">For loop.</param>
        /// <param name="token">Token.</param>
        private Token ParseForLoopEndBlock(ForLoopNode forLoop, Token token)
        {
            try {
                // try to match the end of block
                match(token, TokenType.END_OF_BLOCK);
                token = scanner.getNextToken(token);
                match(token, TokenType.FOR_LOOP);
                return(scanner.getNextToken(token));
            } catch (UnexpectedTokenException ex) {
                // something went wrong, need to find the actual end of the block
                token = FastForwardToEndOfBlock(ex);
            }

            try {
                // if we didn't succeed in the first try, we now found the block's end
                // or the end of file if the block was never finalized
                match(token, TokenType.FOR_LOOP);
                return(scanner.getNextToken(token));
            } catch (UnexpectedTokenException ex) {
                return(FastForwardToStatementEnd(ex));
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Visits for loop node.
 /// </summary>
 /// <returns>An ISemanticCheckValue.</returns>
 /// <param name="node">Node.</param>
 public ISemanticCheckValue VisitForLoopNode(ForLoopNode node)
 {
     // nothing to evaluate here, it's done from the ExecutionVisitor
     return(voidProperty);
 }