Beispiel #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));
        }
Beispiel #2
0
        /// <summary>
        /// Parses a single statement as a StatementsNode's executable statement.
        /// </summary>
        /// <returns>The next token</returns>
        /// <param name="token">Token.</param>
        /// <param name="statementsNode">A StatementsNode.</param>
        private Token ParseStatement(Token token, StatementsNode statementsNode)
        {
            switch (token.Type)
            {
            case TokenType.DECLARATION:
                return(ParseDeclaration(token, statementsNode));

            case TokenType.ID:
                return(ParseVariableAssign(token, statementsNode));

            case TokenType.FOR_LOOP:
                return(ParseForLoop(token, statementsNode));

            case TokenType.READ:
                return(ParseRead(token, statementsNode));

            case TokenType.PRINT:
                return(ParsePrint(token, statementsNode));

            case TokenType.ASSERT:
                return(ParseAssert(token, statementsNode));

            case TokenType.ERROR:
                notifyError(new SyntaxError(token, TokenType.UNDEFINED, ParserConstants.EXPECTATION_SET_STATEMENT));
                return(FastForwardToStatementEnd(token));

            default:
                throw new UnexpectedTokenException(token, TokenType.UNDEFINED, ParserConstants.EXPECTATION_SET_STATEMENT);
            }
        }
Beispiel #3
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));
        }
Beispiel #4
0
        public IOPrintNode CreateIOPrintNode(StatementsNode statementsNode, Token t)
        {
            IOPrintNode ioPrintNode = new IOPrintNode(t);

            statementsNode.Statement = ioPrintNode;

            return(ioPrintNode);
        }
Beispiel #5
0
        public IOReadNode CreateIOReadNode(VariableIdNode idNode, StatementsNode statementsNode, Token t)
        {
            IOReadNode ioReadNode = new IOReadNode(idNode, symbolTable, t);

            statementsNode.Statement = ioReadNode;

            return(ioReadNode);
        }
Beispiel #6
0
        public ForLoopNode CreateForLoopNode(VariableIdNode idNode, StatementsNode statementsNode, Token t)
        {
            ForLoopNode node = new ForLoopNode(idNode, symbolTable, t);

            statementsNode.Statement = node;

            return(node);
        }
Beispiel #7
0
        public AssignNode CreateAssignNode(VariableIdNode idNode, StatementsNode statementsNode, Token t)
        {
            AssignNode assignNode = new AssignNode(idNode, symbolTable, t);

            statementsNode.Statement = assignNode;

            return(assignNode);
        }
Beispiel #8
0
        public StatementsNode CreateStatementsNode(IStatementsContainer parentNode, Token token)
        {
            StatementsNode statementsNode = new StatementsNode(token);

            parentNode.Sequitor = statementsNode;

            return(statementsNode);
        }
Beispiel #9
0
        public AssertNode CreateAssertNode(StatementsNode statementsNode, Token t)
        {
            AssertNode assertNode = new AssertNode(t);

            statementsNode.Statement = assertNode;

            return(assertNode);
        }
Beispiel #10
0
        public DeclarationNode CreateDeclarationNode(VariableIdNode idNode, StatementsNode statementsNode, Token t)
        {
            DeclarationNode declarationNode = new DeclarationNode(idNode, symbolTable, t);

            declarationNode.AssignNode = CreateAssignNode(idNode, t);
            statementsNode.Statement   = declarationNode;

            return(declarationNode);
        }
Beispiel #11
0
 /// <summary>
 /// Parses a print statement into an IOPrintNode
 /// </summary>
 /// <returns>The next token.</returns>
 /// <param name="token">Token.</param>
 /// <param name="statementsNode">A StatementsNode.</param>
 private Token ParsePrint(Token token, StatementsNode statementsNode)
 {
     try {
         // build the print statement node
         IOPrintNode printNode = nodeBuilder.CreateIOPrintNode(statementsNode, token);
         // parse the expression to print
         return(ParseExpression(scanner.getNextToken(token), printNode));
     } catch (UnexpectedTokenException ex) {
         return(FastForwardToStatementEnd(ex));
     }
 }
Beispiel #12
0
 /// <summary>
 /// Parses a read statement into an IOReadNode.
 /// </summary>
 /// <returns>The next token</returns>
 /// <param name="token">Token.</param>
 /// <param name="statementsNode">A StatementsNode.</param>
 private Token ParseRead(Token token, StatementsNode statementsNode)
 {
     try {
         VariableIdNode varId = nodeBuilder.CreateIdNode();
         // create the IOReadNode and affiliate it with the statementsNode
         nodeBuilder.CreateIOReadNode(varId, statementsNode, token);
         // parses the variable id that the read operation's value is saved to
         return(ParseVarId(scanner.getNextToken(token), varId));
     } catch (UnexpectedTokenException ex) {
         return(FastForwardToStatementEnd(ex));
     }
 }
Beispiel #13
0
        /// <summary>
        /// Parses statements.
        /// In the AST a StatementsNode connects a single statement or a block to its successor.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="token">Token.</param>
        /// <param name="parent">IStatementContainer to affiliate the statements with.</param>
        private Token ParseStatements(Token token, IStatementsContainer parent)
        {
            switch (token.Type)
            {
            case TokenType.DECLARATION:
            case TokenType.FOR_LOOP:
            case TokenType.READ:
            case TokenType.PRINT:
            case TokenType.ASSERT:
            case TokenType.ID:
                /* Asks the NodeBuilder to create a StatementsNode and affiliate it with the
                 * parent node given as argument.
                 *
                 * Note that the token the scanner provides is also connected to its corresponding
                 * node(s). This makes it easier to print informative error messages in case something
                 * goes wrong. */
                StatementsNode statements = nodeBuilder.CreateStatementsNode(parent, token);
                Token          next;

                try {
                    // try to parse a statement and affiliate it with the statements node
                    next = ParseStatement(token, statements);
                } catch (UnexpectedTokenException ex) {
                    // fastforward to the end of statement if it's malformed
                    next = FastForwardToStatementEnd(ex);
                }

                match(next, TokenType.END_STATEMENT);

                // connect another statements node to this one
                return(ParseStatements(scanner.getNextToken(next), statements));

            case TokenType.END_OF_BLOCK:
            case TokenType.END_OF_FILE:
                // if the end of file or block is found, create no more statements to the current block / AST
                return(token);

            case TokenType.ERROR:
                // this statement cannot be parsed, notify error and fastforward to a safe spot
                notifyError(new SyntaxError(token, TokenType.UNDEFINED, ParserConstants.EXPECTATION_SET_STATEMENTS));

                next = FastForwardToStatementEnd(token);
                // try to parse more statements
                return(ParseStatements(scanner.getNextToken(next), parent));

            default:
                return(token);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Visits the statements node.
        /// </summary>
        /// <returns>An ISemanticCheckValue.</returns>
        /// <param name="node">Node.</param>
        public ISemanticCheckValue VisitStatementsNode(StatementsNode node)
        {
            // first execute the statement and then its follower
            if (node.Statement != null)
            {
                node.Statement.Accept(this);
            }

            if (node.Sequitor != null)
            {
                return(node.Sequitor.Accept(this));
            }

            return(voidProperty);
        }
Beispiel #15
0
        /// <summary>
        /// Checks the static semantic constraints of a StatementsNode.
        /// </summary>
        /// <returns>An ISemanticCheckValue.</returns>
        /// <param name="node">Node.</param>
        public ISemanticCheckValue VisitStatementsNode(StatementsNode node)
        {
            // first check the node's statement, then the following StatementsNode
            if (node.Statement != null)
            {
                node.Statement.Accept(this);
            }

            if (node.Sequitor != null)
            {
                node.Sequitor.Accept(this);
            }

            return(voidProperty);
        }
Beispiel #16
0
        /// <summary>
        /// Parses an assign statement.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="token">Token.</param>
        /// <param name="statementsNode">Statements node.</param>
        private Token ParseVariableAssign(Token token, StatementsNode statementsNode)
        {
            try {
                VariableIdNode idNode = nodeBuilder.CreateIdNode();
                // parse the target id
                Token next = ParseVarId(token, idNode);

                match(next, TokenType.ASSIGN);
                AssignNode assignNode = nodeBuilder.CreateAssignNode(idNode, statementsNode, token);

                // parses the expression of the assignment
                return(ParseExpression(scanner.getNextToken(next), assignNode));
            } catch (UnexpectedTokenException ex) {
                return(FastForwardToStatementEnd(ex));
            }
        }
Beispiel #17
0
        /// <summary>
        /// Parses a declaration statement.
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="token">Token.</param>
        /// <param name="statementsNode">A StatementsNode.</param>
        private Token ParseDeclaration(Token token, StatementsNode statementsNode)
        {
            // Try to parse all the pieces that a DeclarationNode needs to be evaluated.
            try {
                VariableIdNode idNode = nodeBuilder.CreateIdNode();
                // parse the target id
                Token next = ParseVarId(scanner.getNextToken(token), idNode);

                match(next, TokenType.SET_TYPE);
                // parse the id's type
                next = ParseType(scanner.getNextToken(next), idNode);

                // create the actual DeclarationNode
                DeclarationNode declarationNode = nodeBuilder.CreateDeclarationNode(idNode, statementsNode, token);
                // parse the assign for the DeclarationNode
                return(ParseAssign(next, declarationNode.AssignNode));
            } catch (UnexpectedTokenException ex) {
                return(FastForwardToStatementEnd(ex));
            }
        }
Beispiel #18
0
        /// <summary>
        /// Parses an assert statement into an AssertNode
        /// </summary>
        /// <returns>The next token.</returns>
        /// <param name="token">Token.</param>
        /// <param name="statementsNode">A StatementsNode.</param>
        private Token ParseAssert(Token token, StatementsNode statementsNode)
        {
            try {
                Token next = scanner.getNextToken(token);
                match(next, TokenType.PARENTHESIS_LEFT);

                // create the AssertNode
                AssertNode assertNode = nodeBuilder.CreateAssertNode(statementsNode, token);

                // parse the expression to assert when executed
                next = ParseExpression(scanner.getNextToken(next), assertNode);
                match(next, TokenType.PARENTHESIS_RIGHT);

                // create an IOPrinterNode to print a message in case of a failed assertion
                nodeBuilder.CreateIOPrintNodeForAssertNode(assertNode);

                return(scanner.getNextToken(next));
            } catch (UnexpectedTokenException ex) {
                return(FastForwardToStatementEnd(ex));
            }
        }
Beispiel #19
0
 public StatementsNode(Token token)
 {
     this.statement = null;
     this.sequitor  = null;
     this.token     = token;
 }
Beispiel #20
0
 public RootNode()
 {
     this.sequitor = null;
     this.token    = new Token(1, 0, null, TokenType.PROGRAM);
 }
Beispiel #21
0
 /// <summary>
 /// Visits the statements node.
 /// </summary>
 /// <returns>An ISemanticCheckValue.</returns>
 /// <param name="node">Node.</param>
 public ISemanticCheckValue VisitStatementsNode(StatementsNode node)
 {
     // nothing to evaluate here, it's done from the ExecutionVisitor
     return(voidProperty);
 }
Beispiel #22
0
 /// <summary>
 /// Visits the statements node.
 /// </summary>
 /// <returns>An ISemanticCheckValue.</returns>
 /// <param name="node">Node.</param>
 public ISemanticCheckValue VisitStatementsNode(StatementsNode node)
 {
     // nothing to evaluate here
     return(voidProperty);
 }