private Instruction matchInstruction() {
		dispatchEvent(ParserEvent.BEGAN_PARSING_NON_TERMINAL_SYMBOL, "Instruction");

		Instruction instruction = null; // TODO Invalid instruction.
		if (SyntacticValidator.getInstance().isNextToken(ProductionRule.REQUIRED, Token.Type.IDENTIFIER, Reserved.Keyword.IF, Reserved.Keyword.REPEAT, Reserved.Keyword.WHILE, Reserved.Keyword.READ, Reserved.Keyword.WRITE)) {
			if (SyntacticValidator.getInstance().isNextToken(ProductionRule.OPTIONAL, Token.Type.IDENTIFIER)) {
				if (ScopeManager.getInstance().getCurrentScope().find(TokenIterator.getInstance().peek().getValue().toString()) instanceof Procedure || TokenIterator.getInstance().peek(2).getValue().toString().equals(Reserved.Symbol.OPENING_PARENTHESIS.toString())) {
					instruction = matchCall();
				} else {
					instruction = matchAssign();
				}
			} else if (SyntacticValidator.getInstance().isNextToken(ProductionRule.OPTIONAL, Reserved.Keyword.IF)) {
				instruction = matchIf();
			} else if (SyntacticValidator.getInstance().isNextToken(ProductionRule.OPTIONAL, Reserved.Keyword.REPEAT)) {
				instruction = matchRepeat();
			} else if (SyntacticValidator.getInstance().isNextToken(ProductionRule.OPTIONAL, Reserved.Keyword.WHILE)) {
				instruction = matchWhile();
			} else if (SyntacticValidator.getInstance().isNextToken(ProductionRule.OPTIONAL, Reserved.Keyword.READ)) {
				instruction = matchRead();
			} else {
				instruction = matchWrite();
			}
		}

		dispatchEvent(ParserEvent.FINISHED_PARSING_NON_TERMINAL_SYMBOL, "Instruction");
		return instruction;
	}