/// <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)); }
/// <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); } }
/// <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)); }
public IOPrintNode CreateIOPrintNode(StatementsNode statementsNode, Token t) { IOPrintNode ioPrintNode = new IOPrintNode(t); statementsNode.Statement = ioPrintNode; return(ioPrintNode); }
public IOReadNode CreateIOReadNode(VariableIdNode idNode, StatementsNode statementsNode, Token t) { IOReadNode ioReadNode = new IOReadNode(idNode, symbolTable, t); statementsNode.Statement = ioReadNode; return(ioReadNode); }
public ForLoopNode CreateForLoopNode(VariableIdNode idNode, StatementsNode statementsNode, Token t) { ForLoopNode node = new ForLoopNode(idNode, symbolTable, t); statementsNode.Statement = node; return(node); }
public AssignNode CreateAssignNode(VariableIdNode idNode, StatementsNode statementsNode, Token t) { AssignNode assignNode = new AssignNode(idNode, symbolTable, t); statementsNode.Statement = assignNode; return(assignNode); }
public StatementsNode CreateStatementsNode(IStatementsContainer parentNode, Token token) { StatementsNode statementsNode = new StatementsNode(token); parentNode.Sequitor = statementsNode; return(statementsNode); }
public AssertNode CreateAssertNode(StatementsNode statementsNode, Token t) { AssertNode assertNode = new AssertNode(t); statementsNode.Statement = assertNode; return(assertNode); }
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); }
/// <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)); } }
/// <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)); } }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); } }
/// <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)); } }
/// <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)); } }
public StatementsNode(Token token) { this.statement = null; this.sequitor = null; this.token = token; }
public RootNode() { this.sequitor = null; this.token = new Token(1, 0, null, TokenType.PROGRAM); }
/// <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); }
/// <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); }